In the Next.js App Router, components render differently depending on whether they're Server Components (default) or Client Components (marked with "use client"):
By default, all components in the App Router are Server Components. 1 These components:
When you add the "use client"
directive at the top of a file, you're declaring that component and all its imports as Client Components. 2 These components:
useState
, event handlers, and browser APIsRemember that you don't need to add "use client" to every component that needs client-side functionality. Once you define the boundary with "use client", all child components imported into it become part of the client bundle.
Both Server Components and Client Components can be statically rendered in Next.js App Router, but they work differently:
Server Components are statically rendered by default at build time. 1 This means:
Client Components marked with "use client" can also be part of statically rendered routes: 1
A route becomes dynamically rendered (not static) when: 1
cookies()
, headers()
, or searchParams
fetch(..., { cache: 'no-store' })
dynamic = 'force-dynamic'
or revalidate = 0
route segment config optionsIf none of these dynamic features are used, Next.js will statically render both Server and Client Components by default, optimizing performance while preserving interactivity where needed.
The key difference is that Server Components don't send component JavaScript to the client when statically rendered, while Client Components still send their JavaScript for hydration, even when pre-rendered as static HTML.