๐Ÿš€ 01. SSR๊ณผ HTML: Next.js๊ฐ€ HTML์„ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•

2026๋…„ 3์›” 5์ผ ์ˆ˜์ •๋จ

๐Ÿ“‹ ๊ฐœ์š”

CSR vs SSR vs SSG vs ISR โ€” ๊ฐ ๋ Œ๋”๋ง ์ „๋žต์ด ์ƒ์„ฑํ•˜๋Š” HTML์˜ ์ฐจ์ด, Hydration์ด๋ž€ ๋ฌด์—‡์ธ๊ฐ€, Next.js App Router์˜ ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋ฅผ HTML ๊ด€์ ์—์„œ ํŒŒํ—ค์นฉ๋‹ˆ๋‹ค.

๐Ÿ“Œ ์ด ๋ฌธ์„œ๋ฅผ ์ฝ๊ธฐ ์ „์—

โฑ๏ธ ์˜ˆ์ƒ ์ฝ๊ธฐ ์‹œ๊ฐ„: 20๋ถ„ / ํ•ต์‹ฌ ํŒŒํŠธ๋งŒ: 12๋ถ„

๐ŸŽฏ ์ด ๋ฌธ์„œ์˜ ์œ„์น˜

์ด ๋ฌธ์„œ๋Š” HTML ์‹ฌํ™” ์„น์…˜์ž…๋‹ˆ๋‹ค. HTML guide 01๋ฒˆ(HTML ๋ฉ˜ํƒˆ ๋ชจ๋ธ)๊ณผ Next.js ๋ Œ๋”๋ง ์ „๋žต์— ๋Œ€ํ•œ ๊ธฐ๋ณธ ์ดํ•ด๊ฐ€ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ—บ๏ธ ์ด ๋ฌธ์„œ์˜ ํ๋ฆ„

[CSR์˜ ํ•œ๊ณ„] โ†’ [SSR์ด ๋‹ค๋ฅธ ์ด์œ ] โ†’ [Next.js๊ฐ€ HTML์„ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•] โ†’ [Hydration] โ†’ [์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์™€ HTML]

๐ŸŽฏ ์ด ๋ฌธ์„œ๋ฅผ ๋‹ค ์ฝ์œผ๋ฉด ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ

  • CSR๊ณผ SSR์—์„œ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๋ฐ›๋Š” ์ดˆ๊ธฐ HTML์˜ ์ฐจ์ด๋ฅผ ์„ค๋ช…ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • Hydration์ด ๋ฌด์—‡์ด๋ฉฐ ์™œ ํ•„์š”ํ•œ์ง€ ์›๋ฆฌ๋กœ ์„ค๋ช…ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • Next.js App Router์˜ ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๊ฐ€ HTML ์ƒ์„ฑ์— ์–ด๋–ป๊ฒŒ ๊ธฐ์—ฌํ•˜๋Š”์ง€ ์„ค๋ช…ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • Hydration Mismatch ์—๋Ÿฌ๊ฐ€ ์™œ ๋ฐœ์ƒํ•˜๋Š”์ง€ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

