Next.js 연동하기

Next.js 연동하기 (Usage with Next.js)

Next.js는 현재 세계에서 가장 인기 있는 React 서버사이드 동형(Isomorphic) 프레임워크예요. 이 글에서는 Next.js로 만든 프로젝트에서 antd 컴포넌트를 사용하는 방법을 따라 해볼게요.

출처: 문서

본문

Next.js는 현재 전 세계에서 가장 인기 있는 React 서버사이드 동형 프레임워크예요. 이 글에서는 Next.js로 만든 프로젝트에서 antd 컴포넌트를 사용해 볼게요.

설치와 초기화

시작하기 전에 yarn이나 pnpm 또는 bun을 설치해 두어야 해요.

이 도구는 환경과 의존성을 자동으로 만들고 초기화해 줘요. 네트워크 오류가 발생하면 프록시 설정을 바꾸거나 다른 npm 레지스트리를 사용해 보세요.

초기화가 끝나면 프로젝트로 들어가서 실행해 볼게요.

$ cd antd-demo
$ npm run dev

브라우저에서 http://localhost:3000/ 을 열어 NEXT 로고가 보이면 성공이에요.

antd 가져오기

이제 yarn이나 npm, pnpm, bun으로 antd를 설치해 볼게요.

src/app/page.tsx를 수정해서 antd에서 Button 컴포넌트를 가져와 봅시다.

import React from 'react';
import { Button } from 'antd';

const Home = () => (
  <div className="App">
    <Button type="primary">Button</Button>
  </div>
);

export default Home;

이제 페이지에 파란색 primary 버튼이 표시되는 걸 확인할 수 있을 거예요. 이제 antd의 어떤 컴포넌트든 선택해서 여러분의 애플리케이션을 개발하면 돼요. Next.js의 다른 워크플로우는 사용자 가이드에서 확인할 수 있어요.

첫 화면에서 antd 컴포넌트에 스타일이 적용되지 않는 걸 발견할 수 있을 거예요. 이제 Next.js의 모드에 따라 서로 다른 SSR 스타일 처리 방식을 선택해야 해요.

App Router 사용하기 업데이트됨

Next.js에서 App Router를 사용하면서 antd를 컴포넌트 라이브러리로 사용한다면, antd 컴포넌트 라이브러리가 여러분의 Next.js 애플리케이션에서 더 잘 동작하고 더 나은 사용자 경험을 제공하도록, 다음 방법으로 antd의 첫 화면 스타일을 HTML로 추출해서 주입해 페이지 깜빡임(flicker)을 방지해 볼 수 있어요.

  1. @ant-design/nextjs-registry 설치

  1. app/layout.tsx에서 사용
import React from 'react';
import { AntdRegistry } from '@ant-design/nextjs-registry';

const RootLayout = ({ children }: React.PropsWithChildren) => (
  <html lang="en">
    <body>
      <AntdRegistry>{children}</AntdRegistry>
    </body>
  </html>
);

export default RootLayout;

:::warning Next.js App Router는 현재 <Select.Option />이나 <Typography.Text />처럼 .을 사용한 하위 컴포넌트 호출을 지원하지 않아요. 경로(path)에서 직접 임포트하면 이 문제를 해결할 수 있어요. :::

더 자세한 내용은 with-nextjs-app-router-inline-style을 참고하세요.

Pages Router 사용하기

Next.js에서 Pages Router를 사용하면서 antd를 컴포넌트 라이브러리로 사용한다면, antd 컴포넌트 라이브러리가 여러분의 Next.js 애플리케이션에서 더 잘 동작하고 더 나은 사용자 경험을 제공하도록, 다음 방법으로 antd의 첫 화면 스타일을 HTML로 추출해서 주입해 페이지 깜빡임을 방지해 볼 수 있어요.

  1. @ant-design/[email protected] 설치

개발자를 위한 참고 사항

@ant-design/cssinjs를 설치할 때는 반드시 antd의 로컬 node_modules에 있는 @ant-design/cssinjs 버전과 일치해야 해요. 그렇지 않으면 여러 React 인스턴스가 생겨 ctx를 올바르게 읽지 못하는 문제가 발생할 수 있어요. (팁: npm ls @ant-design/cssinjs 명령으로 로컬 버전을 확인할 수 있어요)

image

  1. pages/_document.tsx 다시 작성
import React from 'react';
import { createCache, extractStyle, StyleProvider } from '@ant-design/cssinjs';
import Document, { Head, Html, Main, NextScript } from 'next/document';
import type { DocumentContext } from 'next/document';

const MyDocument = () => (
  <Html lang="en">
    <Head />
    <body>
      <Main />
      <NextScript />
    </body>
  </Html>
);

MyDocument.getInitialProps = async (ctx: DocumentContext) => {
  const cache = createCache();
  const originalRenderPage = ctx.renderPage;
  ctx.renderPage = () =>
    originalRenderPage({
      enhanceApp: (App) => (props) => (
        <StyleProvider cache={cache}>
          <App {...props} />
        </StyleProvider>
      ),
    });

  const initialProps = await Document.getInitialProps(ctx);
  const style = extractStyle(cache, true);
  return {
    ...initialProps,
    styles: (
      <>
        {initialProps.styles}
        <style dangerouslySetInnerHTML={{ __html: style }} />
      </>
    ),
  };
};

export default MyDocument;
  1. 커스텀 테마 지원
// theme/themeConfig.ts
import type { ThemeConfig } from 'antd';

const theme: ThemeConfig = {
  token: {
    fontSize: 16,
    colorPrimary: '#52c41a',
  },
};

export default theme;
  1. pages/_app.tsx 다시 작성
import React from 'react';
import { ConfigProvider } from 'antd';
import type { AppProps } from 'next/app';

import theme from './theme/themeConfig';

const App = ({ Component, pageProps }: AppProps) => (
  <ConfigProvider theme={theme}>
    <Component {...pageProps} />
  </ConfigProvider>
);

export default App;
  1. 페이지 컴포넌트에서 antd 사용
import React from 'react';
import { Button } from 'antd';

const Home = () => (
  <div className="App">
    <Button type="primary">Button</Button>
  </div>
);

export default Home;

더 자세한 내용은 with-nextjs-inline-style을 참고하세요.

더 알아보기 (Learn more)