Dynamic content in Next.js in the router

How to set up dynamic content in Next.js website

insidePrevious postWe saw how to link the homepage to the blog page.

Blog is a great use case for Next.js, we will continue to addBlog post.

Blog posts have dynamic URLs. For example, a post titled "Hello World" might have a URL/blog/hello-world. The post titled "My second post" may have a URL/blog/my-second-post.

This content is dynamic and may be taken from databases, markdown documents or more.

Next.js can provide dynamic content based on:Dynamic URL.

We create a dynamic URL by creating a dynamic page with the following content[]syntax.

how is it? We add apages/blog/[id].jsfile. The file will be processed/blog/Route, as we mentioned above:/blog/hello-world,/blog/my-second-postAnd more.

In the file name[id]All content in square brackets that means dynamic will be placed inidParametersQuery attributesofrouter.

Okay, too much at once.

what exactly is itrouter?

The router is a library provided by Next.js.

We import fromnext/router:

import { useRouter } from "next/router";

Once we haveuseRouter, We use the following method to instantiate the router object:

const router = useRouter();

Once you have the router object, you can extract information from it.

In particular, we can[id].jsBy accessing the filerouter.query.id.

So let's continue to apply all these contents to practice.

Create a filepages/blog/[id].js:

import { useRouter } from "next/router";

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

return ( <> <h1>Blog post</h1> <p>Post id: {router.query.id}</p> </> ); };

Now if you gohttp://localhost:3000/blog/testRouter, you should see the following:

We can use thisidParameter to collect posts from the post list. For example, from the database. For simplicity, we will add aposts.jsonFiles in the project root folder:

{
  "test": {
    "title": "test post",
    "content": "Hey some post content"
  },
  "second": {
    "title": "second post",
    "content": "Hey this is the second post content"
  }
}

Now we can import it and import it fromidkey:

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> </> ); };

Reloading the page should show us the following results:

But this is not! Instead, we got an error in the console and also an error in the browser:

why? Because when the component is initialized during rendering, the data does not yet exist. In the next lesson, we will learn how to use getInitialProps to provide data to the component.

Now, add a littleif (!post) return <p></p>Check before returning to JSX:

import { useRouter } from "next/router";
import posts from "../../posts.json";

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

const post = posts[router.query.id]; if (!post) return <p></p>;

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

Everything is normal now. Initially, there is no dynamic when rendering the componentrouter.query.idinformation. After rendering, Next.js will use the query value to trigger an update, and the page will display the correct information.

If you look at the source code, it will be empty<p>Tags in HTML:

We will solve the problem of not being able to implement SSR as soon as possible, which will harm the loading time of our users, SEO and social sharing, as we have already discussed.

We can complete the blog example by listing the posts in the following articlespages/blog.js:

import posts from "../posts.json";

const Blog = () => ( <div> <h1>Blog</h1>

<span style="color:#f92672">&lt;</span><span style="color:#a6e22e">ul</span><span style="color:#f92672">&gt;</span>
  {Object.<span style="color:#a6e22e">entries</span>(<span style="color:#a6e22e">posts</span>).<span style="color:#a6e22e">map</span>((<span style="color:#a6e22e">value</span>, <span style="color:#a6e22e">index</span>) =&gt; {
    <span style="color:#66d9ef">return</span> <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">li</span> <span style="color:#a6e22e">key</span><span style="color:#f92672">=</span>{<span style="color:#a6e22e">index</span>}<span style="color:#f92672">&gt;</span>{<span style="color:#a6e22e">value</span>[<span style="color:#ae81ff">1</span>].<span style="color:#a6e22e">title</span>}<span style="color:#f92672">&lt;</span><span style="color:#960050;background-color:#1e0010">/li&gt;;</span>
  })}
<span style="color:#f92672">&lt;</span><span style="color:#960050;background-color:#1e0010">/ul&gt;</span>

</div> );

export default Blog;

By importing, we can link them to each post pageLinkFromnext/linkAnd use it in the posts loop:

import Link from "next/link";
import posts from "../posts.json";

const Blog = () => ( <div> <h1>Blog</h1>

<span style="color:#f92672">&lt;</span><span style="color:#a6e22e">ul</span><span style="color:#f92672">&gt;</span>
  {Object.<span style="color:#a6e22e">entries</span>(<span style="color:#a6e22e">posts</span>).<span style="color:#a6e22e">map</span>((<span style="color:#a6e22e">value</span>, <span style="color:#a6e22e">index</span>) =&gt; {
    <span style="color:#66d9ef">return</span> (
      <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">li</span> <span style="color:#a6e22e">key</span><span style="color:#f92672">=</span>{<span style="color:#a6e22e">index</span>}<span style="color:#f92672">&gt;</span>
        <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">Link</span> <span style="color:#a6e22e">href</span><span style="color:#f92672">=</span><span style="color:#e6db74">"/blog/[id]"</span> <span style="color:#a6e22e">as</span><span style="color:#f92672">=</span>{<span style="color:#e6db74">"/blog/"</span> <span style="color:#f92672">+</span> <span style="color:#a6e22e">value</span>[<span style="color:#ae81ff">0</span>]}<span style="color:#f92672">&gt;</span>
          <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">a</span><span style="color:#f92672">&gt;</span>{<span style="color:#a6e22e">value</span>[<span style="color:#ae81ff">1</span>].<span style="color:#a6e22e">title</span>}<span style="color:#f92672">&lt;</span><span style="color:#960050;background-color:#1e0010">/a&gt;</span>
        <span style="color:#f92672">&lt;</span><span style="color:#960050;background-color:#1e0010">/Link&gt;</span>
      <span style="color:#f92672">&lt;</span><span style="color:#960050;background-color:#1e0010">/li&gt;</span>
    );
  })}
<span style="color:#f92672">&lt;</span><span style="color:#960050;background-color:#1e0010">/ul&gt;</span>

</div> );

export default Blog;

Download mine for freeNext.js manual


More tutorials next: