This question is related to my two previous questions on the subject :
So, my objective is to have a Context API and different layouts based on auth state in a SEO friendly manner.
Now I have the following code :
My folder structure
/app
--Layouts
--Auth.jsx
--Main.jsx
--layout.jsx
--Context.jsx
--page.jsx
./layout.jsx
import AppWrapper from './Context.jsx';
export default function RootLayout({ children }) {
return (
<html lang="fr">
<body>
<AppWrapper>
{children}
</AppWrapper>
</body>
</html>
)
}
./Context.jsx
"use client";
import { createContext, useContext, useState} from 'react';
import Main from "./Layouts/Main.jsx";
import Auth from "./Layouts/Auth.jsx";
const Context = createContext();
export default function AppWrapper({children}) {
const [isAuth, setAuth] = useState(false)
return (
<Context.Provider value={{
isAuth: isAuth,
setAuth: setAuth
}}>
{ !isAuth ?
<Main>{children}</Main>
:
<Auth>{children}</Auth>
}
</Context.Provider>
)
}
export function useAppContext() {
return useContext(Context);
}
./Layouts/Main.jsx (Same for Layouts/Auth.jsx)
export default function Main({ children }) {
console.log('children of main');
return (
<>
<p>Im main</p>
{children}
</>
)
}
./page.jsx
'use client'
import { useAppContext } from './Context';
import Context from "./Context";
export default function Home() {
const context = useAppContext(Context);
return (
<>
<p>Im self</p>
<button onClick={() => context.setAuth(current => !current)}>Toggle</button>
</>
)
}
As you can see :
- root layout is a server component
./Context.jsx
is a client component./Layouts
are server components./page.jsx
is a client component
But the console.log
in ./Layouts/Main.jsx
is displayed on the browser console.
So :
- Is it a client component ?
- Does this makes the whole app client side rendered ?
- How to optimize all of that ?
- What am I missing ?
2
Answers
Yes
Yes
Keep the auth state on server using cookies, display and revalidate layouts on server for each user.
Need to forget SPA architecture, Context API is nice but outdated when it comes to conditionally render meta-components/layouts. Its place is at root only passing children and used only on leaf components.
Server is probably not getting the initial context values which is why server is not rendering html from Main layout. You need to remove default from context export and check if you see the main layout html in page source.
export
defaultfunction AppWrapper