HOME
PROJECTS
Featured projectsProject archive
BLOG
All posts

Categories

AI EngineeringSoftware ArchitectureTechnical SEOWeb & Marketing
TOOLS
QR Code Maker
VIEN

Got an idea worth building?

I build websites, web apps and AI solutions. Free consultation, reply within 24 hours.

Get in touchBook a call

Nguyễn Sinh Nhật

Software Engineer

Software Engineer — Fullstack Developer and AI Engineer focused on scalable web apps and practical AI solutions.

Explore

  • Home
  • Projects
  • Blog
  • Tools

Tools

  • QR Code Maker
  • RSS feed

Contact

  • nhatnguyendev251@gmail.com
  • 0328 398 467
  • Ngu Hanh Son Ward, Da Nang City, Viet Nam

© 2026 Nguyễn Sinh Nhật. Built with Next.js & Sanity.

Available for new projects
Loading blog post
Back to all posts
Next.js illustration explaining proper use client usage with Server Components and Client Components.

Software Architecture

One misplaced use client can make Next.js heavier

Understand Server and Client Component boundaries in Next.js to reduce browser JavaScript without losing interactivity.

By Nguyễn Sinh Nhật•Published Aug 02, 2026•7 min read

Table of contents

  • The familiar mistake: making the whole page a Client Component
  • A better pattern: create a small interactive island
  • When do you actually need use client?
  • Do not turn it into a rigid rule
  • Conclusion
This article is also available in Vietnamese
One misplaced "use client" directive can turn Next.js's biggest advantage into a heavier React SPA.

That does not make "use client" bad. The issue is treating it as a quick fix whenever a component needs state, an event handler, or a browser API. Put it in page.tsx, layout.tsx, or an overly broad parent component, and the client boundary grows further than necessary.

In the App Router, components are Server Components by default. They can fetch data on the server and use server-only dependencies without sending that code to the browser. When a file has "use client", that file and the dependencies it imports become part of the client-side graph.

The familiar mistake: making the whole page a Client Component

Imagine a product page with a title, product data, long-form content, and search filters. Because the filter needs useState, the easiest move appears to be making the entire page a Client Component.

products-page.tsxtsx
"use client";

export default function ProductsPage() {
  const [query, setQuery] = useState("");

  return (
    <>
      <SearchFilters query={query} onQueryChange={setQuery} />
      <ProductGrid query={query} />
    </>
  );
}

It works, but the page is now a client boundary. Layout, content, formatters, and the product grid can be pulled toward the browser more than the experience actually requires.

A better pattern: create a small interactive island

Keep the page and data on the server. Extract only the part that truly needs the browser into a Client Component. The filter stays interactive in the browser, while the product grid, data, and remaining content can render on the server.

products-page.tsxtsx
export default async function ProductsPage({ searchParams }) {
  const products = await getProducts(searchParams.query);

  return (
    <>
      <SearchFilters />
      <ProductGrid products={products} />
    </>
  );
}
search-filters.tsxtsx
"use client";

export function SearchFilters() {
  // state, event handlers and URL interaction live here
}
server-client-boundary.mmd

When do you actually need use client?

  • You need useState, useEffect, onClick, onChange, or browser APIs such as window and localStorage.
  • You need database access, secrets, file reads, static content, or heavy dependencies: keep it in a Server Component.
  • A small form, modal, dropdown, or date picker: use a small Client Component instead of turning the whole page into one.
Use client does not mark an interactive component. It marks the boundary where the browser must participate.

Do not turn it into a rigid rule

Real-time dashboards, rich-text editors, drag-and-drop boards, and internal tools with complex client state will need more Client Components. The goal is not to push everything to the server. The goal is to keep browser JavaScript where it creates value.

Conclusion

Next.js is not powerful because everything becomes fast automatically. It is powerful when a team knows what belongs on the server, what belongs in the browser, and does not let one interactive button pull an entire page into the client graph. Before adding use client, ask: does this code truly need to run in the browser, or is it simply near code that does?

Frequently asked questions

No. It defines a boundary at the marked file and its imported dependencies. However, placing that boundary too high in the tree can move more code into the browser than necessary.

No. Server Components do not handle state, event handlers, or browser APIs. Client Components remain the right place for genuine interactivity.

Related posts

Keep exploring articles in this category.

A developer writing NestJS code with a clean interface and minimalist desk.
Software ArchitectureSep 28, 20266 min read

Domain models, aggregates and repositories in NestJS explained

Designing domain models, scoping aggregate boundaries and implementing repository interfaces in NestJS through a product module. Avoid stuffing logic into services.

Read article
A developer working on a Next.js application with a split screen of server and client components plus performance metrics.
Software ArchitectureSep 25, 20265 min read

How to Choose Server vs Client Components in Next.js: Practical Examples

A practical guide to choosing Server vs Client Components in Next.js, common hydration mismatch mistakes, and how to measure bundle size before and after.

Read article