Back to Blog
Architecture / FrontendMarch 15, 2026
Managing Complex State in App Router
How we structure large-scale custom SaaS applications in Next.js, balancing server components and client state.
Server First, Client Second
In the App Router, the default should always be a server component. Data fetching, auth, and access control belong closest to their source.
The State Layer
When interaction demands client state, we reach for a thin, typed store and keep it scoped to the leaf view.
use-view-state.ts
const useViewState = create<ViewState>((set) => ({
filters: {},
setFilters: (filters) => set({ filters }),
}))Takeaways
Split state by ownership: URL for shared intent, server for data, client only for ephemeral UI.