Search code examples
reactjsnext.jsjsxreact-context

Next.js 13, Context API, conditional layouts and SEO optimization


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 ?

Solution

    • Is it a client component ?

    Yes

    • Does this makes the whole app client side rendered ?

    Yes

    • How to optimize all of that ?

    Keep the auth state on server using cookies, display and revalidate layouts on server for each user.

    • What am I missing ?

    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.