Apollo query inside nuxt.config.js

2.3k views Asked by At

I'm trying to make a smart request in nuxt with nuxt-apollo-module in order to grab my routes for the nuxt-sitemaps-module (so I can create my sitemap with them).

I need to make this request from within nuxt.config.js file. I have tried this way with no luck (as app doesn't exist in this context). What would be the right way to do this? Thanks in advance!

The relevant part of my nuxt.config.js

import gql from 'graphql-tag'

module.exports = {

  modules: [
    '@nuxtjs/apollo',
    '@nuxtjs/sitemap'
  ],

  apollo: {
    clientConfigs: {
      default: {
        httpEndpoint: 'https://example.com/graphql'
      }
    }
  },


  sitemap: {
    path: '/sitemap.xml',
    hostname: 'https://example.com/',
    generate: true,
    cacheTime: 86400,
    trailingSlash: true,
    routes: async ({ app }) => {
      const myRoutes = ['/one-random-path/']
      let client = app.apolloProvider.defaultClient
      let myProductsQuery = gql`query {
          products {
              slug
          }
      }`
      let myBrandsQuery = gql`query {
          brands {
              slug
          }
      }`
      const myProducts = await client.query({ query: myProductsQuery })
      const myBrands = await client.query({ query: myBrandsQuery })

      return [myRoutes, ...myProducts, ...myBrands]
    }
  }
}
3

There are 3 answers

0
Paidge On

I gave up using Apollo. It was easier to use Axios. Moreover, no nneds to configure @nuxtjs/sitemap :

import axios from 'axios'

sitemap: {
    hostname: URL_SITE,
    gzip: true,
},
routes() {
    return axios({
        url: ENDPOINT,
        method: 'post',
        data: {
            query: `
                query GET_POSTS {
                    posts {
                        nodes {
                            slug
                        }
                    }
                }
            `,
        },
    }).then((result) => {
        return result.data.data.posts.nodes.map((post) => {
            return '/blog/' + post.slug
        })
    })
}
0
ryunishimura On

I was able to generate it this way, but I'm sure there is a better way.

yarn add node-fetch apollo-boost
sitemap: {
  routes: async () => {
    const routes = []
    const fetch = require("node-fetch")
    const { gql } = require("apollo-boost")
    const ApolloBoost = require("apollo-boost")
    const ApolloClient = ApolloBoost.default

    const client = new ApolloClient({
      fetch: fetch,
      uri: YOUR_API_ENDPOINT,
    })

    const fetchUsers = gql`
      query {
        users {
          id
        }
      }
    `

    const users = await client
      .query({
        query: fetchUsers,
      })
      .then((res) => res.data.users)

    users.forEach((user) => {
      routes.push({
        route: `/${user.id}`,
      })
    })

    return routes
  },
},
0
Quibble On

This was how I was able to do it with authentication. Got round to it by following the documentation here which had a Vue example: https://www.apollographql.com/docs/react/networking/authentication/

Might be a cleaner way to do it with apollo-boost if you can also use auth?

import fetch from 'node-fetch'
import { ApolloClient } from 'apollo-client'
import { HttpLink } from 'apollo-link-http'
import { ApolloLink, concat } from 'apollo-link'
import { InMemoryCache } from 'apollo-cache-inmemory'

import globalQuery from './apollo/queries/global.js'

const httpLink = new HttpLink({ uri: process.env.SCHEMA_URL, fetch })

const authMiddleware = new ApolloLink((operation, forward) => {
  // add the authorization to the headers
  const token = process.env.STRAPI_API_TOKEN
  operation.setContext({
    headers: {
      authorization: token ? `Bearer ${token}` : 'Bearer',
    },
  })
  return forward(operation)
})

export const apolloClient = new ApolloClient({
  link: concat(authMiddleware, httpLink),
  cache: new InMemoryCache(),
})

export default async () => {
  let global = null
  const globalResponse = await apolloClient.query({ query: globalQuery })
  if (globalResponse?.data?.global?.data) {
    global = globalResponse.data.global.data.attributes
  }

  console.log('globals:::', global)
}