๐Ÿ—บ๏ธ ์ด ๋ฌธ์„œ์˜ ๋ฐฐ๊ฒฝ ์„ธ๊ณ„๊ด€: '์˜์ˆ˜๋„ค ์ปค๋ฎค๋‹ˆํ‹ฐ'

  • ๐Ÿฃ ์˜์ฒ  ( ์‹ ์ž… ): "์˜ํ˜ธ ๋‹˜, Next.js ์“ฐ๋ฉด SEO๊ฐ€ ์ข‹๋‹ค๊ณ  ํ–ˆ๋Š”๋ฐ, ๊ทธ๊ฒŒ HTML์ด๋ž‘ ์–ด๋–ค ๊ด€๊ณ„์˜ˆ์š”? React๋Š” JavaScript๋กœ HTML์„ ๋งŒ๋“œ๋Š” ๊ฑฐ์ž–์•„์š”. ๊ทธ๋Ÿผ ๊ตฌ๊ธ€ ๋ด‡์ด ํŽ˜์ด์ง€ ๊ธ์„ ๋•Œ ๋ญ˜ ๋ณด๋Š” ๊ฑด๊ฐ€์š”?"
  • ๐Ÿฆ ์˜ํ˜ธ ( ๋ฆฌ๋“œ ): "์ •ํ™•ํžˆ ๊ฑฐ๊ธฐ์„œ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ด์•ผ ํ•ด์š”. ๊ตฌ๊ธ€ ๋ด‡์ด ์˜์ˆ˜๋„ค ์ปค๋ฎค๋‹ˆํ‹ฐ์— ์ ‘์†ํ•˜๋ฉด, ์ฒซ ๋ฒˆ์งธ๋กœ ๋ฐ›๋Š” HTML ํŒŒ์ผ์ด ๋ญ๋ƒ๊ฐ€ SEO์˜ ํ•ต์‹ฌ์ด๊ฑฐ๋“ ์š”. CSR์€ ๋นˆ ๊ป๋ฐ๊ธฐ HTML์„ ์ฃผ๊ณ , SSR์€ ์ฝ˜ํ…์ธ ๊ฐ€ ์ฑ„์›Œ์ง„ HTML์„ ์ค˜์š”. ๊ทธ ์ฐจ์ด๊ฐ€ Google ๊ฒ€์ƒ‰ ์ˆœ์œ„์— ์ง๊ฒฐ๋ผ์š”."

๐Ÿค” ์™œ ์•Œ์•„์•ผ ํ•˜๋Š”๊ฐ€

์˜์ˆ˜๋„ค ์ปค๋ฎค๋‹ˆํ‹ฐ ์ถœ์‹œ ํ›„, ๊ฒŒ์‹œ๊ธ€์ด ๊ตฌ๊ธ€์— ์•ˆ ๊ฑธ๋ฆฌ๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค.

๐Ÿ‘” ์˜์ˆ˜(PM): "์˜์ฒ  ๋‹˜, ์šฐ๋ฆฌ ๊ฒŒ์‹œ๊ธ€์„ ๊ตฌ๊ธ€์—์„œ ๊ฒ€์ƒ‰ํ•˜๋ฉด ์•ˆ ๋‚˜์™€์š”. SEO ์„ค์ • ๋‹ค ํ–ˆ๋‹ค๊ณ  ํ•˜์ง€ ์•Š์•˜์–ด์š”?"

์˜์ฒ ์ด์˜ ๊ธฐ์กด ์…‹์—…: ์ˆœ์ˆ˜ React CRA(Create React App). ์ฆ‰ CSR(Client-Side Rendering) ์ด์—ˆ๋‹ค.


๐Ÿ†š 1. CSR vs SSR โ€” ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๋ฐ›๋Š” HTML์˜ ์ฐจ์ด

CSR (Client-Side Rendering)

<!-- ๊ตฌ๊ธ€ ๋ด‡์ด CSR ์‚ฌ์ดํŠธ์— ์ ‘์†ํ•ด์„œ ๋ฐ›๋Š” HTML -->
<!doctype html>
<html>
  <head>
    <title>์˜์ˆ˜๋„ค ์ปค๋ฎค๋‹ˆํ‹ฐ</title>
  </head>
  <body>
    <!-- ๋นˆ ๊ป๋ฐ๊ธฐ! ์ฝ˜ํ…์ธ ๊ฐ€ ์—†์Œ -->
    <div id="root"></div>
    <!-- JS ๋ฒˆ๋“ค์ด ์‹คํ–‰๋˜์–ด์•ผ ์ด div ์•ˆ์— ์ฝ˜ํ…์ธ ๊ฐ€ ์ฑ„์›Œ์ง -->
    <script src="/static/js/bundle.js"></script>
  </body>
</html>

๊ตฌ๊ธ€ ๋ด‡์€ JavaScript๋ฅผ ์‹คํ–‰ํ•˜๊ธด ํ•˜์ง€๋งŒ, ์‹คํ–‰์— ์‹œ๊ฐ„ ์ง€์—ฐ์ด ์žˆ๊ณ  JS๊ฐ€ ๋ฌด๊ฑฐ์šธ์ˆ˜๋ก ํฌ๋กค๋ง ํ’ˆ์งˆ์ด ๋–จ์–ด์ ธ. ์ฝ˜ํ…์ธ ๊ฐ€ ์—†๋Š” ์ดˆ๊ธฐ HTML์€ SEO์— ๋ถˆ๋ฆฌํ•ด.

