Interleaving server and client means mixing server-side and client-side code in one component. This helps you load data on the server and add interactive parts on the client smoothly.
Interleaving server and client in NextJS
import React from 'react'; import ClientComponent from './ClientComponent'; // Server Component export default async function Page() { const data = await fetch('https://api.example.com/data').then(res => res.json()); return ( <main> <h1>Server Data</h1> <ClientComponent items={data.items} /> </main> ); } // Client Component 'use client'; import { useState } from 'react'; export default function ClientComponent({ items }) { const [count, setCount] = useState(0); return ( <section> <p>Items count: {items.length}</p> <button onClick={() => setCount(count + 1)}>Clicked {count} times</button> </section> ); }
Server Components run only on the server and can fetch data directly.
Client Components run in the browser and can use React hooks like useState.
'use client'; import { useState } from 'react'; export default function ClientOnly() { const [text, setText] = useState(''); return <input value={text} onChange={e => setText(e.target.value)} />; }
export default async function ServerOnly() { const data = await fetch('https://api.example.com/data').then(r => r.json()); return <div>Data count: {data.length}</div>; }
import ClientComponent from './ClientComponent'; export default async function Page() { const data = await fetch('https://api.example.com/data').then(r => r.json()); return <ClientComponent items={data.items} />; }
This example shows a server component fetching a list of fruits and passing it to a client component. The client component displays the count and has a button that updates a click counter interactively.
This way, data loads fast from the server, and the button works smoothly on the client.
import React from 'react'; import ClientComponent from './ClientComponent'; // Server Component export default async function Page() { // Simulate fetching data on server const data = { items: ['apple', 'banana', 'cherry'] }; return ( <main> <h1>Fruits List</h1> <ClientComponent items={data.items} /> </main> ); } // Client Component 'use client'; import { useState } from 'react'; export default function ClientComponent({ items }) { const [count, setCount] = useState(0); return ( <section> <p>We have {items.length} fruits.</p> <button onClick={() => setCount(count + 1)} aria-label="Click counter"> Clicked {count} times </button> </section> ); }
Always mark client components with 'use client'; at the top.
Server components can fetch data directly without extra hooks.
Client components can use React hooks like useState for interactivity.
Interleaving lets you mix server data fetching with client interactivity.
Use server components for loading data and client components for user actions.
This approach improves performance and user experience in Next.js apps.