Closed temtechie closed 11 months ago
You can split the provider inside a client component named Providers
than will load all your client providers without render the layout as client by default.
But if I'm not saying wrong, the NextIntlClientProvider already have the use client
directive so you don't need to pass anything in your layout.
And your root layout must be server side and never use react states or what ever inside, only state manager as redux/zustand/jotai or react context itself that are component that will use use client
directive inside but not directly from the layout.
@HakkaOfDev which provider exactly,
here is my code from my layout.tsx can you send use this code to create the Provider?
`"use client";
import Header from "../component/Header";
import Sidebar from "../component/Sidebar";
import Loader from "../component/common/Loader";
import "./globals.css";
import { useState, useEffect, ReactNode } from "react";
import { NextIntlClientProvider } from 'next-intl';
import { notFound } from 'next/navigation';
type Props = {
children: ReactNode;
params: { locale: string };
};
export default async function RootLayout({
children, params: { locale }
}: Props) {
let messages;
try {
messages = ( await import(`../../messages/${locale}.json`)).default;
} catch (error) {
notFound();
}
const [sidebarOpen, setSidebarOpen] = useState(false);
const [loading, setLoading] = useState<boolean>(true);
useEffect(() => {
setTimeout(() => setLoading(false), 500);
}, []);
return (
<html lang={locale}>
<body suppressHydrationWarning={true}>
<NextIntlClientProvider locale={locale} messages={messages}>
<div className="">
{loading ? (
<Loader />
) : (
<div className="flex h-screen overflow-hidden">
<Sidebar
sidebarOpen={sidebarOpen}
setSidebarOpen={setSidebarOpen}
/>
<div className="relative flex flex-1 flex-col overflow-y-auto overflow-x-hidden">
<Header
sidebarOpen={sidebarOpen}
setSidebarOpen={setSidebarOpen}
/>
<main>
<div className="mx-auto w-full px-4 py-4 md:px-6 2xl:px-11">
{children}
</div>
</main>
</div>
</div>
)}
</div>
</NextIntlClientProvider>
</body>
</html>
);
}
`
show me exactly what to do here
For example here, you need to use a StateManager lib or a context on top level of your application that will store states for you because you can't use a layout as client. And you should move for example the the sidebarOpened state directly inside the Sidebar component.
I would use a simple wrapper component that include the loading thing in "use client" + the children so:
"use client";
import * from "react";
function LoadingWrapper({ children }) {
const [loading, setLoading] = React.useState(true);
React.useEffect(() => {
setTimeout(() => setLoading(false), 500);
}, []);
if(loading) return <Loader />;
return children;
}
so your Layout can become:
import Header from "../component/Header";
import Sidebar from "../component/Sidebar";
import Loader from "../component/common/Loader";
import "./globals.css";
import { ReactNode } from "react";
import { NextIntlClientProvider } from 'next-intl';
import { notFound } from 'next/navigation';
type Props = {
children: ReactNode;
params: { locale: string };
};
export default async function RootLayout({
children, params: { locale }
}: Props) {
let messages;
try {
messages = ( await import(`../../messages/${locale}.json`)).default;
} catch (error) {
notFound();
}
return (
<html lang={locale}>
<body suppressHydrationWarning={true}>
<NextIntlClientProvider locale={locale} messages={messages}>
<LoadingWrapper>
<div className="flex h-screen overflow-hidden">
<Sidebar /> {/* states inside the component */}
<div className="relative flex flex-1 flex-col overflow-y-auto overflow-x-hidden">
<Header />
<main>
<div className="mx-auto w-full px-4 py-4 md:px-6 2xl:px-11">
{children}
</div>
</main>
</div>
</div>
</LoadingWrapper>
</NextIntlClientProvider>
</body>
</html>
);
}
If you need to access to the sidebar state, you need probably to use a react context or a State Manager on top level of your application. I recommend zustand, it's simple.
very helpful thanks man. i will send a dm on your email
very helpful thanks man. i will send a dm on your email
You can add me via discord: hakkaofdev Have a good night!
yeah. I will use redux. I am more familiar with redux
is working now thanks man. i used your advice and did some twerking
Seems like this was resolved, will close the issue then.
Is your feature request related to a problem? Please describe.
Error: async/await is not yet supported in Client Components, only Server Components. This error is often caused by accidentally adding
'use client'
to a module that was originally written for the server. I get this error from nextjs because async/await is not yet supported in client component using the app Route.now i want to use the 'use client' flag in my Root Layout to enable me use useState and other react hook.
Describe the solution you'd like
to remove the async/await . I have made my root layout a client component, and i can not use async/await in client component
Describe alternatives you've considered
to remove the async/await and have alternative to fetch
let messages; try { messages = (await import(
../../messages/${locale}.json
)).default; } catch (error) { notFound(); }I have tried using .then it didnot work