SSR (Server-Side Rendering)

<!-- ๊ตฌ๊ธ€ ๋ด‡์ด Next.js SSR ์‚ฌ์ดํŠธ์— ์ ‘์†ํ•ด์„œ ๋ฐ›๋Š” HTML -->
<!doctype html>
<html lang="ko">
  <head>
    <title>๋ฆฌ์•กํŠธ ์ƒํƒœ๊ด€๋ฆฌ ๋น„๊ต | ์˜์ˆ˜๋„ค ์ปค๋ฎค๋‹ˆํ‹ฐ</title>
    <meta name="description" content="Zustand, Jotai ์‹ค๋ฌด ๋น„๊ต ๋ถ„์„" />
  </head>
  <body>
    <!-- ์ด๋ฏธ ์ฝ˜ํ…์ธ ๊ฐ€ ์ฑ„์›Œ์ ธ ์žˆ์Œ! -->
    <main>
      <article>
        <h1>๋ฆฌ์•กํŠธ ์ƒํƒœ๊ด€๋ฆฌ ๋น„๊ต: Zustand vs Jotai</h1>
        <p>์ €๋Š” ์š”์ฆ˜ Zustand๋ฅผ ์“ฐ๋Š”๋ฐ, Jotai์™€ ์„ฑ๋Šฅ ์ฐจ์ด๊ฐ€...</p>
        <section>
          <h2>๋Œ“๊ธ€ 5๊ฐœ</h2>
          <!-- ๋Œ“๊ธ€๋“ค๋„ HTML์— ํฌํ•จ -->
        </section>
      </article>
    </main>
    <!-- JS๋Š” Hydration์„ ์œ„ํ•ด ๋กœ๋“œ -->
    <script src="/_next/static/chunks/app.js" defer></script>
  </body>
</html>

์„œ๋ฒ„์—์„œ ์ด๋ฏธ ๋ Œ๋”๋ง๋œ HTML์„ ๋ธŒ๋ผ์šฐ์ €์— ์ „๋‹ฌํ•ด. ๊ตฌ๊ธ€ ๋ด‡์ด JavaScript ์‹คํ–‰ ์ „์—๋„ ์ฝ˜ํ…์ธ ๋ฅผ ์ฝ์„ ์ˆ˜ ์žˆ์–ด.


๐Ÿ’ง 2. Hydration โ€” ์ •์  HTML์— ์ธํ„ฐ๋ž™ํ‹ฐ๋น„ํ‹ฐ ์‹ฌ๊ธฐ

SSR๋กœ ๋ Œ๋”๋ง๋œ HTML์€ ํ™”๋ฉด์— ๋ฐ”๋กœ ๋ณด์ด์ง€๋งŒ, ์•„์ง ์ธํ„ฐ๋ž™ํ‹ฐ๋ธŒํ•˜์ง€ ์•Š์•„ (๋ฒ„ํŠผ ํด๋ฆญ, ์ƒํƒœ ๋ณ€ํ™” ์—†์Œ). Hydration์€ ์ด ์ •์  HTML์— React์˜ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ์™€ ์ƒํƒœ ๊ด€๋ฆฌ๋ฅผ ์—ฐ๊ฒฐํ•˜๋Š” ๊ณผ์ •์ด์•ผ.

[์„œ๋ฒ„] โ†’ HTML ์ƒ์„ฑ โ†’ ๋ธŒ๋ผ์šฐ์ €์— ์ „์†ก
     โ†“
[๋ธŒ๋ผ์šฐ์ €] HTML ์ฆ‰์‹œ ํ‘œ์‹œ (์‚ฌ์šฉ์ž๊ฐ€ ๋น ๋ฅด๊ฒŒ ๋ด„)
     โ†“
