Apollo-module: Support for new full static

Created on 19 Jun 2020  ·  24Comments  ·  Source: nuxt-community/apollo-module

When can we able to release a support for the new full static generation on NuxtJs? I am having an issue using apollo-module on generating the static page using smart queries.

I have this component page

export default {
  data() {
    return {
      isEmpty,
      format,
      articles: [],
      query: '',
      resultsPerPage: 5,
      currentPage: 1,
      totalRecords: 0,
      loading: 0,
      filteredArticles: []
    }
  },
  apollo: {
    articles: {
      loadingKey: 'loading',
      deep: true,
      prefetch: true,
      watchLoading(isLoading) {
        if (isLoading) {
          console.log('This should not be happening from the client!!!')
        }
      },
      query: articlesQuery,
      variables() {
        return {
          start: this.resultsPerPage * (this.currentPage - 1),
          limit: this.resultsPerPage,
          sort: 'date:DESC'
        }
      },
      result(result) {
        this.articles = result.data.articles
        this.totalRecords = result.data.articlesConnection.aggregate.count
        this.refreshData()
      }
    }
  }
}

this generates static files with no payload data, there it keeps on refetching.

Most helpful comment

The more I use Apollo with Vue, the more frustrated I am with it. It feels like it's built by React devs, not Vue devs. Just so verbose and complicated, also kind of doubles up with Vuex.

I'm going to give this a try on our next project.
https://github.com/Gomah/nuxt-graphql-request

Works way more inline with how Nuxt wants you to use the fetch() hook.

All 24 comments

I have the same problem. Any known workaround to fix this?

Found a workaround inspired by https://dev.to/astagi/how-to-build-a-jamstack-multi-language-blog-with-nuxt-js-3gah

My code looks like this, I switched to asyncData instead of the smart query, then it worked.

  async asyncData({ app, route }) {
    const { data } = await app.apolloProvider.defaultClient.query({
      query: MY_QUERY,
      variables: {
        id: app.$slugToId.getId(route.path), // custom function
        language: app.i18n.locale
      }
    })
    return {
      page: data.page
    }
  },

but It would be nice to use smart query again

I'm having the same issue in the components so I can't use the asyncData method.
Do you have an other solution ?

@yohan-atlan try nuxt fetch method instead of asyncData. Works for me.

It's works for me ! Thank you !

Update : this is not working, the response in the fetch is working when nuxt generate the site but when it's live the data object rewriting dom

I have been banging my head on this for a while (until found this page and stopped, so thanks).

If you look at this video here at 16:52 (should start there) it's been said that asyncData needs to be used, as smart queries will not work until target: static is released. However as we're discovering, this doesn't seem to be true.

Also, shortly after she says that static will not expose your api to the users, but the httpEndpoint will still be visible if you inspect app.js file. Is this the normal behaviour? What does she mean exactly then?

Thanks @yvess

I've been trying to use your approach, as like you I was using only smart queries but I would like to use the new Nuxt Full Static.

