[next.js] Next.js 설정 파일(next.config.js 정리)
Next.js에서 설정 파일인 next.config.js는 웹사이트의 동작을 최적화하고 보안을 강화하며 개발 환경과 실제 배포 환경 간의 차이를 관리할 수 있는 중요한 역할을 합니다. 이 문서에서는 설정 파일을 구성하는 방법과 각 기능의 사용 이유, 장점, 단점, 그리고 코드 예제를 통해 자세히 설명하겠습니다
목차
- 리다이렉션 설정하기
- 환경 변수
- 외부 이미지 도메인 허용
- 커스터마이징
- 국제화 설정
- 보안 헤더 설정하기
1. 리다이렉션 설정하기
사용 이유
- 오래된 URL을 새로운 URL로 연결할 때 유용합니다.
- SEO를 유지하고 사용자 경험을 개선할 수 있습니다.
장점
- 사용자가 잘못된 URL로 접속해도 자동으로 올바른 페이지로 이동합니다.
- 검색 엔진 크롤러가 새로운 URL을 쉽게 인식합니다.
단점
- 많은 리다이렉션 규칙이 있을 경우 관리가 복잡해질 수 있습니다.
코드 예시
module.exports = {
async redirects() {
return [
{
source: '/old-page',
destination: '/new-page',
permanent: true, // 301 리다이렉션
},
];
},
};
비유
리다이렉션은 오래된 주소를 새로운 집 주소로 안내하는 우편 서비스와 같습니다. 이를 통해 검색 엔진은 웹사이트의 구조 변화에도 혼란을 겪지 않으며, 올바른 페이지를 색인할 수 있습니다. 특히, 301 리다이렉션은 기존 페이지의 SEO 점수를 새로운 페이지로 이전시켜 검색 순위를 유지하는 데 중요한 역할을 합니다.
2. 환경 변수 설정하기
사용 이유
- 개발 환경과 배포 환경에서 다른 설정값을 사용할 수 있습니다.
- 민감한 정보를 코드에 직접 포함하지 않도록 보호합니다. 예를 들어, API 키, 데이터베이스 URL, 인증 토큰과 같은 민감한 정보는 노출될 경우 보안 사고로 이어질 수 있으므로 환경 변수로 관리해야 합니다.
장점
- 환경별로 다른 설정을 쉽게 관리할 수 있습니다.
- 민감한 데이터를 안전하게 처리할 수 있습니다.
단점
- 환경 변수가 올바르게 설정되지 않으면 예상치 못한 동작이 발생할 수 있습니다.
코드 예시
module.exports = {
env: {
CUSTOM_API_ENDPOINT: process.env.CUSTOM_API_ENDPOINT,
},
};
비유
환경 변수는 다양한 재료를 저장하는 찬장처럼, 필요할 때 필요한 재료(API, 키 등)를 꺼내 쓸 수 있게 합니다.
3. 외부 이미지 도메인 허용하기
사용 이유
- 외부 이미지 리소스를 활용하여 웹사이트 성능을 최적화할 수 있습니다.
장점
- CDN을 활용한 빠른 이미지 로딩이 가능합니다.
- 다양한 출처의 이미지를 사용할 수 있습니다.
단점
- 도메인을 추가로 관리해야 합니다.
코드 예시
module.exports = {
images: {
domains: ['example.com', 'images.unsplash.com'],
},
};
비유
이미지 도메인 허용은 특정 친구만 파티에 초대하는 것과 같습니다.
4. Webpack 설정 커스터마이징
사용 이유
- 빌드 과정을 세부적으로 제어하여 프로젝트 요구 사항에 맞출 수 있습니다.
장점
- 프로젝트에 특화된 플러그인을 추가할 수 있습니다.
- 빌드 성능을 최적화할 수 있습니다.
단점
- 복잡한 설정은 유지보수를 어렵게 만들 수 있습니다.
코드 예시
module.exports = {
webpack: (config, { webpack }) => {
config.plugins.push(new webpack.DefinePlugin({
'process.env.VERSION': JSON.stringify('1.0.0'),
}));
return config;
},
};
비유
Webpack 커스터마이징은 레고 조립에서 자신만의 특별한 부품을 추가하는 것과 같습니다. 이를 통해 개발자는 빌드 프로세스를 보다 효율적으로 디버깅할 수 있습니다. 특히, 소스맵(source map)을 활성화하면 원본 코드를 기반으로 오류를 추적할 수 있어 디버깅 과정이 훨씬 간단해집니다. 하지만 복잡한 설정으로 인해 디버깅 시 불필요한 변수가 생길 수 있으므로 적절한 테스트와 검토가 필요합니다.
5. 국제화 설정
사용 이유
- 다국어 사용자 경험을 제공합니다. 이를 위해 i18next와 같은 번역 도구나 서비스를 활용하면 실무에서 더욱 효과적으로 다국어 지원을 구현할 수 있습니다. i18next는 다양한 언어 파일 관리 및 번역 작업을 단순화하며, Next.js와의 통합도 용이합니다.
장점
- 전 세계 사용자를 대상으로 서비스를 확장할 수 있습니다.
- 기본 언어 설정을 통해 접근성을 높입니다.
단점
- 번역 및 언어 파일 관리가 필요합니다.
코드 예시
module.exports = {
i18n: {
locales: ['en', 'ko', 'ja'],
defaultLocale: 'en',
},
};
비유
국제화 설정은 전 세계 여행자를 위한 다국어 표지판을 설치하는 것과 같습니다.
6. 보안 헤더 설정하기
사용 이유
- 다양한 보안 위협(클릭재킹, XSS 등)으로부터 보호합니다.
장점
- 보안이 강화됩니다.
- 사용자의 데이터를 안전하게 보호할 수 있습니다.
단점
- 잘못된 설정은 정상적인 동작을 방해할 수 있습니다.
주요 보안 헤더 기능
- X-Content-Type-Options
- 사용 목적: 브라우저가 잘못된 MIME 타입으로 파일을 실행하지 않도록 방지.
- 설정값: nosniff.
- 예: X-Content-Type-Options: nosniff.
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options
- X-Frame-Options
- 사용 목적: 클릭재킹 공격 방지.
- 설정값: DENY, SAMEORIGIN, ALLOW-FROM.
- 예: X-Frame-Options: DENY.
- https://developer.mozilla.org/ko/docs/Web/HTTP/Headers/X-Frame-Options
- X-XSS-Protection
- 사용 목적: 브라우저에서 XSS 공격을 탐지하고 방지.
- 설정값: 1; mode=block.
- 예: X-XSS-Protection: 1; mode=block.
- https://developer.mozilla.org/ko/docs/Web/HTTP/Headers/X-XSS-Protection
- Strict-Transport-Security (HSTS)
- 사용 목적: HTTPS를 강제하여 중간자 공격 방지.
- 설정값: max-age=SECONDS; includeSubDomains.
- 예: Strict-Transport-Security: max-age=31536000; includeSubDomains.
- https://yozm.wishket.com/magazine/detail/1862/
- Content-Security-Policy (CSP)
- 사용 목적: 허용된 리소스 출처를 명시하여 XSS 및 데이터 삽입 공격 방지.
- 설정값: default-src 'self'; 등.
- 예: Content-Security-Policy: default-src 'self'; script-src 'self';
- https://developer.mozilla.org/ko/docs/Web/HTTP/CSP.
코드 예시
module.exports = {
async headers() {
return [
{
source: '/(.*)',
headers: [
{ key: 'X-Content-Type-Options', value: 'nosniff' },
{ key: 'X-Frame-Options', value: 'DENY' },
{ key: 'X-XSS-Protection', value: '1; mode=block' },
{ key: 'Strict-Transport-Security', value: 'max-age=31536000; includeSubDomains' },
{ key: 'Content-Security-Policy', value: "default-src 'self'; script-src 'self';" },
],
},
];
},
};
보안 헤더 설정은 집에 잠금장치, 경보 시스템, 그리고 감시 카메라를 설치하는 것과 같습니다.
이 문서를 통해 next.config.js의 다양한 기능과 설정을 이해하고, 필요에 맞게 프로젝트를 최적화할 수 있기를 바랍니다!
/** @type {import('next').NextConfig} */
const nextConfig = {
// 보안 헤더를 설정하는 비동기 함수
async headers() {
// 현재 환경이 개발 환경인지 확인
const isDevelopment = process.env.NODE_ENV === "development";
// 기본적인 보안 헤더 설정 배열
const securityHeaders = [
{
// MIME 타입 스니핑 방지
key: "X-Content-Type-Options",
value: "nosniff",
},
{
// iframe으로 페이지가 로드되는 것을 방지
key: "X-Frame-Options",
value: "DENY",
},
{
// XSS 공격 방지를 위한 브라우저 내장 필터 활성화
key: "X-XSS-Protection",
value: "1; mode=block",
},
{
// HTTPS 강제 적용 (HSTS)
key: "Strict-Transport-Security",
value: "max-age=31536000; includeSubDomains",
},
];
// Content Security Policy(CSP) 헤더 설정
const cspHeader = {
key: "Content-Security-Policy",
value: [
// 기본적으로 같은 출처의 리소스만 허용
"default-src 'self'",
// 스크립트 실행 정책 (개발/프로덕션 환경 분리)
isDevelopment
? "script-src 'self' 'unsafe-inline' 'unsafe-eval' https://vercel.live"
: "script-src 'self' 'unsafe-inline' 'unsafe-eval'",
// 스타일 로딩 정책
"style-src 'self' 'unsafe-inline'",
// 이미지 로딩 정책
"img-src 'self' data: blob:",
// 폰트 로딩 정책
"font-src 'self'",
// iframe 관련 정책
"frame-ancestors 'none'",
// 폼 제출 정책
"form-action 'self'",
// iframe 소스 정책
"frame-src 'self'",
// 미디어 파일 정책
"media-src 'self'",
// 매니페스트 파일 정책
"manifest-src 'self'",
].join("; "),
};
// 모든 경로에 보안 헤더 적용
return [
{
source: "/:path*",
headers: [...securityHeaders, cspHeader],
},
];
},
};
module.exports = nextConfig;