Today
Yesterday
Previous 7 days
Older
Alex Rivera
alex@example.com
useState, useEffect, or browser APIs
- Are the default in Next.js 13+ App Router
Client Components run in the browser. They:
- Are marked with 'use client' at the top
- Can use React hooks and browser APIs
- Support interactivity (onClick, onChange, etc.)
- Are hydrated on the client side
The mental model: think of Server Components as the "shell" that renders once on the server, and Client Components as the interactive "islands" embedded within that shell.useState or useEffect
- Handling user events (clicks, input changes)
- Using browser-only APIs (localStorage, window)
- Integrating with third-party libraries that need the DOM
A practical pattern: keep as much of your component tree as Server Components, and only push down to Client Components at the leaf level where interactivity is actually needed.// ProductPage.tsx — Server Component (no 'use client')
import AddToCartButton from './AddToCartButton';
async function ProductPage({ id }: { id: string }) {
// Direct DB call — only possible in Server Component
const product = await db.products.findById(id);
return (
<div>
<h1>{product.name}</h1>
<p>{product.description}</p>
<p>${product.price}</p>
{/* Only this leaf needs to be a Client Component */}
<AddToCartButton productId={id} />
</div>
);
}
// AddToCartButton.tsx — Client Component
'use client';
import { useState } from 'react';
export function AddToCartButton({ productId }: { productId: string }) {
const [added, setAdded] = useState(false);
return (
<button onClick={() => setAdded(true)}>
{added ? 'Added to Cart ✓' : 'Add to Cart'}
</button>
);
}
ChatAI can make mistakes. Consider checking important information.