Using Sanity GROQ queries in nuxt.config.js for dynamic route generation

13 replies
Last updated: Feb 4, 2021
Hello everyone,I am struggling with something and I am surprised I am not able to find a solution out there. (I found an article on medium but their solution did not work for me).

I am using sanity with nuxt and since I am building my app/site with nuxt generate I need to make sure I can create all the dynamic routes in my nuxt.config.js
This is something I have done in other cases using REST APIs and axios.
Actually even in this case I have tried doing the below with axios and it worked.


let dynamicRoutes = () => {
  return axios
    .get(
      `<https://XXXXXXXX.api.sanity.io/v1/data/query/BLABLA?query=YYYYYYYYYYY>`,
      axiosconfig
    )
    .then((res) => {
      return res.data.result.map((el) =>
        el._type === 'bbb'
          ? `/detail-bbb/${el.slug}/`
          : `/detail-aaa/${el.slug}/`
      )
    })
}

// and then 
generate: {
    routes: dynamicRoutes,
  },
this works. I basically play with the API using vision and I copy the URL from there and with axios I am able to get this to work.

Anyways this is not good and I want to have my proper GROQ query and use sanity for it as I have done in my components and pages but I cannot get it done.

Is there any link you guys can point me to?
AI Update

I can definitely help you get this working with the proper @sanity/client and GROQ queries instead of using axios!

The solution is to use @sanity/client in your nuxt.config.js file to execute your GROQ queries. Here's how to do it:

First, make sure you have @sanity/client installed:

npm install @sanity/client

Then in your nuxt.config.js, import and configure the Sanity client at the top of the file:

const sanityClient = require('@sanity/client')

const client = sanityClient({
  projectId: 'YOUR_PROJECT_ID',
  dataset: 'YOUR_DATASET', // usually 'production'
  apiVersion: '2024-01-01', // use current date
  useCdn: false, // `false` if you want to ensure fresh data for build
})

const dynamicRoutes = async () => {
  const query = `*[_type in ["aaa", "bbb"]]{
    _type,
    "slug": slug.current
  }`
  
  const results = await client.fetch(query)
  
  return results.map((el) => 
    el._type === 'bbb'
      ? `/detail-bbb/${el.slug}/`
      : `/detail-aaa/${el.slug}/`
  )
}

export default {
  // ... other config
  generate: {
    routes: dynamicRoutes
  }
}

Key points:

  1. Use require() not import - Since nuxt.config.js runs in a Node context during build time, you need to use CommonJS require() syntax rather than ES6 imports

  2. Set useCdn: false - For build-time queries, you want fresh data directly from the API, not cached CDN data

  3. Use async/await - The client.fetch() method returns a Promise, so make your dynamicRoutes function async

  4. apiVersion - Always specify an API version. You can use today's date or a fixed date for consistency

If you're using Nuxt 3, the config file might be nuxt.config.ts and you can use ES6 imports:

import sanityClient from '@sanity/client'

const client = sanityClient({
  projectId: 'YOUR_PROJECT_ID',
  dataset: 'production',
  apiVersion: '2024-01-01',
  useCdn: false,
})

export default defineNuxtConfig({
  // ... other config
  hooks: {
    async 'nitro:config'(nitroConfig) {
      const query = `*[_type in ["aaa", "bbb"]]{ _type, "slug": slug.current }`
      const results = await client.fetch(query)
      
      const routes = results.map((el) => 
        el._type === 'bbb' ? `/detail-bbb/${el.slug}/` : `/detail-aaa/${el.slug}/`
      )
      
      nitroConfig.prerender.routes = routes
    }
  }
})

This gives you the proper Sanity client integration with full GROQ query support, just like you're using in your components! The Nuxt.js quickstart guide has more details on setting up Sanity with Nuxt.

Show original thread
13 replies
Hi! There's a nuxt channel. But give me a second and I'll show you an example repo with Nuxt.
oops I will post there or actually search there first. I did not know about it 🙂
are you using the nuxt-sanity module or the sanity client directly?
Hi Jerome. I tried both actually but with no success.In my pages I am importing the @nuxtjs/sanity and I am able to fetch data
(also, if your website doesn't have a lot of pages, you could just Nuxt dynamic crawler, which should be enabled by default)
hmm now it has a very few pages but I believe it will have a few hundereds soon so I am not sure that is appropriate 🙂
I added this note to the readme not long time ago: https://github.com/mornir/snipcart-web#note-on-nuxt-crawler
about using the nuxt-sanity module inside nuxt-config.js --&gt; https://github.com/nuxt-community/sanity-module/issues/3
thanks Jerome. That is actually why I would rather avoid the crawler. I would soon get expensive sanity bills hehe 🙂
the second link you sent me is the one I actually tried to follow with no success. I guess I will give it another try. I was hoping there was some other official or unofficial documentation about this since I thought it was a common scenario but you reminded me that with the auto crawler not many people needs this probably.

I will give that another try
thanks again!
when creating the client, it's important to also pass the name of the dataset (it doesn't default to 'production').
thank you! that example you passed me is actually new to me. I will have a look later today but at first sight it looks like it could work for me and probably I also see what I was missing in my previous attempts (I took for granted I did not need to import node-fetch)thank you very much again. I will write here later tonight if the solution worked with more details so that it can be helpful for others
🙂
yeah, the workaround with node-fetch is a bit weird. But if you use the official nuxt client (
import createClient from '@sanity/client'
), you don't need node-fetch and patching fetch.

Sanity – Build the way you think, not the way your CMS thinks

Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.

Was this answer helpful?