I am building a website using Prismic CMS and Nextjs 14. I followed this tutorial which resulted in a successful website with no errors. On my new project's website, I'm getting an error when trying to import my <NavBar /> component into my layout.js file. My goal with the nav is to conditionally render CSS classes for active and inactive nav links. I don't get this error every time, but when I do, the error is:
I Googled the error, and I found this article. I tried putting the <NavBar /> code directly into my layout.js file. The page loaded fine, but I'm still getting that same error from time to time. I think that it has something to do with useRouter() and usePathname() because the tutorial didn't use that, but I'm not sure. I also read the Nextjs docs regarding client and server components and had trouble understanding.
This is the code from my layout.js file:
'use client'
import { PrismicPreview, PrismicNextLink, PrismicNextImage } from '@prismicio/next';
import { repositoryName, createClient } from '@/prismicio';
import { usePathname, useRouter } from 'next/navigation';
import './globals.css';
// import NavBar from './components/NavBar';
// import Footer from './components/Footer';
export default function RootLayout({ children }) {
return (
<html lang='en'>
<body>
<NavBar />
{children}
<PrismicPreview repositoryName={repositoryName} />
{/* <Footer /> */}
</body>
</html>
);
}
async function NavBar() {
const pathname = usePathname();
const router = useRouter();
const client = createClient();
const nav = await client.getSingle('navigation_menu');
const inactive = 'hover:border-purpleDefault hover:border-b-2';
const active = 'border-lavender border-b-2';
return (
<div className='flex justify-center items-center font-semibold max-w-full mx-auto py-2'>
<div className='container flex justify-between'>
<span className='text-2xl leading-6 font-logo flex flex-row items-center'>
{nav.data.company_name}
<PrismicNextImage
field={nav.data.company_logo}
className='h-20 w-20 ml-4'
/>
</span>
<ul className='flex items-center text-2xl'>
{nav.data.menu_items.map((item) => {
return (
<li key={JSON.stringify(item)}>
<PrismicNextLink
field={item.link}
className={`no-underline ${(router.pathname = item.link ? active : inactive)}`}
>
{item.label}
</PrismicNextLink>
</li>
);
})}
</ul>
</div>
</div>
);
}
The <NavBar /> code used in the layout.js file is the exact same code that I used when the <NavBar /> was in the components folder.
This is my folder structure that's relevant to this post:
app
|
—— api
—— components
|
—— slice-simulator
globals.css
layout.js
page.js

The issue in here is that you're mixing
use clientwith a component that usesawaitinside.async/awaitcomponents are always Server components, which means that you can't mix hooks (which require client components) andasync/await(which require server components).Your best solution is to move your
NavBarcomponent to its own separate file with the'use client'directive to allow the use of hooks inside and have the data contained in thenavvariable to be passed by props.If you don't want to pollute your
layoutwith client fetches you can do something like this:NavBarContent.jsx:NavBar.jsx: