자바스크립트/Next js

[next] metadata 와 use client 충돌

KIMJAVAN 2024. 12. 20. 14:10
728x90

[오류상황] 

metadata도 정의하고 싶고 use client 써서 useState 도 쓰고싶은 상황.

둘 다 같이 사용하니까 오류 발생함  (page.tsx에서 발생)

// "use client";

// import { useState } from "react";

export const metadata = {
  title: 'Next.js hihi ;)',
}

export default function Tomato() {
  // const [count, setCount] = useState(0);

  return (
    <main>
      <h1>main page</h1>
      {/* <button onClick={() => setCount(count + 1)}>Click me: {count}</button> */}
    </main>
  );
}

 

위와같이 metadata 쓸거면 useState를 주석하고 useState를 쓸거면 metadata를 주석해야 작동된다 (하나에 같이 못씀)

 

[해결방법]

// app/tomato/page.tsx
export const metadata = {
  title: 'Next.js hihi ;)',
};

import TomatoClient from "./tomato-client"; // 클라이언트 컴포넌트 불러오기

export default function TomatoPage() {
  return (
    <main>
      <TomatoClient /> {/* 클라이언트 컴포넌트 렌더링 */}
    </main>
  );
}
// app/tomato/tomato-client.tsx
"use client";

import { useState } from "react";

export default function TomatoClient() {
  const [count, setCount] = useState(0);

  return (
    <>
      <h1>main page</h1>
      <button onClick={() => setCount(count + 1)}>
        Click me: {count}
      </button>
    </>
  );
}

 

 

  • page.tsx는 서버 컴포넌트이므로 metadata를 정의할 수 있다.
  • TomatoClient는 클라이언트 컴포넌트로, useState와 같은 클라이언트 기능을 사용할 수 있다.
  • 서버 컴포넌트에서 클라이언트 컴포넌트를 렌더링하면, 두 기능을 모두 사용할 수 있다.

 

Next.js에서는 metadata는 서버 컴포넌트에서만 정의할 수 있습니다. 따라서 클라이언트 기능을 사용해야 한다면:

  • metadata를 서버 컴포넌트에 정의하고
  • 클라이언트 로직은 별도의 클라이언트 컴포넌트에 작성하면 된다.

이 방식은 SEO 최적화클라이언트 상태 관리를 모두 해결할 수 있는 Next.js의 표준 방법이다.