Hi sorry for the terrible use of the word use in the title. I am getting the following error when deploying my project via Vercel (running fine locally).
Error:
useSearchParams() should be wrapped in a suspense boundary at page "/rooms/cinema/movie". Read more: https://nextjs.org/docs/messages/missing-suspense-with-csr-bailout
But I don't think adding the Suspense tag worked as I call the useSearchParams hook inside the useEffect hook.... where do I need to add the Suspense tag?
Code:
// ./movie/page.jsx
'use client'
import React, { useEffect, useState, Suspense } from 'react';
import { useSearchParams } from 'next/navigation';
import moviesData from "/public/JSON/movies.json";
import Link from 'next/link';
import Stars from './Stars';
export default function Movie() {
const searchParams = useSearchParams();
const [movieName, setMovieName] = useState("Unknown");
const [movieData, setMovieData] = useState({});
const [movieTags, setMovieTags] = useState([]);
useEffect(() => {
const title = searchParams.get('title');
if (title) {
setMovieName(title);
}
}, [searchParams]);
useEffect(() => {
if (movieName && moviesData[movieName]) {
setMovieData(moviesData[movieName]);
setMovieTags(moviesData[movieName].tags);
} else {
setMovieData({}); // Reset if movieName is invalid
setMovieTags([]);
}
}, [movieName]);
return (
<Suspense>
<body className='cinema'>
<Link className="link" href="/"> < Home </Link>
<Link className="link" href="/rooms/cinema/"> < Cinema </Link>
<div className='moviePage'>
<div className='moviePageImg'>
<img className="moviePoster" src={movieData.image}></img>
</div>
<div className='moviePageData'>
<h1>{movieName}</h1>
<h2>{movieData.director}</h2>
<div> <Stars rating={movieData.stars}/> </div> <br/>
<div id='synopsis'> {movieData.synopsis} </div> <br/>
<div id='review'> {movieData.review} </div> <br/>
<ul id='tags'>
{/* {movieData.tags} */}
{movieTags.map((tag)=> <li className='tag' key={tag}>{tag}</li>)}
</ul>
</div>
</div>
<div className="fuzzy-overlay"></div>
</body>
</Suspense>
);
}
Repository if interested: https://github.com/SengulC/unboxd
For your example, the Suspense
boundary must exist above the component that is throwing a promise; i.e. if you're looking to maintain the structure of your page, create a layout under the movie
directory to neighbor closest to your page:
// ./movie/layout.tsx
type LayoutProps = {
children: React.ReactNode
}
export default async function Layout({ children }: LayoutProps) {
return (
<Suspense fallback={...}>
{ children }
</Suspense>
)
}