404 Error in Category Menu in Sanity + Next.js
Based on your description, you're running into a common Next.js routing issue when working with Sanity. The problem is likely that when you create a top-level pages/[slug].js file by copying from pages/posts/[slug].js, the GROQ queries are still configured for the nested route structure and aren't returning the correct data for your category pages.
Here's what's probably happening:
The 404 Error: When you copied the code from pages/posts/[slug].js to pages/[slug].js, the getStaticPaths function is still querying for posts with slugs, but your top-level route needs different logic. Next.js returns a 404 when getStaticPaths doesn't return the slug you're trying to access, or when getStaticProps can't find the content for that path.
Common fixes:
- Update your GROQ query in
getStaticPathsto fetch the right content type. If you want to show category pages at the root level, your query should look for categories instead of posts:
export async function getStaticPaths() {
const paths = await client.fetch(
`*[_type == "category" && defined(slug.current)][].slug.current`
);
return {
paths: paths.map((slug) => ({ params: { slug } })),
fallback: true, // or 'blocking'
};
}- Update
getStaticPropsto fetch the category and its associated posts:
export async function getStaticProps({ params }) {
const { slug } = params;
const category = await client.fetch(
`*[_type == "category" && slug.current == $slug][0]`,
{ slug }
);
const posts = await client.fetch(
`*[_type == "post" && references(*[_type == "category" && slug.current == $slug]._id)]`,
{ slug }
);
return {
props: {
category,
posts,
},
revalidate: 60,
};
}About the CORS error: This usually happens when you're trying to call the Sanity API from the client-side (like in a React component) without proper configuration. Always fetch Sanity data in getStaticProps, getServerSideProps, or API routes—never directly in components during client-side rendering. The Vercel with-sanity example does this correctly by keeping all Sanity queries in Next.js data fetching functions.
Why pages/posts/[slug].js works but pages/[slug].js doesn't: The nested route works because its queries are specifically configured for that route structure. When you copy it to the root level without adjusting the queries, it's looking for content that may not exist at those paths, or the query results don't match what the root-level route expects.
The misplaced comma issue you mentioned in the original thread is actually quite common! JavaScript syntax errors in getStaticPaths or getStaticProps can cause cryptic errors that manifest as 404s or CORS issues.
The key takeaway: make sure your getStaticPaths returns the slugs that actually exist for your category content type, and getStaticProps fetches the right data for those slugs. The queries need to match your schema and the route structure you're building.
Sanity – Build the way you think, not the way your CMS thinks
Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.