[๋ธŒ๋ผ์šฐ์ €] JS ๋ฒˆ๋“ค ๋‹ค์šด๋กœ๋“œ + ์‹คํ–‰
     โ†“
[React] ๊ธฐ์กด DOM์„ ๋‹ค์‹œ ๋ Œ๋”๋งํ•˜์ง€ ์•Š๊ณ ,
        ์ด๋ฏธ ์žˆ๋Š” DOM์— ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ + ์ƒํƒœ ์—ฐ๊ฒฐ
        = Hydration ์™„๋ฃŒ โ†’ ์ธํ„ฐ๋ž™ํ‹ฐ๋ธŒํ•œ ์•ฑ์ด ๋จ
// Next.js Pages Router: ์„œ๋ฒ„์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ props๋กœ ์ „๋‹ฌ
export async function getServerSideProps() {
  const post = await fetchPost(params.id);
  return { props: { post } };
}
 
export default function PostPage({ post }) {
  const [liked, setLiked] = useState(false);
 
  return (
    <article>
      <h1>{post.title}</h1>
      {/* ์ด ๋ฒ„ํŠผ์€ Hydration ์ „์—” ํด๋ฆญ ์•ˆ ๋จ */}
      <button onClick={() => setLiked(!liked)}>
        {liked ? "โค๏ธ" : "๐Ÿค"} ์ข‹์•„์š”
      </button>
    </article>
  );
}

Hydration Mismatch ์—๋Ÿฌ:
์„œ๋ฒ„์—์„œ ๋ Œ๋”๋งํ•œ HTML๊ณผ ํด๋ผ์ด์–ธํŠธ์—์„œ React๊ฐ€ ๋งŒ๋“ค๋ ค๋Š” VDOM์ด ๋‹ค๋ฅด๋ฉด ์—๋Ÿฌ ๋ฐœ์ƒ.

// โŒ Hydration Mismatch ์›์ธ: ์„œ๋ฒ„/ํด๋ผ์ด์–ธํŠธ ํ™˜๊ฒฝ ์ฐจ์ด
function Greeting() {
  // ์„œ๋ฒ„: typeof window === 'undefined' โ†’ ๋‹ค๋ฅธ ๊ฒฐ๊ณผ
  // ํด๋ผ์ด์–ธํŠธ: typeof window === 'object' โ†’ ๋‹ค๋ฅธ ๊ฒฐ๊ณผ
  return <div>{typeof window === 'undefined' ? 'Server' : 'Client'}</div>;
}
 
// โœ… ํ•ด๊ฒฐ: useEffect๋กœ ํด๋ผ์ด์–ธํŠธ์—์„œ๋งŒ ์‹คํ–‰
function Greeting() {
  const [isClient, setIsClient] = useState(false);
  useEffect(() => setIsClient(true), []);
  return <div>{isClient ? 'Client' : 'Loading...'}</div>;
}

๐Ÿ—๏ธ 3. Next.js App Router โ€” ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์™€ HTML

Next.js App Router์˜ ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋Š” ํด๋ผ์ด์–ธํŠธ๋กœ JavaScript๋ฅผ ์ „ํ˜€ ๋ณด๋‚ด์ง€ ์•Š๊ณ  HTML๋งŒ ์ƒ์„ฑํ•ด.

// app/posts/[id]/page.tsx โ€” ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ (๊ธฐ๋ณธ)
// ์ด ์ปดํฌ๋„ŒํŠธ๋Š” ์„œ๋ฒ„์—์„œ๋งŒ ์‹คํ–‰, ํด๋ผ์ด์–ธํŠธ JS ๋ฒˆ๋“ค์— ํฌํ•จ ์•ˆ ๋จ
async function PostPage({ params }: { params: { id: string } }) {
  // ์„œ๋ฒ„์—์„œ ์ง์ ‘ DB๋‚˜ API ํ˜ธ์ถœ ๊ฐ€๋Šฅ
  const post = await db.post.findUnique({ where: { id: params.id } });
 
  return (
    <article>
      <h1>{post.title}</h1>
      <p>{post.content}</p>
      {/* ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ๋Š” 'use client' ์„ ์–ธ ํ•„์š” */}
      <LikeButton postId={post.id} initialLikes={post.likes} />
    </article>
  );
}
// components/LikeButton.tsx โ€” ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ
"use client"; // ์ด ์„ ์–ธ์ด ์žˆ์–ด์•ผ๋งŒ JS๊ฐ€ ํด๋ผ์ด์–ธํŠธ๋กœ ์ „์†ก๋จ
 
