0
0
NextJSframework~5 mins

Shared state across layouts in NextJS

Choose your learning style9 modes available
Introduction

Shared state across layouts lets different pages or sections of your app use the same data or settings. This helps keep things consistent and saves you from repeating code.

You want a user login status to be available on all pages.
You need a theme (dark or light mode) to stay the same across different layouts.
You want to keep a shopping cart updated no matter which page the user visits.
You want to share language or localization settings across the whole app.
Syntax
NextJS
'use client';
import { createContext, useContext, useState } from 'react';

const SharedStateContext = createContext();

export function SharedStateProvider({ children }) {
  const [state, setState] = useState(false);

  return (
    <SharedStateContext.Provider value={{ state, setState }}>
      {children}
    </SharedStateContext.Provider>
  );
}

export function useSharedState() {
  return useContext(SharedStateContext);
}

This pattern uses React Context to share state.

Wrap your layouts or pages with SharedStateProvider to give them access.

Examples
Wrap your root layout with the provider to share state across all pages and layouts inside.
NextJS
import { SharedStateProvider } from './SharedStateContext';

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>
        <SharedStateProvider>
          {children}
        </SharedStateProvider>
      </body>
    </html>
  );
}
Use the shared state inside any component or layout by calling the custom hook.
NextJS
'use client';
import { useSharedState } from './SharedStateContext';

export default function Header() {
  const { state, setState } = useSharedState();

  return (
    <header>
      <button onClick={() => setState(!state)}>
        Toggle: {state ? 'On' : 'Off'}
      </button>
    </header>
  );
}
Sample Program

This example shows how to share a dark mode setting across layouts and pages. The SharedStateProvider wraps the app. The Header toggles the mode. The Page shows the current mode and changes style accordingly.

NextJS
'use client';
import { createContext, useContext, useState } from 'react';

const SharedStateContext = createContext();

export function SharedStateProvider({ children }) {
  const [darkMode, setDarkMode] = useState(false);

  return (
    <SharedStateContext.Provider value={{ darkMode, setDarkMode }}>
      {children}
    </SharedStateContext.Provider>
  );
}

export function useSharedState() {
  return useContext(SharedStateContext);
}

// RootLayout.js
export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>
        <SharedStateProvider>
          {children}
        </SharedStateProvider>
      </body>
    </html>
  );
}

// Header.js
'use client';
import { useSharedState } from './SharedStateContext';

export default function Header() {
  const { darkMode, setDarkMode } = useSharedState();

  return (
    <header style={{ padding: '1rem', backgroundColor: darkMode ? '#222' : '#eee', color: darkMode ? '#eee' : '#222' }}>
      <button onClick={() => setDarkMode(!darkMode)} aria-label="Toggle dark mode">
        {darkMode ? 'Switch to Light Mode' : 'Switch to Dark Mode'}
      </button>
    </header>
  );
}

// Page.js
'use client';
import Header from './Header';
import { useSharedState } from './SharedStateContext';

export default function Page() {
  const { darkMode } = useSharedState();

  return (
    <main style={{ padding: '1rem', backgroundColor: darkMode ? '#333' : '#fff', color: darkMode ? '#ddd' : '#000' }}>
      <Header />
      <p>The current mode is {darkMode ? 'Dark' : 'Light'}.</p>
    </main>
  );
}
OutputSuccess
Important Notes

Always wrap your app or layouts with the provider to share state properly.

Use React Context carefully; too much shared state can slow your app.

For bigger apps, consider state management libraries or server state solutions.

Summary

Shared state lets multiple layouts and pages use the same data easily.

React Context with a provider and custom hook is a simple way to share state in Next.js.

Wrap your root layout with the provider and use the custom hook inside components.