• nuxt
  • graphql
  • jamstack

Static website and GraphQL queries with Nuxt.js

Graphql client is king.

Published on : August 5, 2021

The problem

I encountered a nasty bug while using static generation with Nuxt and nuxt apollo client. I found the issue already reported on github.

It seems the module doesn't handle static generation correctly with nuxt generate.

I could find request to my local API url after the static generation. Moreover, it also seemed like <nuxt-link> navigation was broken.

The solution 🙌

Fortunately, there is another Nuxt module that handles GraphQL requests!

[Nuxt graphql request to the rescue!](https://github.com/gomah/nuxt-graphql-request 'Working module github repository's (new tab)')

The conf

buildModules: [
graphql: {
  clients: {
    default: {
      endpoint: 'http://API_URL/graphql',
      options: {
        headers: {
          authorization: 'Bearer API_TOKEN',

The request

The best approach so far is to use asyncData in pages and fetch in components. Using fetch in pages does not work well at all with nuxt generate.

I also install the graphql-tag package (only in devDependencies) to be able to import directly .gql files.

Query example:

query {
  homepage {
    hero {

Inside a page

import homepageQuery from '~/graphql/queries/singles/homepage'

export default {
  async asyncData({ $graphql }) {
    const data = await $graphql.default.request(homepageQuery)
    return { data }

Inside a component

It is safer to wait until fetch has received a response before displaying anything. You can use $fetchState to be sure (documentation).

  <header v-if="!$fetchState.pending"></header>

import headerQuery from '~/graphql/queries/singles/header'

export default {
  data() {
    return {
      data: {},
  async fetch() {
    try {
      const data = await this.$graphql.default.request(headerQuery)
      this.data = data
    } catch (error) {
      console.error(JSON.stringify(error, undefined, 2))


To pass options to the request, for example for a multilingual version with nuxt/i18n and/or a url parameter in a dynamic page:

import articleQuery from '~/graphql/queries/articles'

export default {
  async asyncData({ $graphql, app, params }) {
    const locale = app.i18n.localeProperties.iso
    const data = await $graphql.default.request(articleQuery, {
      code: locale,
      slug: params.slug,
    return { data }