Clean URLs with Dynamic Routing

Dynamic Routing

Here, we are going to use the Dynamic Routing feature of Next.js, it allows you to handle dynamic routes in /pages.

Let's create our first dynamic route by adding a new page to pages/p/[id].js, notice that you need to add the folder /p inside /pages first, and that the page is called [id].js. Then add the following content:

import { useRouter } from 'next/router';
import Layout from '../../components/MyLayout';

export default function Post() {
  const router = useRouter();

  return (
    <Layout>
      <h1>{router.query.id}</h1>
      <p>This is the blog post content.</p>
    </Layout>
  );
}

The previous page is special, instead of handling a static route like /about, it will handle routes that come after /p/. For example, /p/hello-nextjs will be handled by this page. Although, /p/post-1/another will not.

Having brackets ([]) in the page name makes it a dynamic route. Currently, you can not make part of a page name dynamic, only the full name. For example, /pages/p/[id].js is supported but /pages/p/post-[id].js is not currently.

When creating the dynamic route we added id between the brackets ([]). This is the name of the query param received by the page, so for /p/hello-nextjs the query object will have { id: 'hello-nextjs'}, and we can access it with useRouter().


Now let's add multiple links that use our new dynamic route, Use the following code for pages/index.js:

import Layout from '../components/MyLayout';
import Link from 'next/link';

const PostLink = props => (
  <li>
    <Link href="/p/[id]" as={`/p/${props.id}`}>
      <a>{props.id}</a>
    </Link>
  </li>
);

export default function Blog() {
  return (
    <Layout>
      <h1>My Blog</h1>
      <ul>
        <PostLink id="hello-nextjs" />
        <PostLink id="learn-nextjs" />
        <PostLink id="deploy-nextjs" />
      </ul>
    </Layout>
  );
}

Have a look at the following code block:

const PostLink = props => (
  <li>
    <Link href="/p/[id]" as={`/p/${props.id}`}>
      <a>{props.id}</a>
    </Link>
  </li>
);

In the <Link> element, the href prop is now the path of the page in the pages folder and as is the URL to show in URL bar of the browser.


Now try to click on the first blog post and you'll be navigated to the blog post.

After that, hit the back button and then hit the forward button. What happened?