Easy static HTML exports of your Next.js + GraphQL site
March 1st, 2019
You’re here because you’d like to learn how to create static HTML exports for your Next.js site which uses GraphQL as a data source to create dynamic pages from page components. And that site may even use WPGraphQL to pull content from WordPress.
Fantastic, this article will describe the simple process of doing exactly that.
Generally speaking, all else being equal, serving a static HTML file as a webpage is generally going to be the fastest way to get that page in your users hands. There are exceptions to every rule, but this is a pretty safe bet. This speed is great for SEO, UX, conversion rates, blah blah blah, but building a site that delivers that fast is also just fun!
Bare with me for a few moments as we setup the solution with a bit of boilerplate.
As you will see if you peruse the interactive Next.js docs, they have a simple method of enabling static HTML exports. Create a file in your project at the root directory called
next.config.js, and add the following code:
Then add the following to
And then run:
Now checkout the
out directory. You’ll see static HTML file for your
index route. You can now run the following to see your site in action:
The Next.js docs then extend this example with the following code snippet:
What we are doing here on the lines starting with
'/p…' is passing query data to the component at
Ok, now the problem becomes clear: we need a data source to populate the
date, etc.) that our components rely on. But the
next export doesn’t “hook into” the GraphQL data source you have likely already setup in your
So does this mean you need to rewire everything to hook up GraphQL, write fetching logic, looping, etc?
No, it means I had to. You can just install the NPM package I created and do some basic configuration. 🙂
A minimal package which provides the functionality required to perform a static HTML export of dynamic pages from Next.js when using GraphQL as a data source.https://www.npmjs.com/package/next-graphql-static-export
Ok, end of boilerplate setup. Let’s get down creating your Next.js+GraphQL+WPGraphQL+static-HTML-exported site.
By the way, you do not need to include WPGraphQL in your project to make use of this method. Though if your site has a WordPress backend, you probably should.
There are no assumptions in the code for the NPM package which rely on WPGraphQL, other than possibly the schema.
Here is the relevant bit of the WPGraphQL schema in a query result:
Notice the nesting of
hasNext page, along with
nodes. It’s worth taking a quick look at the results you get from queries on your project if you are not using WPGraphQL. If your GraphQL server does not return data in this format, no problem, you can still easily use this package. You’ll just need to write a custom query result parsing function. Details below.
We’ll assume for the moment that your GraphQL server does have the same schema as WPGraphQL and move on.
First install ‘next-graphql-static-export’:
Now create a new
config-exports.js file in the root directory of your project, where we will configure the parameters that we pass to the
processContent made available via the
next-graphql-static-export library. The following is an example of sensible defaults:
Open up your
package.json again, and add change the line pertaining to the
dev script to the following:
EXPORT env var will allow us to continue to use
npm run dev to develop our site, yet avoid doing a full static HTML export every time we change a line of code (see next step for where we use this env var).
Open up your
next.config.js again, and make it look similar to the following:
Now go ahead and run the following again:
Open up localhost:8080 and you should see your beautiful site with all dynamic page fully rendered and served as static HTML!
If your schema differs from the one shown above, then you will need to pass your own query result parsing function to your typeParams in your config-export.js file. Here is an example function which exactly reproduces the existing functionality:
Note that the function takes in the
queryResponse, and the current
contentType, both of which are used to destructure the query result and return the following required values:
You can use any amount of logic in this function, but those values are required.
To use this function in your implementation, simply add the function as a parameter to the relevant content types. So our new
config-exports.js would look like this:
And that’s all there is to adapting this module to a different schema than the one natively expected. Feel free to reach out with any questions.