function LikeButton({ postId, initialLikes }: Props) {
  const [likes, setLikes] = useState(initialLikes);
 
  return (
    <button onClick={() => setLikes(l => l + 1)}>
      โค๏ธ {likes}
    </button>
  );
}

๊ฒฐ๊ณผ์ ์œผ๋กœ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๋ฐ›๋Š” HTML:

  • PostPage ์˜ h1, p = ์„œ๋ฒ„์—์„œ ๋งŒ๋“ค์–ด์ง„ ์ •์  HTML (JS ์—†์Œ)
  • LikeButton = ์ดˆ๊ธฐ HTML์— ํฌํ•จ๋˜๋‚˜, Hydration์„ ์œ„ํ•œ JS๊ฐ€ ํด๋ผ์ด์–ธํŠธ๋กœ ์ „์†ก๋จ

๐Ÿ ํ•ต์‹ฌ ๋น„๊ตํ‘œ

๋ Œ๋”๋ง ๋ฐฉ์‹์ดˆ๊ธฐ HTMLJS ํ•„์š”FCPSEO
CSR๋นˆ ๊ป๋ฐ๊ธฐํ•„์ˆ˜๋А๋ฆผ๋ถˆ๋ฆฌ
SSR์ฝ˜ํ…์ธ  ํฌํ•จHydration์šฉ๋น ๋ฆ„์œ ๋ฆฌ
SSG์ฝ˜ํ…์ธ  ํฌํ•จ (๋นŒ๋“œ ์‹œ ์ƒ์„ฑ)Hydration์šฉ๋งค์šฐ ๋น ๋ฆ„๋งค์šฐ ์œ ๋ฆฌ
์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์ฝ˜ํ…์ธ  ํฌํ•จ์ตœ์†Œํ™”๋งค์šฐ ๋น ๋ฆ„๋งค์šฐ ์œ ๋ฆฌ


๐Ÿ“ ๋งˆ๋ฌด๋ฆฌ ํ€ด์ฆˆ

Q1. ๋‹ค์Œ ์ค‘ SEO ๊ด€์ ์—์„œ ์ดˆ๊ธฐ HTML์— ์ฝ˜ํ…์ธ ๊ฐ€ ํฌํ•จ๋˜์–ด ๊ตฌ๊ธ€ ๋ด‡์ด JavaScript ์‹คํ–‰ ์—†์ด๋„ ํŽ˜์ด์ง€ ๋‚ด์šฉ์„ ์ฝ์„ ์ˆ˜ ์žˆ๋Š” ๋ Œ๋”๋ง ๋ฐฉ์‹์€?

  • A) CSR (Create React App ๊ธฐ๋ณธ ๋ฐฉ์‹)
  • B) SSR (Next.js getServerSideProps)
  • ๊ฐ€) CSR + SWR ๋ฐ์ดํ„ฐ ํŽ˜์นญ
  • ๋ผ) CSR + React Query

โœ… ์ •๋‹ต: B

๐Ÿ’ก ์ƒ์„ธ ํ•ด์„ค:

  • SSR์€ ์„œ๋ฒ„์—์„œ HTML์„ ์™„์„ฑํ•ด์„œ ๋ณด๋‚ด์ฃผ๋ฏ€๋กœ ๊ตฌ๊ธ€ ๋ด‡์ด JavaScript ์—†์ด๋„ ์ฝ˜ํ…์ธ ๋ฅผ ์ฝ์„ ์ˆ˜ ์žˆ์–ด์š”. CSR ๋ฐฉ์‹์€ ์ดˆ๊ธฐ HTML์ด ๋นˆ ๊ป๋ฐ๊ธฐ์ด๊ณ  JavaScript๊ฐ€ ์‹คํ–‰๋˜์–ด์•ผ ์ฝ˜ํ…์ธ ๊ฐ€ ์ฑ„์›Œ์ง€๋ฏ€๋กœ SEO์— ๋ถˆ๋ฆฌํ•ด์š”.
  • ๐Ÿ“Œ ํ•ต์‹ฌ ๊ธฐ์–ต๋ฒ•: "SSR/SSG = ๊ตฌ๊ธ€ ๋ด‡์—๊ฒŒ ์ฝ˜ํ…์ธ  ๋‹ด๊ธด ๋ช…ํ•จ, CSR = ๋นˆ ๋ช…ํ•จ"

