Headless CMS with GraphQL and Dynamic Routes in NuxtJS

Posted: Reading Time:

So you're working on an awesome headless CMS (for this tutorial, I'm using Craft CMS), you got GraphQL running, it's returning data, and you're feeling really good about your project. Now you're ready to hook it up to NuxtJS and have Nuxt generate flat files for you to deploy to Netlify (or some other static file hosting solution). You go ahead and run `nuxt generate` and to your dismay, you notice that Nuxt ignored all of our dynamic routes for your blog posts. If you take a look at the Nuxt documentation, you'll notice that unfortunately, dynamic routes are ignored by this `generate` command. Nuxt doesn't know what all of your possible dynamic routes are, so it can't generate them.

Warning: dynamic routes are ignored by the generate command: API Configuration generate

When I first saw this warning in the documentation, I was pretty worried I was going to be screwed. After doing some research, and a few late-night epiphanies, I figured out how to tell Nuxt about my dynamic routes.

Telling Nuxt about your "Dynamic" Routes

You can manually define the routes that Nuxt should generate static files for by including a `routes` object in your nuxt.config.js file. It might look like something like this:

generate: { routes: [ 'blog/entry-1', 'blog/entry-2', 'blog/entry-999' ] }

That's all well and good, but you don't want to have to manually put all of your entries from your headless CMS into this static file, and then manually redeploy.

To get around this, we can dynamically tell Nuxt to fetch our dynamic routes. Pretty meta, huh?

Dynamically generating Dynamic Routes

Instead of manually putting in paths to that `routes` object, we can query our GraphQL endpoint for all of the URIs we need, and then load that into our nuxt.config.js file. Then, next time we run our `generate` command, it will pull in all of the URIs that we have in our app. I created a new file in the root of my project called dynamicGen.js. It looks something like this:

Now that you have this file, and replaced all of my placeholder values with your real API values, you should be good to run it and generate all the URIs that Nuxt will need. We can run this code on our server using node. Give it a try by running `node dynamicGen.js` in the root of your project. If everything went well, you should see your array of URIs in the console, as well as a "Dynamic pages successfully written!" message. Lastly, you should have a new dynamicPages.json file in the root of your project.

Telling Nuxt about your Real Dynamic Routes

We're almost there! We now need to tell our nuxt.config.js file about our dynamic routes file. To do this, we can import our dynamicPages.json file into the top of our file:

var pages = require('./dynamicPages.json')

Once it is imported, we can replace our hardcoded `routes` object with this pages variable:

generate: { routes: pages }

Rad. This should be all we need to tell Nuxt about all of our dynamic pages.

Dynamic Pages and your Deployment Pipeline

Nuxt knows about our dynamic pages, but there is some manual work in here where we have to run some commands on our own. We can automate these commands so that they are run automatically as part of our deployment process to Netlify, Amazon S3 bucket, Github pages, etc. 

I like to set up script aliases inside of my package.json file so everything is self-contained and easy to remember. In your package.json file, go ahead and add a new item to your "scripts" array:

"scripts": {  ...  "pages": "node dynamicGen.js"} 

Instead of running `node dynamicGen.js`, we can now run `npm run pages`. It's a bit easier to remember and will look a little nicer when we start to daisy-chain these commands together in our build process.

Deploying to Netlify

For this project, I'm using Netlify to deploy and host my project. The steps below should be pretty similar for whatever other build tools you need to use though.

In Netlify, you can issue a build command and a subsequent publish directory to host all of your static files. A typical build command for Nuxt would be `npm run generate` which would call `nuxt generate`. Before we run that however, we want to run our dynamicGen.js file to get all of our dynamic routes, and then run our generate function. We can do run multiple commands by adding `&&` in between them.

npm run pages && npm run generate

Our custom run pages command will run first, and then as soon as that's done, it will run our traditional generate command and deploy those to Netlify. 

I have an additional command in here to generate a custom schema, that I needed to add to get Matrix fields working with GraphQL and ApolloJS to fix a "WARNING: heuristic fragment matching going on!" warning (that was really an error). [TODO ADD LINK HERE TO OTHER ARTICLE]
 

Conclusion

The progression of the JAM stack is moving crazy fast, and while it's certainly exciting, stuff isn't always documented that well. I hope this helps resolve any head scratches you ran into while trying to get Nuxt dynamic routes to work with your headless CMS. How did this work out for you? Work just right? Run into trouble? Feel free to let me know on twitter, @ErskineRob.

If you need help with a Vue/Nuxt/GraphQL project, I'd love to help out.

Go to the Home Page

Hey there,

I’m a creative designer, developer, and leader obsessed with solving complex problems

Check this Nerd Out!

Go to the Resume Page

Résumé

Experience & Accolades

Over ten years and going strong

Go to the About Page

About Me

Bios & Photos

A story to rival the Star Wars universe

Go to the Professional Work Page

Pro Work

Case Studies

Go to the Blog Page

Writing

Articles

Latest:

Go to the Contact Page

Contact

Social & Contact Form

Slide into my DMs :)

Go to the Non-Profit Work Page

Non-Profit Work

Case Studies

Go to the Activity Page

Activity

Updates

Latest:

Go to the For-Fun Page

For Fun

Case Studies