How to Use the Context API in Next.js (App Router, React 19)
- Published
- Updated
- Reading time
- 5 min read

On this page 11 sections
- How do I set up Context in the Next.js App Router?
- Context vs other state options in Next.js
- Full guide
- Simplifying State Management in Next.js Applications
- Why Use the Context API in Next.js?
- Setting Up Context API in Next.js
- Using Context API with Server Components
- Advanced Tips and Best Practices
- Key Benefits of Context API in Next.js
- Conclusion
- Frequently asked questions
Updated 12 October 2026 · By Abhilash Sahoo, Infyways
To use the Context API in Next.js (App Router), create the context and its provider in a Client Component marked 'use client', wrap your app (or part of it) with the provider in layout.tsx, and read it with useContext (or React 19's use) in Client Components. Server Components cannot read React context; pass server data to the provider as props instead.
How do I set up Context in the Next.js App Router?
// app/providers/theme-provider.tsx
'use client';
import { createContext, useContext, useState } from 'react';
type Theme = 'light' | 'dark';
const ThemeContext = createContext<{ theme: Theme; toggle: () => void } | null>(null);
export function ThemeProvider({ children }: { children: React.ReactNode }) {
const [theme, setTheme] = useState<Theme>('light');
return (
<ThemeContext value={{ theme, toggle: () => setTheme(t => (t === 'light' ? 'dark' : 'light')) }}>
{children}
</ThemeContext>
);
}
export function useTheme() {
const ctx = useContext(ThemeContext);
if (!ctx) throw new Error('useTheme must be used inside ThemeProvider');
return ctx;
}
// app/layout.tsx (Server Component)
import { ThemeProvider } from './providers/theme-provider';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body><ThemeProvider>{children}</ThemeProvider></body>
</html>
);
}
React 19 (used by current Next.js) lets you render <ThemeContext> directly as the provider; <ThemeContext.Provider> still works. Server Components can be passed as children through a Client provider without becoming client code.
Context vs other state options in Next.js
| Need | Use |
|---|---|
| Theme, locale, auth user, UI state shared by many components | React Context |
| Frequently changing global state with many subscribers | Zustand, Jotai or Redux Toolkit (avoid re-rendering every consumer) |
| Server data (fetching, caching, revalidation) | Fetch in Server Components, or TanStack Query / SWR on the client |
| State that should be in the URL (filters, tabs) | Search params |
Full guide
Simplifying State Management in Next.js Applications
Highlights:
- Learn how to use Context API in Next.js
- Simplify state management with
useContextandcreateContext - Explore practical examples using server and client components
State management is crucial when developing scalable applications. In Next.js, using the Context API for managing state simplifies data sharing across components. This guide explains how to set up and use the Context API in your Next.js application effectively.
Why Use the Context API in Next.js?

Next.js offers powerful tools for both server and client-side development. However, managing state across deeply nested components can be challenging. With Next.js Context, you can:
- Avoid "prop drilling" by passing data directly to components.
- Share global state using
createContextanduseContexthooks. - Simplify state management in both server components and client components.
For example, instead of passing a user object down multiple layers of components, you can use a Next.js Provider to make it accessible across the entire app.
Setting Up Context API in Next.js
Step 1: Create a Context
Start by creating a context using React’s createContext function. In your Next.js application, define it as a separate module:
import { createContext, useContext, useState } from 'react';
export const UserContext = createContext(null);
export function UserProvider({ children }) {
const [user, setUser] = useState(null);
return (
<UserContext.Provider value={{ user, setUser }}>
{children}
</UserContext.Provider>
);
}
In this code:
createContext: Creates a context object.UserProvider: Wraps components and provides access to theuserstate.
Step 2: Use Context in Components
To access context values, use the useContext hook. Here’s an example of consuming the UserContext:
import { useContext } from 'react';
import { UserContext } from '../context/UserContext';
export default function UserProfile() {
const { user, setUser } = useContext(UserContext);
if (!user) {
throw new Error("No user data available");
}
return (
<div>
<h1>Welcome, {user.name}!</h1>
<button onClick={() => setUser(null)}>Logout</button>
</div>
);
}
Step 3: Wrap Your Application
Wrap your app with the UserProvider in pages/_app.js:
import { UserProvider } from '../context/UserContext';
export default function App({ Component, pageProps }) {
return (
);
}
his makes the user state available throughout the app.
Using Context API with Server Components
Server Components cannot use useContext, and React context is not available on the server. Fetch the data in a Server Component (such as layout.tsx) and pass it to the Client provider as a prop:
// app/layout.tsx
const user = await getUser();
return <UserProvider initialUser={user}>{children}</UserProvider>;
Advanced Tips and Best Practices
Error Handling in Context
When consuming context values, always handle cases where the context might not be available:
const context = useContext(UserContext);
if (!context) {
throw new Error("UserContext must be used within a UserProvider");
}
Using Context with useState
Leverage useState from React to manage local state within your context:
export const ThemeContext = createContext();
export function ThemeProvider({ children }) {
const [theme, setTheme] = useState('light');
return (
<ThemeContext.Provider value={{ theme, setTheme }}>
{children}
</ThemeContext.Provider>
);
}
Combining Context with Other Hooks
Combine useContext with useEffect to fetch and update data dynamically:
import { useEffect, useContext } from 'react';
import { UserContext } from '../context/UserContext';
export default function FetchUser() {
const { setUser } = useContext(UserContext);
useEffect(() => {
async function fetchData() {
const data = await fetch('/api/user').then((res) => res.json());
setUser(data);
}
fetchData();
}, [setUser]);
return <div>Loading user data...</div>;
}
Key Benefits of Context API in Next.js
- Effortless State Sharing: No need for complex state management libraries.
- Server and Client Compatibility: Works seamlessly with server-side rendering (SSR) and client components.
- Improved Code Readability: Cleaner structure without excessive props.
Conclusion
Using the Context API in Next.js is a powerful way to manage global state. By combining createContext, useContext, and Next.js Provider, you can streamline state management for server and client components alike.
Whether you're building SEO-friendly applications with server-side rendering or dynamic client-side apps, the Context API offers a lightweight yet robust solution.
Explore more on Next.js state management in the official Next.js documentation and start simplifying your development workflow today!
Looking for a Next.js Developer? Hire now!
Frequently asked questions
Filed under Web Development


