How AI is powering better personalization in e-commerce [with Vercel]. Sign up now

Check if Sanity post exists in React Router v5/v6 before rendering

7 repliesLast updated: Nov 29, 2025

How can we check inside React Router V5 or V6 if a Sanity.io [type="post"] Exists? Currently, the NotFound component will not work it always returns a empty page.

const App = () => {

return (

<BrowserRouter>

<Routes>

&lt;Route element={&lt;AllPosts /&gt;} path="/" exact /&gt;

&lt;Route element={&lt;BlogSinglePost /&gt;} path="/blog/:slug" /&gt;

&lt;Route element={&lt;NotFound /&gt;} path="*" /&gt;

</Routes>

</BrowserRouter>

);

};
AI Update

The issue you're experiencing is that your BlogSinglePost component needs to check if the document exists and handle the case when it doesn't. React Router will always match the /blog/:slug route before the * wildcard route, so you need to handle the 404 logic inside your BlogSinglePost component itself.

Here's how to fix this:

In your BlogSinglePost component:

import { useParams, Navigate } from 'react-router-dom';
import { useEffect, useState } from 'react';
import { client } from './sanityClient'; // your Sanity client

const BlogSinglePost = () => {
  const { slug } = useParams();
  const [post, setPost] = useState(null);
  const [loading, setLoading] = useState(true);
  const [notFound, setNotFound] = useState(false);

  useEffect(() => {
    const query = `*[_type == "post" && slug.current == $slug][0]`;
    
    client.fetch(query, { slug })
      .then((data) => {
        if (!data) {
          setNotFound(true);
        } else {
          setPost(data);
        }
        setLoading(false);
      })
      .catch((error) => {
        console.error('Error fetching post:', error);
        setNotFound(true);
        setLoading(false);
      });
  }, [slug]);

  if (loading) return <div>Loading...</div>;
  if (notFound) return <Navigate to="/404" replace />;

  return (
    <div>
      {/* Your post content */}
      <h1>{post.title}</h1>
      {/* ... */}
    </div>
  );
};

Update your routes:

const App = () => {
  return (
    <BrowserRouter>
      <Routes>
        <Route element={<AllPosts />} path="/" exact />
        <Route element={<BlogSinglePost />} path="/blog/:slug" />
        <Route element={<NotFound />} path="/404" />
        <Route element={<NotFound />} path="*" />
      </Routes>
    </BrowserRouter>
  );
};

Key points:

This approach ensures that the document existence check happens at the data-fetching level, which is where it needs to be since React Router doesn't know anything about your Sanity content.

Show original thread
7 replies

Was this answer helpful?

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.

Related contributions