공식 문서 보기를 돌같이 하는 버릇을 고치자!
13버전을 익히기도 전에 14버전이 출시된 Next.js... 마지막으로 공부했던 버전이 12였기에 새로 공부해야 함을 느꼈다. 다행히 공식 문서가 매우매우 잘 되어 있었다. Learn Next 페이지를 이용하여 14버전을 익혀보려고 한다.
대시보드 앱을 만드는 과정으로, 16장으로 이루어졌다. 모두 익히면 Next.js의 필수 기술을 갖추게 된다고 한다. 다음은 배울 내용이다.
React와 자바스크립트에 대한 기본적인 이해가 있다고 가정하며 Node는 18.17.0 이상을 기준으로 한다.
Next의 설치는 npx create-next-app@latest로 하는데, 여기서는 제공하는 예제를 포함하여 설치한다.
npx create-next-app@latest nextjs-dashboard --use-npm --example "https://github.com/vercel/next-learn/tree/main/dashboard/starter-example"
예제의 app 디렉토리의 구성은 다음과 같다.
├─public
│
├─app
│ │ layout.tsx # 전체 레이아웃 (필수)
│ │ page.tsx # index 페이지 (필수)
│ │
│ ├─lib
│ │ data.ts # 데이터 패치
│ │ definitions.ts # 타입 정의
│ │ placeholder-data.js # 미리 생성한 mockup 데이터
│ │ utils.ts # 화폐 단위, 날짜 형식, 컬럼 설정, 페지네이션 생성 등
│ │
│ └─ui # UI를 구성하는 컴포넌트
│ │ acme-logo.tsx
│ │ button.tsx
│ │ global.css
│ │ login-form.tsx
│ │ search.tsx
│ │ skeletons.tsx
│ │
│ ├─customers
│ │ table.tsx
│ │
│ ├─dashboard
│ │ cards.tsx
│ │ latest-invoices.tsx
│ │ nav-links.tsx
│ │ revenue-chart.tsx
│ │ sidenav.tsx
│ │
│ └─invoices
│ breadcrumbs.tsx
│ buttons.tsx
│ create-form.tsx
│ edit-form.tsx
│ pagination.tsx
│ status.tsx
│ table.tsx
└─scripts
seed.js # 데이터베이스를 채울 시딩
컴포넌트 이름과 내부의 이름이 깔끔해서 어렵게 고민할 필요가 없었다. 이게 네이밍 센스란 건가? 벌써 하나 배웠다.
npm run dev로 실행한 첫 화면이다.

2장에서는 아무것도 꾸며지지 않은 홈페이지를 어떻게 스타일링하는가를 알려준다.
앱 전체에 공용으로 적용하는 스타일은 최상위 루트에서 호출하여 사용한다. Next에서는 app 디렉토리의 바로 아래에 있는 layout.tsx이 Root Layout이다.
RootLayout에서 global.css를 호출한다.
// layout.tsx
+ import '@/app/ui/global.css';
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body>{children}</body>
</html>
);
}
Next는 Tailwind CSS를 지원하기 때문에 global.css에는 Tailwind CSS의 기본 지시문을 포함하고 있다.
/* global.css*/
@tailwind base;
@tailwind components;
@tailwind utilities;
global.css를 적용한 화면은 처음과 달리 보기 편안하다.

앞서 언급한 Tailwind CSS는 className으로 빠르고 쉽게 스타일을 적용하는 CSS Framework이다. Next에서 기본적으로 지원하며, create-next-app으로 세팅 시 사용 여부를 묻는다. yes를 선택하면 필요한 자원을 알아서 설치해준다.
<Link
href="/login"
className="flex items-center gap-5 self-start rounded-lg bg-blue-500 px-6 py-3 text-sm font-medium text-white transition-colors hover:bg-blue-400 md:text-base"
>
<span>Log in</span> <ArrowRightIcon className="w-5 md:w-6" />
</Link>
위 이미지에서 보이는 Log in 버튼의 코드이다. 개인적으로 제일 선호하는 스타일링 시스템이기도 하다. config 파일에서 커스텀 클래스를 만들 수도 있고, 수치가 적용되는 클래스명에 직접 설정할 수도 있다.
// tailwind.config.js
import type { Config } from 'tailwindcss';
const config: Config = {
theme: {
extend: {
// custom color를 세팅한다
colors: {
blue: {
400: '#2589FE',
500: '#0070F3',
600: '#2F6FEB',
},
},
},
},
};
export default config;
// temp.jsx
<p className="p-[10px]">패딩 수치 직접 설정</p>
CSS Modules는 CSS의 범위를 컴포넌트 범위로 축소해 더 쉽게 스타일을 관리하고 충돌을 방지하는 이점을 제공한다. *.module.css로 생성한 후 import styles from "./temp.module.css"로 호출했다. className={styles.wrapper}으로 적용했다.
import styles from './temp.module.css';
function Temp() {
return (
<div className={styles.wrapper}>
<h1 className={styles.title}>Hello CSS Modules!</h1>
</div>
);
}
선호하는 방식은 아니다. CSS 작성도 귀찮고, 파일도 늘어나고, 보기도 불편하기 때문이다. 아직 스타일 변화가 잦아 유지보수가 빡세게 필요한 무언가를 만들어 본 경험이 없어서 그럴 수도. 아무튼 지금은 패스.
clsx는 조건부로 클래스명을 입력할 때 사용할 수 있는 라이브러리이다.
import clsx from 'clsx';
export default function InvoiceStatus({ status }: { status: string }) {
return (
<span
className={clsx(
'inline-flex items-center rounded-full px-2 py-1 text-sm',
{
'bg-gray-100 text-gray-500': status === 'pending',
'bg-green-500 text-white': status === 'paid',
},
)}
>
// ...
)}
value가 truthy일 경우 key로 받은 클래스명을 적용한다.
이 외에 CSS-in-JS 방식의 styled-components, styled-jsx, emotion 등이나 SASS가 있다.