next.jsnext.js13

How to do dynamic routes with Next.js and redirect to 404 if route is not found?


I'm currently trying to make a dynamic route with Next.js 13 with app folder, my request is that I want to define some static routes and if the slug does not match with what I put, it'll return a 404 page

Here is what I did with Next version at 13.0.5 and pages folder and this was working great, if I'm going to an unexisting page like /pages/post/foo, I'm redirected to 404 page

// pages/post/[id].tsx
import { useRouter } from "next/router";

const Post = () => {
  const router = useRouter();
  const { id, foo } = router.query;

  return (
    <div>
      <p>Post: {id}</p>
    </div>
  );
};

export const getStaticProps = () => ({
  props: {},
});

export const getStaticPaths = () => ({
  paths: [{ params: { id: "abc" } }, { params: { id: "abcd" } }],
  fallback: false,
});

export default Post;

Now I'm trying to do the same with app folder and this version of Next.js 13.4.4

// app/[locale]/post/[id].tsx
export const dynamicParams = false;
export const generateStaticParams = async () => [{ id: "abc" }, { id: "abcd" }];

const Post = ({ params: { id } }) => (
  <div>
    <p>Post: {id}</p>
  </div>
);

export default Post;

But the issue is that it's not working at all, I mean by that that the dynamic route is working but if I try something like /post/foo, it's not showing a 404 page I'm using next-intl for the locale change

A solution I thought was to do this

import { notFound } from "next/navigation";

const Post = ({ params: { id } }) => {
  if (!['abc', 'abcd'].includes(id)) notFound();

  return (/* ... */);
};

But I wanted to know if there was a better solution, thanks in advance!


Solution

  • To throw a "not found" page in Next.js using App Router for dynamic URLs, you would do this:

    import { notFound } from 'next/navigation';
    
    type Params = {
      id: string;
    };
    
    export default function YourPage({ params }: { params: Params }) {
      // quick for demo purposes
      if (params.id === '123') {
        notFound();
      }
    
      return (
        <p>Look at this page, this page is amazing!</p>
      );
    }
    

    See the official Next.js documentation here: https://nextjs.org/docs/app/api-reference/functions/not-found