Checking if a post exists in React Router V5 or V6 and redirecting to 404 page component.

7 replies
Last updated: Mar 10, 2021
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>

<Route element={<AllPosts />} path="/" exact />

<Route element={<BlogSinglePost />} path="/blog/:slug" />

<Route element={<NotFound />} path="*" />

</Routes>

</BrowserRouter>

);

};
Mar 10, 2021, 2:22 PM
Not an answer to your question. But couldn't you do this in the BlogSinglePost page instead, by checking if the data returned from the fetch command is an empty array?
Mar 10, 2021, 2:53 PM
import { useEffect, useState } from "react";

import { useParams } from "react-router-dom";


import SanityClient from "sanity.client";

import { getImage, TheContent } from "sanity.helpers";


import Loader from "components/Loader";


const BlogSinglePost = (props) => {

const [singlePost, setSinglePost] = useState(null);

const [loading, setLoading] = useState(true);

const { slug } = useParams();

const { projectId, dataset } = SanityClient.clientConfig;


useEffect(() => {
`const singlePostQuery = ``

*[slug.current == $slug] {

_id,

title,

slug,

mainImage {

alt,

asset -> {

_id,

url

}

},

body,

"name": author->name,

"authorImage": author->image,

"authorImageAlt": author->image

}
``;`


setTimeout(() => {

setLoading(false);

}, 500);


SanityClient.fetch(singlePostQuery, { slug })

.then((data) => (setSinglePost(data.length === 0) ? {} : data))

.catch(console.error);

}, [slug]);


// if (!singlePost || loading) return <Loader />;


if (!singlePost) return <div>Loading...</div>;

if (Object.keys(singlePost).length === 0)

return <div>Article not found...</div>;


return (

<>

{singlePost &&

singlePost.map((post) => (

<div key={post._id}>

<h2>{post.title}</h2>

<img src={getImage(post.authorImage).width(100).url()} alt="" />

<h4>{post.name}</h4>

{post.mainImage && (

<img

src={getImage(post.mainImage).width(860).url()}

alt={post.mainImage.alt}

/>

)}

<TheContent

blocks={post.body}

projectId={projectId}

dataset={dataset}

/>

</div>

))}

</>

);

};


export default BlogSinglePost;
Mar 10, 2021, 3:19 PM
Hi!
I have tried this. But for some reason it keeps loading.
Mar 10, 2021, 3:21 PM
.then((data) => (setSinglePost(data.length === 0) ? {} : data))

This looks like the parentheses aren’t ordered correctly. Would you mind trying:


.then((data) => (setSinglePost((data.length === 0) ? {} : data)))
Mar 10, 2021, 3:22 PM
user A
Hi there!
I have tried the code which you have shared. It works for articles that are not found. But for some reason, if it does exist it stops at loading..
Mar 10, 2021, 3:26 PM
Solved!!! Any idea how I can redirect to the React Router 404 page component?
user A
Mar 10, 2021, 3:26 PM
In this example it looks like they’re passing the 404 component via children rather than the
element
prop.
Mar 10, 2021, 3:56 PM

Sanity– build remarkable experiences at scale

Sanity is a modern headless CMS that treats content as data to power your digital business. Free to get started, and pay-as-you-go on all plans.

Was this answer helpful?