Reputation: 295
I am using the App Router in Next JS, and Strapi as my CMS. When I query the API in Postman, I get the expected results. Bad routes without corresponding slugs return a 404, and only routes with slugs return a 200 with data.
However, in my Next JS front-end, all routes resolve 200, and if there isn't a slug, it just returns an empty data array. I can check for the empty array and push the 404 error page, but that seems like bad idea for a number of reasons.
I can't seem to find any answer for the correct way to do this. This answer seems to be out of date with the old pages router. How do I return a 404 on a bad route with dynamic routing with the App Router approach?
Here is my current front-end code, with folder structure app/works/[slug]/page.js
'use client'
import axios from 'axios';
import useSWR from 'swr';
import { useRouter } from 'next/navigation';
const fetcher = (url) => axios.get(url).then((res) => res.data.data);
export default function SingleWork({ params }) {
const router = useRouter();
const { slug } = params;
const { data, error, isLoading } = useSWR(
`http://localhost:1337/api/works?filters[slug][$eq]=${slug}&populate=*`,
fetcher
);
if (error) {
return (
<div>Failed to load</div>
)
}
if (isLoading) {
return (
<div>Loading...</div>
)
};
if (!data[0]) {
router.push("/404")
} else {
return (
<div>My Post: {JSON.stringify(data)}</div>
)
}
}
Upvotes: 0
Views: 761
Reputation: 334
To make Next.js return a 404 status for routes with dynamic parameters that don't match your defined routes, you can set the dynamicParams in layout or page file.
export const dynamicParams = false // true | false,
true (default): Dynamic segments not included in generateStaticParams are generated on demand.
false: Dynamic segments not included in generateStaticParams will return a 404.
Upvotes: 1
Reputation: 562
Remove the custom 404 handling from your SingleWork component. You will handle it in the getServerSideProps function.
Create a pages/app/works/[slug].js file with the following content:
import axios from 'axios';
export default function SingleWork({ data }) {
return (
<div>My Post: {JSON.stringify(data)}</div>
);
}
export async function getServerSideProps({ params }) {
const { slug } = params;
try {
const response = await axios.get(
`http://localhost:1337/api/works?filters[slug][$eq]=${slug}&populate=*`
);
const data = response.data.data[0];
if (!data) {
return {
notFound: true, // This will trigger a 404 error
};
}
return {
props: { data },
};
} catch (error) {
console.error('Error fetching data:', error.message);
return {
props: {},
};
}
}
By utilizing the getServerSideProps function, you can perform the data fetching on the server side and handle the 404 error condition correctly. If the data is not found, the notFound property is set to true, resulting in a 404 error response. Otherwise, the fetched data is passed as props to the component.
Upvotes: 0