如何使用Next.js进行动态路由,如果找不到路由则重定向到404?

aiazj4mn  于 2023-10-18  发布在  其他
关注(0)|答案(2)|浏览(144)

我目前正在尝试使用Next.js 13和app文件夹创建一个动态路由,我的请求是我想定义一些静态路由,如果slug与我输入的内容不匹配,它将返回404页面
这是我在13.0.5pages文件夹下一个版本所做的,这是工作很好,如果我要去一个不存在的页面,如/pages/post/foo,我被重定向到404页

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

现在我尝试对app文件夹和这个版本的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;

但问题是它根本不工作,我的意思是动态路由工作,但如果我尝试类似/post/foo的东西,它不会显示404页面我正在使用next-intl进行区域设置更改
我想的一个解决办法是这样做

import { notFound } from "next/navigation";

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

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

但我想知道是否有更好的解决方案,提前感谢!

qnzebej0

qnzebej01#

https://nextjs.org/docs/app/api-reference/file-conventions/route-segment-config
https://nextjs.org/docs/app/api-reference/file-conventions/not-found
您可以使用dynamicdynamicParams的组合,并结合路由所在文件夹中的not-found.tsx来实现此效果。

// [id]/page.tsx

export default function IdPage({ id }: any) {
  return <>Something here...</>;
}

export async function generateStaticParams() {
  return ['1', '2', '3'].map((id) => ({
    id
  }));
}

export const dynamic = 'force-static';
export const dynamicParams = false;
quhf5bfb

quhf5bfb2#

如果你使用getStaticProps:

export const getStaticPaths: GetStaticPaths = async ()=> {
    return {
        paths: [], //you can define your paths
        fallback: "blocking"
    }
}

export const getStaticProps: GetStaticProps = async (context) => {
   const slug = context.params?.slug as string;
   const posts = getTutorialBySlug(slug) ?? null;

   if (!posts) {
       return {
           notFound: true,
       };
   }

   return {
       props: {
           posts: posts,
       },
   };
};

如果您正在使用get ServerSideProps:

export const getServerSideProps: GetServerSideProps = async (
  context
) => {
  const slug = context.params?.slug as string;
  const post = getPostBySlug(slug) ?? null;

  if (!post) {
    return {
      notFound: true, //redirects to 404 page
    };
  }

  return {
    props: {
      post,
    },
  };
};

相关问题