I don't know much about asyncData using apollo, but using your example I get the error:
[Vue warn]: Property or method "page" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. See: https://vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.
(I am using _page_ as per your example, but I also tried to just return { data } .

I also tried to do return console.log(data), which I don't know if it's correct and anyway doesn't return anything.

I'd expect to have the result in my template just using {{ data }}, and I am importing my .gql file (as I was already with smart queries). Any idea of what I am missing here?

@Saurou 'page' is part of my data you need to change it to you data variables. When data returns nothing than you graqphql query is wrong

Yes, I changed it for my queries and still using my .gql files that were working with smart queries.

in the end I have something like:
<div>{{ home.title }}</div>

then in the

I was not able to update this ticket about my solution. Like you said smart queries are not yet supported so I use this instead.

export default {
  components: {
    Pagination
  },
  async fetch() {
    const response = await this.$apolloProvider.defaultClient.query({
      query: articlesQuery,
      variables: {
        start: this.resultsPerPage * (this.currentPage - 1),
        limit: this.resultsPerPage,
        sort: 'date:DESC'
      }
    })

    this.articles = response.data.articles
    this.totalRecords = response.data.articlesConnection.aggregate.count
    this.refreshData()
  },
  fetchOnServer: true,
  data() {
    return {
      articles: [],
      query: '',
      resultsPerPage: 5,
      currentPage: 1,
      totalRecords: 0,
      loading: 0,
      filteredArticles: []
    }
  },
  computed: {
    pageCount() {
      return Math.ceil(this.articles.length / this.resultsPerPage)
    }
  },
  methods: {
    getAuthorText(author, index, authors) {
      return author.name + (index < authors.length - 1 ? ',' : '')
    },
    refreshData() {
      if (process.client) window.scrollTo({ top: 0 })
      // this.$apollo.queries.articles.refetch()

      this.filteredArticles = take(
        drop(this.articles, (this.currentPage - 1) * this.resultsPerPage),
        this.resultsPerPage
      )
    },
    onPageChange(page) {
      this.currentPage = page
      this.refreshData()
    },
    isEmptyImage(listImage) {
      return isEmpty(listImage)
    },
    formatDate(date, pattern) {
      return format(date, pattern)
    }
  }
}

also don't forget to generate the route of each page on your nuxt.config.js

Thanks @shidcordero ! Unlike the asyncData method I was trying, with fetch I can pull the data in my pages.

Unfortunately when I test it with Nuxt Serve, I can see graphql it's not fetched but pages aren't loading. So I have to understand why.

Is it related to your "also don't forget to generate the route of each page on your nuxt.config.js"? should not be automatic apart for dynamic pages? (and even those if I read right are now generated automatically following nuxt-link)

Thanks @shidcordero ! Unlike the asyncData method I was trying, with fetch I can pull the data in my pages.

Unfortunately when I test it with Nuxt Serve, I can see graphql it's not fetched but pages aren't loading. So I have to understand why.

Is it related to your "also don't forget to generate the route of each page on your nuxt.config.js"? should not be automatic apart for dynamic pages? (and even those if I read right are now generated automatically following nuxt-link)

Something similar is happening to me. I have two websites deployed with full static. One works, the other behaves as you describe. Payload files are generated as expected, i can see them being loaded but the content never gets replaced.

As soon as i switch to “server” mode and run nuxt generate, all works as expected (but obviously no payload files are used).

thats why its called full static as it intends to be fully static data(from payload) you wont expect it to fetch the data as it generates it upon building. thats the purpose of generating each route on nuxt.config to get each pages data(payload). if you expect it to have dynamic content then you should not use full static.

I understand how it works. I have all routes generated and the payload files are being loaded, but the data() is never updated with the payload's contents. I'll submit a seperate issue with a PoC tomorrow.

Thanks @shidcordero ! Unlike the asyncData method I was trying, with fetch I can pull the data in my pages.

Unfortunately when I test it with Nuxt Serve, I can see graphql it's not fetched but pages aren't loading. So I have to understand why.

Is it related to your "also don't forget to generate the route of each page on your nuxt.config.js"? should not be automatic apart for dynamic pages? (and even those if I read right are now generated automatically following nuxt-link)

well. nuxt-link will prefetch the index page but not the payload. as part of their current issues they specify in the blog that:

You have to specify all your dynamic routes in generate.routes, making it harder since you don't have access to nuxt modules there.

which dynamic route like in my case is the list of articles.

thats why its called full static as it intends to be fully static data(from payload) you wont expect it to fetch the data as it generates it upon building. thats the purpose of generating each route on nuxt.config to get each pages data(payload). if you expect it to have dynamic content then you should not use full static.

That's exactly what I want, and the very first reason why I dropped the smart queries in the first place.
Smart queries were still fetching, ignoring the full static, this is also why you opened this issue, right? (just in case I am misunderstanding it all :D )
Now with fetch doesn't do it anymore (which is good) but pages are empty (instead of using the payload).

about dynamic routes, the article you are mentioning makes a list of Current issues. Now, to me sounds like he's talking about the pre-full static (before 2.13) nuxt generate, as he opens the article with those and _then_ he talks with enthusiasm about 2.13 full static.

Which makes me think (but I think I've read it somewhere else) the full static should check all the nuxt link and generate those pages too, even if they're dynamic. Of course I might be wrong but that will be the next step to check :)

_small update:_

I've been trying to make apollo work with the new full static and so far I had the following results:

1. fetch works on pages, layouts and components, and loads content fine from my query. When using nuxt dev all works good. When testing it with nuxt serve (after nuxt build && nuxt export) pages are generated fine.
ISSUE: pages do not get loaded when navigating during nuxt serve (testing full static).
Code:

async fetch() {
  const layoutresult = await this.$apolloProvider.defaultClient.query({
    query: layoutQuery
  })
  this.layout = layoutresult.data.layout
},
data() {
  layout: {}
}

2. to try to solve the above issue, I changed all the fetch in pages to asyncData. This works fine on nuxt dev and also while testing with nuxt serve. Of course there is an annoying inconsistency here, as asyncData it's used in pages, while fetch it's used in layouts and components.
Code:

async asyncData({app}) {
  const homeresult = await app.apolloProvider.defaultClient.query({
    query: homeQuery
  })
  return { home: homeresult.data.home }
},
data() {
  home: {}
}

This might not apply to you, but these are 2 possible outcomes:

  1. I should use fetch everywhere, and the reason why pages aren't correctly loading on the static site is related to something else I can't yet see.
  2. I should use asyncData on pages, and fetch on layout.

I have chosen 2. as it works... however, fetch() works because it's in the layout and loads directly from the static generated first loaded page. When I tested it with components, data wasn't loading in the same way it doesn't when used in pages.

Pretty sure this is related to #322 and that thus module needs to be updated to use fetch() behind the scenes.

The more I use Apollo with Vue, the more frustrated I am with it. It feels like it's built by React devs, not Vue devs. Just so verbose and complicated, also kind of doubles up with Vuex.

I'm going to give this a try on our next project.
https://github.com/Gomah/nuxt-graphql-request

Works way more inline with how Nuxt wants you to use the fetch() hook.

The more I use Apollo with Vue, the more frustrated I am with it. It feels like it's built by React devs, not Vue devs. Just so verbose and complicated, also kind of doubles up with Vuex.

I'm going to give this a try on our next project.
https://github.com/Gomah/nuxt-graphql-request

Works way more inline with how Nuxt wants you to use the fetch() hook.

💯 this... just set up a new project to test some stuff, fraught with errors and frustrating from the off.. going to chek this alternative you posted, thanks 👍

The more I use Apollo with Vue, the more frustrated I am with it. It feels like it's built by React devs, not Vue devs. Just so verbose and complicated, also kind of doubles up with Vuex.

I'm going to give this a try on our next project.
https://github.com/Gomah/nuxt-graphql-request

Works way more inline with how Nuxt wants you to use the fetch() hook.

Could not agree more with this. I have been using Apollo for about over a year, and thought it was the most viable solution despite constantly bumping into issues and overhead in performance for static builds.

This is a great and easy module to set up and replace Apollo on smaller builds on Nuxt. Thank you for the suggestion!

I have encoured the same problem, and the code bellow works fine for me :

import gql from 'graphql-tag'
export default {

  async asyncData ({app, route}) {
    let client = app.apolloProvider.defaultClient
            const posts = await client.query({
            query: gql`
        query getPosts ($tagSlugAnd : [String]) {
  posts(first: 100, where: {tagSlugAnd: $tagSlugAnd }) {
    edges {
      node {
        slug
        categories {
          edges {
            node {
              name
            }
          }
        }
        tags {
          edges {
            node {
              name
              slug
            }
          }
        }
      }
    }
  }
}
        `,
        variables: { tagSlugAnd : route.params.slug }
        })

        return { posts : posts.data.posts }
  },

    data(){
        return{
            posts:'',
}

any news on this ? nuxt full static with apollo smart queries ?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

wan2land picture wan2land  ·  8Comments

lindesvard picture lindesvard  ·  7Comments

gomezmark picture gomezmark  ·  9Comments

dmitryyankowski picture dmitryyankowski  ·  9Comments

Vlaoff picture Vlaoff  ·  6Comments