When adding dynamic content to Next.js, there may be instances where you need to dynamically generate a page that requires data upfront. One way to achieve this is by utilizing the getInitialProps function. In this blog post, we will explore how to feed data to a Next.js component using getInitialProps.

First, let’s take a look at an example where we encountered an issue while trying to get data from a JSON file for a dynamically generated post page. Here’s the code snippet:

import { useRouter } from 'next/router'
import posts from '../../posts.json'

export default () => {
 const router = useRouter()

 const post = posts[router.query.id]

 return (
 <>
 <h1>{post.title}</h1>
 <p>{post.content}</p>
 </>
 )
}

Unfortunately, this approach led to an error. So, how do we solve this problem and make Server-Side Rendering (SSR) work for dynamic routes?

To provide the component with the necessary props, we can use the getInitialProps function, which needs to be attached to the component. Here’s how:

const Post = () => {
 //...
}

Post.getInitialProps = () => {
 //...
}

export default Post

The getInitialProps function takes an object as its argument, which contains several properties. For our current purpose, we are interested in the query object, which we previously used to get the post ID. We can extract this object using object destructuring syntax as follows:

Post.getInitialProps = ({ query }) => {
 //...
}

Now, we can return the post from within this function:

Post.getInitialProps = ({ query }) => {
 return {
 post: posts[query.id]
 }
}

Furthermore, we can remove the import of useRouter and access the post from the props property passed to the Post component:

import posts from '../../posts.json'

const Post = props => {
 return (
 <div>
 <h1>{props.post.title}</h1>
 <p>{props.post.content}</p>
 </div>
 )
}

Post.getInitialProps = ({ query }) => {
 return {
 post: posts[query.id]
 }
}

export default Post

By implementing these changes, the error will be resolved, and SSR will be functional as expected.

It’s important to note that getInitialProps is executed on both the server-side and the client-side. This means that when navigating to a new page using the Link component, the function will be executed on the client-side. Additionally, getInitialProps receives the following properties in the context object:

  • pathname: the path section of the URL
  • asPath: a string of the actual path (including the query) shown in the browser

For example, calling http://localhost:3000/blog/test will result in the following values for pathname and asPath respectively:

  • /blog/[id]
  • /blog/test

If server-side rendering is involved, getInitialProps will also receive the following properties:

  • req: the HTTP request object
  • res: the HTTP response object
  • err: an error object

These properties are familiar if you have experience with Node.js coding.