소프트웨어 기술(스타트업 위주)

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/linkuseRouter를 활용한 클라이언트 사이드 내비게이션 가능
  • 동적 라우트 ([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 buildnext start 명령어로 프로덕션 모드 실행 가능
Previous
React
Next
vue