apollo-module incompatible with generate

Created on 5 Jul 2018  路  12Comments  路  Source: nuxt-community/apollo-module

Version

v4.0.0-beta.5

Reproduction link

https://github.com/nuxt-community/apollo-module

Steps to reproduce

npm run generate

What is expected ?

generated pages

What is actually happening?

Error: Network error: Cannot read property 'headers' of undefined

Additional comments?

in node_modules\@nuxtjs\apollolib\templates\plugin.js used req.headers.cookie, but req.headers not exist on generation stage

This bug report is available on Nuxt community (#c105)
bug-report

Most helpful comment

Since version beta.6 you can provide a plugin path to your own function as described here:
https://github.com/nuxt-community/apollo-module/releases/tag/v4.0.0-beta.6
You can overwrite the getAuth with your own function to solve this.

I released a beta.7 with the fix of cookie.parse function

All 12 comments

@TrurlMcByte can you show a reproduction what you try to solve?

I've also been having issues getting generate to work with this version.

I had the "Cannot read property 'headers' of undefined" message from time to time, but I think that was only when I didn't have matching templates for all routes.

I'm using apollo-fetch to build a dynamic routes array and this is returning a promise, however none of the routes are getting generated鈥攏ot even index.html. Edit: even without dynamic routes no pages are generated.

I'm using the same code as another project, which is running 3.0.6 of this module and works.

Usual code for page content, like

export default {
  apollo: {
    pagebyhost: {
      includeNodeModules: true,
      query: pageGQL,
      prefetch: context => ({
        hostname: process.env.info.inHostName,
        url: context.route.params.url
      }),
      variables() {
        return {
          hostname: process.env.info.inHostName,
          url: this.$route.params.url
        };
      }
    }
  },
}

In plugin template checked only if (process.server) case, but on generation stage it's also process.server only without req.headers (check manual).

I'm just add (in two places) checks like

            if (typeof req == 'undefined') {
              token = ''
            } else {

and all pages in this case will be generated

@papertokyo I'm also use apollo-fetch for routing itself (also for sitemap.xml), but problem not in routing. Error in page components with "prefetch" (SSR). And SSR in most cases is required for seo.

~base/pages/_url.vue

<template>
  <div>
    <div v-if="pagebyhost">
      <h3>{{ pagebyhost[0].title }}</h3>
      <article v-html="pagebyhost[0].body" />
    </div>
  </div>
</template>

<script>
/*global process:true*/
import pageGQL from "~/apollo/queries/page.gql";

export default {
  apollo: {
    pagebyhost: {
      includeNodeModules: true,
      query: pageGQL,
      prefetch: context => ({
        hostname: process.env.info.inHostName,
        url: context.route.params.url
      }),
      variables() {
        return {
          hostname: process.env.info.inHostName,
          url: this.$route.params.url
        };
      }
    }
  },
  head() {
    return {
      title: this.pagebyhost ? this.pagebyhost[0].title : "Loading"
    };
  }
};
</script>

<style>
img {
  max-width: 600px;
}
</style>

base/apollo/queries/page.gql

query page($hostname: String!, $url: String!) {
  pagebyhost(hostname: $hostname, url: $url) {
    id
    url
    title
    body
    meta
    updated_at
    getSite {
      id
      hostname
    }    
  }
}

env.info injecting into nuxt.config before generation

I'm not familiar with generate function of nuxt. But as far I know you are generating the html files first and this call is not really compatible with prefetch of nuxt, because once deployed you are having only client side environment. Maybe check out to use asyncData or fetch insteat of apollo like this:

async asyncData({route,app}){
  const r = await app.apolloProvider.query({
    query: pageGQL,
     hostname: process.env.info.inHostName,
     url: route.params.url
   return {
     page: r.data
  }
}

If you are using a pure generate approach then it might make sense to check out the generate api to speed up with payload like described here: https://nuxtjs.org/api/configuration-generate

I'm also not across the inner workings, but afaik what Nuxt is doing during generate is doing nuxt build then nuxt start and hitting each route in the array you provide it. Prefetch is working when using the apollo property like below, so I don't think that's the issue.

apollo: {
    event: {
      query: eventsDetail,
      prefetch ({ route }) {
        return { eventQuery: `fields.slug=${route.params.slug}` }
      },
      variables () {
        return { eventQuery: `fields.slug=${this.$route.params.slug}` }
      },
      update (data) {
        return data.events[0]
      }
    }
  }

This is the code I'm using with @nuxtjs/apollo 3.0.6 on a _slug.vue page and nuxt generate is working as expected.

@papertokyo I have this issue only with new nuxt-apollo, inside build-in generated plugin. Really this issue not related to nuxt itself or apollo at all, but only to authentication functions of http-link, used by apollo.

facing the same issue here, everything works decently (using nuxt start/dev) except for the generated static files.

my component is super simple.

import QueryTestString from '~/apollo/queries/query-test-string';

export default{
    apollo: {
        testString: QueryTestString
    }
}

during generation I get the following error in the console:


==== Error report ====
Route: '/'
Error: Network error: Cannot read property 'headers' of undefined
    at new ApolloError (my-project\node_modules\apollo-client\bundle.umd.js:124:32)
    at my-project\node_modules\apollo-client\bundle.umd.js:1198:45
    at my-project\node_modules\apollo-client\bundle.umd.js:1630:21
    at Array.forEach (<anonymous>)
    at my-project\node_modules\apollo-client\bundle.umd.js:1629:22
    at Map.forEach (<anonymous>)
    at QueryManager.broadcastQueries (my-project\node_modules\apollo-client\bundle.umd.js:1622:26)
    at my-project\node_modules\apollo-client\bundle.umd.js:1125:35
    at <anonymous>

tried using the asyncData approach mentioned above, but no luck here:

async asyncData({route,app}) {
        const {data} = await app.apolloProvider.defaultClient.query({
            query: QueryTestString
        });
        return ({
            testString: data
        })
    }

still cannot read property headers of undefined :(
I'd really appreciate if someone had an idea on how to resolve this

@Arne-Winter I have fixed it just by add

if(typeof req == 'undefined') return '';

directly in node_modules/@nuxtjs/apollo/lib/templates/plugin.js before each line with cookie.parse(req.headers.cookie || '') string. But it's dumb way...

Since version beta.6 you can provide a plugin path to your own function as described here:
https://github.com/nuxt-community/apollo-module/releases/tag/v4.0.0-beta.6
You can overwrite the getAuth with your own function to solve this.

I released a beta.7 with the fix of cookie.parse function

excellent, the issue is solved

Was this page helpful?
0 / 5 - 0 ratings