1

In the classic Pages Router of Next, You can add a global provider in your _app.js file and wrap it around the entire component tree. This will ensure that the provider is available to all components.

If you do this using the App Router, you get an error message

You're importing a component that needs useState. It only works in a Client Component but none of its parents are marked with "use client", so they're Server Components by default.

Is there a way to achieve something similar without giving up the Server Components?

Youssouf Oumar
  • 29,373
  • 11
  • 46
  • 65
Farouk M
  • 1,185
  • 7
  • 17
  • Hi Farouk! Please go through the answer of the linked thread. You will get an answer, while the questions are slightly different. – Youssouf Oumar May 06 '23 at 09:59

2 Answers2

2

Wrap the provider in a client component.

'use client';
 
import { SomeProvider } from 'some-library';
 
export function Providers({ children }) {
  return (
    <SomeProvider>
      {children}
    </SomeProvider>
  );
}

And use this wrapped provider in root layout.

import { Providers } from './providers';
 
export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        <Providers>{children}</Providers>
      </body>
    </html>
  );
}
JsPark
  • 73
  • 6
  • useContext will make the entire compoennt client side as well. i'm looking for something that can be used for server compoennts as well. – Shreyas Jadhav Jul 08 '23 at 07:54
  • 1
    Worth noting that this is the [recommended approach](https://nextjs.org/docs/getting-started/react-essentials#rendering-third-party-context-providers-in-server-components) in the docs – Austen Jul 26 '23 at 23:42
-2

// use context in _app.js

// user.js

import { createContext, useState, useContext } from "react";

const Context = createContext();

const Provider = ({ children }) => {
  const [user, setUser] = useState(true);

  const exposed = {
    user,
  };

  return <Context.Provider value={exposed}>{children}</Context.Provider>;
};

export const useUser = () => useContext(Context);

export default Provider;

// _app.js

import UserProvider from "../context/user";

function MyApp({ Component, pageProps }) {
    return (
        <UserProvider>
            <Component {...pageProps} />
        </UserProvider>
    );
}
export default MyApp;

// use user state in any component like this

import { useUser } from "../context/user";

export default function Home({ lessons }) {
  const { user } = useUser();
  console.log({ user });
  return (
    <div>
      
    </div>
  );
}