Q2. Hydration์ด๋ž€ ๋ฌด์—‡์ธ๊ฐ€?

โœ… ์ •๋‹ต: ์„œ๋ฒ„์—์„œ ๋ Œ๋”๋ง๋œ ์ •์  HTML์— React ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ์™€ ์ƒํƒœ๋ฅผ ์—ฐ๊ฒฐํ•˜์—ฌ ์ธํ„ฐ๋ž™ํ‹ฐ๋ธŒํ•œ ์•ฑ์œผ๋กœ ๋งŒ๋“œ๋Š” ๊ณผ์ •

๐Ÿ’ก ์ƒ์„ธ ํ•ด์„ค:

  • SSR๋กœ ์ƒ์„ฑ๋œ HTML์€ ์‚ฌ์šฉ์ž ๋ˆˆ์— ๋ฐ”๋กœ ๋ณด์ด์ง€๋งŒ, ๋ฒ„ํŠผ ํด๋ฆญ์ด๋‚˜ ์ƒํƒœ ๋ณ€ํ™”๋Š” React JS๊ฐ€ Hydration์„ ์™„๋ฃŒํ•ด์•ผ ์ž‘๋™ํ•ด์š”. Hydration์€ ๊ธฐ์กด DOM์„ ๋‹ค์‹œ ๋ Œ๋”๋งํ•˜์ง€ ์•Š๊ณ  ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ์™€ ์ƒํƒœ๋ฅผ ์—ฐ๊ฒฐํ•˜๋Š” ํšจ์œจ์ ์ธ ๊ณผ์ •์ด์—์š”.

Q3. ์˜์ฒ ์ด์˜ ํ…Œ์ŠคํŠธ ํƒ€์ž„

Next.js App Router ํ”„๋กœ์ ํŠธ์—์„œ 'use client' ์„ ์–ธ ์—†์ด ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ค์—ˆ๋‹ค.
์ด ์ปดํฌ๋„ŒํŠธ์—์„œ useState ๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๊ณ  ํ–ˆ๋”๋‹ˆ ์—๋Ÿฌ๊ฐ€ ๋‚ฌ๋‹ค. ์™œ ๊ทธ๋Ÿฐ๊ฐ€?

โœ… ์ •๋‹ต: ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋Š” ํด๋ผ์ด์–ธํŠธ์—์„œ ์‹คํ–‰๋˜์ง€ ์•Š์œผ๋ฏ€๋กœ useState, useEffect ๊ฐ™์€ React hooks๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค. ํด๋ผ์ด์–ธํŠธ์ธก ์ƒํƒœ/์ธํ„ฐ๋ž™์…˜์ด ํ•„์š”ํ•˜๋ฉด 'use client' ๋ฅผ ์„ ์–ธํ•ด์•ผ ํ•œ๋‹ค

๐Ÿ’ก ์ƒ์„ธ ํ•ด์„ค:

  • ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋Š” ์„œ๋ฒ„์—์„œ๋งŒ ์‹คํ–‰๋˜์–ด HTML์„ ์ƒ์„ฑํ•˜๊ณ  ํด๋ผ์ด์–ธํŠธ๋กœ JS๋ฅผ ๋ณด๋‚ด์ง€ ์•Š์•„์š”. useState ๋Š” ํด๋ผ์ด์–ธํŠธ์—์„œ ๋ธŒ๋ผ์šฐ์ € ๋ฉ”๋ชจ๋ฆฌ์— ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•˜๋Š” ํ›…์ด๋ฏ€๋กœ ์„œ๋ฒ„ ํ™˜๊ฒฝ์—์„œ๋Š” ์˜๋ฏธ๊ฐ€ ์—†์–ด์š”.
  • ๐Ÿ“Œ ํ•ต์‹ฌ ๊ธฐ์–ต๋ฒ•: "์ƒํƒœ/์ด๋ฒคํŠธ/๋ธŒ๋ผ์šฐ์ € API = 'use client' ํ•„์ˆ˜"

