Dynamic routing for Now using NextJS

Robbert van Caem
3 min readDec 9, 2019

--

When I looked into Server Side Rendering (SSR) for React, I quickly encountered NextJS. Getting the hang of it took me some time, but since then it’s become a vital part of our digital products. Quickly I came across a very basic requirement: dynamic routing for blog posts.

The objectives

1. Informing Now about dynamic routes
2. Fetching a blog post using Next’s `getInitialProps` method
3. Using a HOC to render a custom error page when data can’t be found

1. Informing Now about dynamic routes

At OOGT, we deploy our applications to Now. When you’re using NextJS, deploying can be as simple as running `now`. It also comes with a handy `now dev` command so that you can locally mimic your Now deployment.

Now needs some knowledge about your application, and you can provide it through a `now.json` file. This typically looks something like this:

now.json

Here, the `name` is the name of your Now project. The `version` field is the version of Now deployments you’re using. The `builds` fields holds some configuration about your builder, which we won’t go into right now. Finally, the `routes` field is what we’re interested in right now. We’ll add a new entry to this.

now.json

What this entry will do is match any URLs after the `/`, and reroute them to the `Post` page, where `slug` is a property of the `query` object in the request context. So, the URL in the browser will be `/some-blog-post-title`, but under the hood it renders the `post` page component with a value of “some-blog-post-title” for the `slug` property in the `query` object. Sounds more difficult than it actually is:

pages/post.js

In the code above, the `getInitialProps` method provided by NextJS can be used to do some async task like data fetching. It returns an object with the props that can be used by our functional Post component.

Next up, let’s use this slug to fetch a blog post!

2. Fetching a blog post

In this example, we’ll pretend we have a Wordpress instance running somewhere which contains the blog posts. We’re going to use the REST API to fetch a blog post. We’ll use `axios` for the requests since this works both server and client-side.

data/posts.js

Notice how the returned object contains a `statusCode` of 404 if the returned response’s `data` object doesn’t contain any items. This is an indicator that the blog post does not exist. Otherwise, we’ll return a `statusCode` of 200 and a `post` property containing the actual data.

Question to self: does the Wordpress REST API actually return a statusCode of 200 for a non-existent post? It would be easier to just use the returned statusCode instead of assuming an empty response means it does not exist. Also, isn’t there an easier way of fetching a single post instead of using the first item in the returned array?

Now, we can use the `getPost` method in our Post component

pages/post.js

Now, the above will work just fine for this particular use case. However, imagine we have another page rendering some post that may or may not exist. We could put an if-statement in every page component checking the statusCode, but we can also use a Higher Order Component (HOC) to render an error page whenever some data fetching method returns a statusCode other than 200.

3. Using a HOC to render a custom error page

You can define a custom error page by creating a file `_error.js` in the `pages` directory. A simple error page could look something like this:

pages/_error.js

To render the error page I found this HOC Tim mentioned on Spectrum.chat which makes it very easy to reuse a custom error page.

hoc/withError.js

We can now use this for our page like this:
https://gist.github.com/robbertvancaem/9302adbc95bf5849f0545b22fc07184d

Got questions or feedback?

Do you know of an easier way of doing this? Or do you have any questions? I’m not claiming to be an expert in Now/NextJS whatsoever, but perhaps I can help digging into a problem you might run into.

Don’t forget to start following me here on Medium or on Twitter!

--

--

Robbert van Caem
Robbert van Caem

No responses yet