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.
Practice
Solution
Step 1: Understand server and client roles
Server components fetch data and render HTML, while client components handle user interactions.Step 2: Identify the benefit of mixing them
Combining them improves performance by reducing client work and speeding up data loading.Final Answer:
It improves performance by loading data on the server and handling interactions on the client. -> Option BQuick Check:
Interleaving = Better performance [OK]
- Thinking all code runs only on client
- Believing interleaving disables server rendering
- Assuming no performance benefit
Solution
Step 1: Recall client component syntax
Next.js requires'use client'directive at the top of the file to mark it as client.Step 2: Check other options
Wrapping tags, special exports, or props flags are not valid Next.js patterns.Final Answer:
Add the directive 'use client' at the top of the file. -> Option DQuick Check:
Client component directive = 'use client' [OK]
- Trying to wrap components with special tags
- Using props to mark client components
- Confusing export syntax for client marking
export default function ServerComponent() {
const data = fetch('https://api.example.com/data').then(res => res.json());
return (
<div>
<ClientComponent />
<p>Data loaded</p>
</div>
);
}
function ClientComponent() {
const [count, setCount] = React.useState(0);
return <button onClick={() => setCount(count + 1)>Clicked {count} times</button>;
}Solution
Step 1: Check ClientComponent usage
ClientComponent uses useState, so it must be marked with 'use client' directive to work as client component.Step 2: Analyze missing 'use client' directive
Without 'use client', ClientComponent is treated as server component, but hooks are invalid there, causing it not to render properly.Final Answer:
Only the paragraph 'Data loaded' because ClientComponent is not marked as client. -> Option AQuick Check:
Missing 'use client' = ClientComponent won't render [OK]
- Assuming ClientComponent renders without 'use client'
- Thinking fetch usage causes error here
- Believing nested client components always render
'use client';
export default function ClientComponent() {
const data = fetch('https://api.example.com/data').then(res => res.json());
return <div>Data count: {data.length}</div>;
}Solution
Step 1: Understand fetch in client components
fetch returns a Promise; using it directly without awaiting causes data to be a Promise, not the actual data.Step 2: Identify the error in rendering
Trying to access data.length on a Promise causes runtime error because Promise has no length property.Final Answer:
Using fetch directly in a client component without async/await causes a Promise error. -> Option CQuick Check:
Fetch returns Promise; must await in client [OK]
- Thinking 'use server' is needed in client components
- Believing JSX can't be returned in client components
- Assuming fetch URL syntax is wrong
Solution
Step 1: Separate data fetching and interactivity
Fetching products is best done on the server for performance and SEO benefits.Step 2: Use client components for user actions
Add-to-cart buttons require client interactivity, so they should be client components nested inside the server component.Final Answer:
Fetch products in a server component and render a client component for the add-to-cart buttons inside it. -> Option AQuick Check:
Server fetch + client interactivity = Fetch products in a server component and render a client component for the add-to-cart buttons inside it. [OK]
- Fetching data on client causing slower load
- Trying to handle interactivity in server components
- Rendering server components inside client components incorrectly
Ready to prove it?
Pass the test and this pattern moves unknown
