Reputation: 1077
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!
Upvotes: 4
Views: 11458
Reputation: 139
If you are using 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,
},
};
};
If you are using 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,
},
};
};
Upvotes: -2
Reputation: 116
https://nextjs.org/docs/app/api-reference/file-conventions/route-segment-config
https://nextjs.org/docs/app/api-reference/file-conventions/not-found
You can use a combination of dynamic
and dynamicParams
to achieve this effect in combination with a not-found.tsx
in the folder your route lives at.
// [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;
Upvotes: 3
Reputation: 1360
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
Upvotes: 7