๐Ÿฃ ์˜์ฒ ์ด์˜ ํ‡ด๊ทผ ์ผ๊ธฐ

์˜ค๋Š˜ ๋“œ๋””์–ด "์™œ Next.js๊ฐ€ SEO์— ์ข‹์€๊ฐ€" ๋ฅผ HTML ๋ ˆ๋ฒจ์—์„œ ์ดํ•ดํ–ˆ๋‹ค. CRA๋กœ ๋งŒ๋“  ์•ฑ์„ ๊ตฌ๊ธ€ ๋ด‡์ด ๋ณด๋ฉด <div id="root"></div> ํ•œ ์ค„์งœ๋ฆฌ ํŽ˜์ด์ง€๋ฅผ ๋ณด๋Š” ๊ฑฐ์˜€๋‹ค. ๊ทธ๋Ÿฌ๋‹ˆ๊นŒ ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ์— ์•ˆ ๋‚˜์™”๋˜ ๊ฑฐ์ง€. SSR๋กœ ๋ฐ”๊พธ๋‹ˆ๊นŒ ๊ตฌ๊ธ€ ๋ด‡์ด ์‹ค์ œ ๊ฒŒ์‹œ๊ธ€ ๋‚ด์šฉ์ด ๋‹ด๊ธด HTML์„ ๋ฐ›๊ฒŒ ๋˜๊ณ , 2์ฃผ ํ›„์— ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ์— ์šฐ๋ฆฌ ๊ฒŒ์‹œ๊ธ€์ด ๋‚˜์˜ค๊ธฐ ์‹œ์ž‘ํ–ˆ๋‹ค.

๐Ÿ’ก "HTML์€ ์ฒซ์ธ์ƒ์ด๋‹ค. SSR์€ ๊ตฌ๊ธ€ ๋ด‡์—๊ฒŒ ์ฝ˜ํ…์ธ ๊ฐ€ ๋‹ด๊ธด HTML์„ ๋จผ์ € ๋ณด์—ฌ์ฃผ๋Š” ๊ฒƒ, CSR์€ ๋นˆ ์ข…์ด๋ฅผ ์ฃผ๋Š” ๊ฒƒ์ด๋‹ค."

Hydration Mismatch๋Š” ์•„์ง๋„ ๊ณ ํ†ต์Šค๋Ÿฝ์ง€๋งŒ... ์ด์ œ ์™œ ์ƒ๊ธฐ๋Š”์ง€๋Š” ์•Œ๊ฒ ๋‹ค. ์„œ๋ฒ„๋ž‘ ํด๋ผ์ด์–ธํŠธ์˜ ์ดˆ๊ธฐ ๋ Œ๋”๋ง ๊ฒฐ๊ณผ๊ฐ€ ๋‹ฌ๋ผ์„œ React๊ฐ€ ํ˜ผ๋ž€์Šค๋Ÿฌ์›Œํ•˜๋Š” ๊ฑฐ๋ผ๋Š” ๊ฑธ. ์ด ์—๋Ÿฌ๋ฅผ ๋ณด๋ฉด "์•„, ์„œ๋ฒ„/ํด๋ผ์ด์–ธํŠธ ๋ถ„๊ธฐ๊ฐ€ ๋ฌธ์ œ๊ตฌ๋‚˜" ํ•˜๊ณ  ๋ฐ”๋กœ ์ฐพ์„ ์ˆ˜ ์žˆ๊ฒŒ ๋๋‹ค.


๐Ÿ”— ๋” ์•Œ์•„๋ณด๊ธฐ