소프트웨어 기술(스타트업 위주)
next
next 정리 입니다.
Next.js 개발 가이드
1. 시작하기 (Getting Started)
1.1 프로젝트 구조 (Project Structure)
1.1.1 폴더 및 파일 컨벤션 (Folder and File Convention)
- Next.js 프로젝트의 기본적인 폴더 및 파일 구조는 다음과 같습니다.
my-next-app/
├── app/ # (Next 13+) 새로운 App Router 사용 시
│ └── page.tsx # 루트 페이지
│ └── layout.tsx # 레이아웃 정의
│ └── about/page.tsx # /about 경로
│ └── api/hello/route.ts # API 라우팅 (App Router 전용)
│
├── pages/ # (기존 방식) Page Router 방식
│ └── index.tsx # 메인 페이지 (/)
│ └── about.tsx # /about 페이지
│ └── api/hello.ts # API 라우팅 (기본 API 라우트)
│
├── public/ # 정적 파일 (이미지, favicon 등)
│ └── logo.png
│
├── styles/ # CSS, SCSS 등 스타일 파일
│ └── globals.css
│
├── components/ # 재사용 가능한 컴포넌트
│ └── Header.tsx
│ └── Footer.tsx
│
├── hooks/ # 커스텀 훅
│ └── useToggle.ts
│
├── lib/ # 유틸 함수, API 클라이언트, 외부 라이브러리 래퍼
│ └── fetcher.ts
│
├── types/ # 타입 정의 (TypeScript 프로젝트일 때)
│ └── user.d.ts
│
├── .env.local # 환경 변수 파일
├── next.config.js # Next.js 설정 파일
├── tsconfig.json # TypeScript 설정 (TS 사용 시)
└── package.json
2. 애플리케이션 빌드 (Building Your Application)
2.1 라우팅 및 내비게이션 (Routing and Navigation)
next/link
및useRouter
를 활용한 클라이언트 사이드 내비게이션 가능- 동적 라우트 (
[id].js
), 병렬 라우트, 인터셉트 라우트 적용 가능
2.2 데이터 관리 및 가져오기 (Data Fetching & Management)
서버에서 데이터 가져오기 (SSR / SSG / ISR) Next.js에서는 다양한 방법으로 서버 측에서 데이터를 가져올 수 있습니다.
- getServerSideProps – SSR (Server Side Rendering)
export async function getServerSideProps() {
const res = await fetch('https://api.example.com/data');
const data = await res.json();
return { props: { data } };
}
요청마다 실행
로그인 등 최신 정보가 필요한 경우 유용
getStaticProps – SSG (Static Site Generation)
export async function getStaticProps() {
const res = await fetch('https://api.example.com/data');
const data = await res.json();
return { props: { data } };
}
정적 페이지 생성, 빌드 타임에 한번만 실행
빠른 성능, CDN 캐싱 가능
getStaticProps + revalidate – ISR (Incremental Static Regeneration)
export async function getStaticProps() {
const data = await fetchData();
return {
props: { data },
revalidate: 60, // 60초마다 페이지 재생성
};
}
정적 페이지 + 일정 주기마다 갱신됨
App Router (Next 13+) – fetch & generateStaticParams 활용
// app/products/[id]/page.tsx
export async function generateStaticParams() {
const res = await fetch('https://api.example.com/products');
const products = await res.json();
return products.map(product => ({
id: product.id.toString(),
}));
}
export default async function ProductPage({ params }) {
const res = await fetch(`https://api.example.com/products/${params.id}`);
const product = await res.json();
return <div>{product.name}</div>;
}
- 클라이언트에서 데이터 가져오기
- 기본적인 fetch + useEffect
import { useEffect, useState } from 'react';
export default function ClientPage() {
const [data, setData] = useState(null);
useEffect(() => {
fetch('/api/hello')
.then(res => res.json())
.then(setData);
}, []);
return <div>{data ? data.message : 'Loading...'}</div>;
}
- SWR – 클라이언트 캐싱 + 자동 갱신
npm install swr
import useSWR from 'swr';
const fetcher = url => fetch(url).then(res => res.json());
export default function Page() {
const { data, error, isLoading } = useSWR('/api/data', fetcher);
if (isLoading) return <div>로딩 중...</div>;
if (error) return <div>에러 발생!</div>;
return <div>{data.message}</div>;
}
- 클라이언트 캐싱
- 자동 리패치 (focus, revalidation)
- React Query – 클라이언트 중심의 캐싱/상태 관리
npm install @tanstack/react-query
import { useQuery } from '@tanstack/react-query';
function Page() {
const { data, isLoading } = useQuery({
queryKey: ['data'],
queryFn: () => fetch('/api/data').then(res => res.json())
});
if (isLoading) return <div>로딩중...</div>;
return <div>{data.message}</div>;
}
강력한 캐싱 + 다양한 기능 (mutation, invalidate, refetch 등)
캐싱 전략 요약
캐싱 방법 | 설명 |
---|---|
getStaticProps | 정적 캐싱, 빌드 시 생성 |
ISR (revalidate) | 정적 캐싱 + 주기적 갱신 |
SWR / React Query | 클라이언트 측 캐싱, 자동 갱신 |
fetch(cache: 'force-cache') | App Router에서 fetch 캐싱 제어 |
- 정리
방식 | 위치 | 사용 예 | 특징 |
---|---|---|---|
getServerSideProps | 서버 | 로그인 필요 페이지 | SSR |
getStaticProps | 서버 | 블로그, 문서 | SSG |
ISR (revalidate) | 서버 | 자주 변경되는 정적 데이터 | SSG + 캐싱 갱신 |
useEffect + fetch | 클라이언트 | 단순 fetch | 초간단 |
SWR, React Query | 클라이언트 | 리스트, 상세, 갱신 데이터 | 캐싱 + 리패치 |
2.3 렌더링 및 성능 최적화 (Rendering & Performance Optimization)
- 서버 컴포넌트 및 클라이언트 컴포넌트의 조합 가능
- 스트리밍 및 부분적 사전 렌더링 지원
2.4 캐싱 및 최적화 (Caching & Optimization)
- 요청 메모이제이션, 데이터 캐싱, 전체 라우트 캐싱 가능
next.config.js
에서output: 'standalone'
설정을 통해 빌드 시 최적화 가능
3. Next.js 주요 기능 (Next.js Features)
3.1 동적 라우팅 (Dynamic Routing)
[id].js
파일을 활용하여 동적 페이지 생성 가능- 예시:
import { useRouter } from 'next/router' export default function Page() { const router = useRouter() const { id } = router.query return <p>Page ID: {id}</p> }
3.2 API 라우트 (API Routes)
pages/api
폴더 내에서 서버리스 API 라우트 생성 가능- 예시:
export default function handler(req, res) { res.status(200).json({ message: 'Hello, Next.js API!' }) }
3.3 국제화 (Internationalization, i18n)
다국어 번역을 해준다는게 아니라 url에 국가 언어별로 자동 라우팅 기능을 지원해준다는 것입니다. i18next와 같은 라이브러리와 통합하면 다국어 번역 기능을 사용할 수 있습니다.
next.config.js
에서 국제화 설정 가능- 예시:
module.exports = { i18n: { locales: ['en', 'ko'], defaultLocale: 'ko', }, }
3.4 미들웨어 (Middleware)
- 요청을 가로채어 사용자 인증 및 접근 제어 가능
다국어 리디렉션이나 인증/보안 기능을 구현할 때 많이 사용됩니다. 요청하기 전에 가로채서 로직을 태워 화면을 전화하는데 주로 사용됩니다.
- 예시:
import { NextResponse } from 'next/server' export function middleware(req) { const url = req.nextUrl.clone() if (!req.cookies.auth) { url.pathname = '/login' return NextResponse.redirect(url) } return NextResponse.next() }
3.5 이미지 최적화 (Image Optimization)
next/image
를 활용하여 자동 최적화 및 lazy loading 지원- 예시:
import Image from 'next/image' export default function MyImage() { return <Image src="/myimage.jpg" width={500} height={300} alt="My Image" /> }
3.6 배포 (Deployment)
Vercel
,Netlify
,AWS
등을 통해 배포 가능next build
및next start
명령어로 프로덕션 모드 실행 가능