
In Next.js 15, server-side state management can be handled in a few different ways depending on your use case — especially with the App Router (introduced in Next 13) and React Server Components (RSC) becoming more central.
Here’s a breakdown of how to do server-side state management effectively in Next.js 15:
Server-Side State Management Approaches
1.Using React Server Components (RSC)
Next.js 15 supports Server Components by default in the app/ directory.
This avoids needing global state libraries entirely unless you’re doing complex client-side state interactions.
2.Storing State in Middleware or Cookies (Session-like)
If your “state” is user/session-based, use:
Middleware for request-level logic
Cookies (next/headers or next/response-cookies) for storing server-accessible state
This is great for:
Auth state
User preferences
Locale/language settings
3.API Routes + Database or Cache Layer
For persistent or sharable state, keep it in:
Postgres / MongoDB
Redis / Upstash
Edge config
Then access it via:
When You Do Need Client-Side State (and Bridge It)
You can combine server-side logic with a hydrated client component:
Tools to Help
next/headers, next/response-cookies: Manage request/response state
cache() from React or Next.js: For memoizing server-side data
Zustand or Redux (if you must use client-global state)
TL;DR: Server State in Next.js 15
Use Case
Approach
Data fetched on request
Server Components + fetch
Persisted state (auth, prefs)
Cookies / Middleware
Shared state across components
React Context (server or client)
Client interactivity
Hydrated client components
Heavy state mgmt
Zustand / Redux (client)
Bonus Round
URL query parameters as a form of state management in Next.js 15, in the App Router.
This is actually a super clean and powerful way to manage state — especially when you want the state to be shareable, bookmarkable, and synchronized with navigation (like filters, tabs, pagination, etc.).
In a Server Component
You can access query parameters using the searchParams prop (available in server components):
No client state needed — the URL is the state.
In a Client Component
Use useSearchParams() from next/navigation to read query params reactively:
When should you use this?
Use case
Use query params?
Filters on a page (search, tags)
✅ Yes
Pagination
✅ Yes
Tabs or views
✅ Yes
Auth or sensitive state
❌ No
Transient UI state (hover, drag)
❌ No
Bonus: Deep Linking
This method makes it easy to:
Share filtered views via URLs
Maintain state when the user refreshes
Let users hit “Back” and go to the previous state
Avoid relying on heavy client state management