본문 바로가기
C.W.K.
Stream
Lesson 08 of 08 · published

프로덕션 출고 체크리스트

~24 min · checklist, launch, audit

Level 0호기심
0 XP0/68 lessons0/11 achievements
0/120 XP to next level120 XP to go0% complete

성능

  • Lighthouse의 주요 범주를 90점 이상으로 확인해.
  • bundle analyzer로 예상 밖의 클라이언트 chunk를 찾아.
  • 무거운 라이브러리는 서버 컴포넌트에 남겨.
  • 첫 화면 핵심 이미지에만 preload를 써.
  • 글꼴은 next/font로 관리해.
  • 라우트마다 캐시와 신선도 전략을 설명할 수 있어야 해.

검색과 공유

  • 모든 페이지에 제목, 설명, Open Graph metadata를 둬.
  • app/sitemap.tsapp/robots.ts로 발견·수집 규칙을 제공해.
  • 배포된 주소에서 OG 이미지와 Twitter Card가 실제로 렌더링되는지 확인해.

보안과 실패 복구

  • CSP, X-Frame-Options, HSTS 같은 보안 헤더를 검토해.
  • NEXT_PUBLIC_ 변수에는 어떤 비밀도 넣지 마.
  • 모든 서버 액션에서 입력과 권한을 다시 검사해.
  • 보안 패치를 위해 지원되는 최신 Next.js minor를 유지해.
  • not-found.tsx, 루트 error.tsx, global-error.tsx를 실제 실패로 시험해.
  • 오류 추적기에 production 사건이 들어오는지 확인해.

접근성과 실제 배포

  • 모든 의미 있는 이미지에 alt, 모든 입력에 label을 제공해.
  • 키보드만으로 이동·제출·모달 닫기가 작동해야 해.
  • 색 대비가 WCAG AA를 통과하는지 확인해.
  • 스크린 리더로 핵심 흐름을 끝까지 점검해.
  • 배포가 READY가 된 뒤 실제 production URL, 응답 상태, 오류 로그를 확인해.

체크박스를 채운 사실보다 실패를 재현해 통과시킨 증거가 중요해. 소스와 빌드가 맞아도 사용자에게 도착한 런타임이 다르면 아직 출고된 게 아니야.

체크리스트마다 명령, URL, screenshot, 로그처럼 다시 확인할 증거를 붙이고 담당자와 유효 기간을 정해. Lighthouse 점수는 최신 build SHA, 보안 header는 실제 production 응답, 오류 추적은 의도적 사건으로 검증해. 한 번 통과한 항목도 dependency와 콘텐츠가 바뀌면 다시 실행돼야 해. 항목이 많다는 이유로 출고가 안전해지는 건 아니야. 제품의 핵심 흐름이 체크리스트 밖에 있으면 사소한 점수는 모두 초록이어도 실패해. 사용자가 실제로 시작해 목표를 끝내는 한 경로를 먼저 정하고, 성능·보안·접근성 검사가 그 경로를 지키게 해. 체크리스트를 최신 배포 SHA에 대해 실행하고 각 항목에 결과 URL이나 로그를 붙여. 키보드·스크린 리더로 핵심 거래를 끝낸 뒤 보안 header와 오류 복구를 실제 production 응답에서 확인해. 실패 항목을 고친 뒤 같은 검사를 재실행해야 초록이 증거가 돼.

Code

next.config에서 보안 헤더 설정하기·ts
// next.config.ts
import type { NextConfig } from 'next';

const config: NextConfig = {
  async headers() {
    return [{
      source: '/(.*)',
      headers: [
        { key: 'X-Frame-Options', value: 'DENY' },
        { key: 'X-Content-Type-Options', value: 'nosniff' },
        { key: 'Referrer-Policy', value: 'strict-origin-when-cross-origin' },
        { key: 'Strict-Transport-Security', value: 'max-age=31536000; includeSubDomains' },
        { key: 'Permissions-Policy', value: 'camera=(), microphone=(), geolocation=()' },
      ],
    }];
  },
};
export default config;
sitemap과 robots·ts
// app/sitemap.ts
import type { MetadataRoute } from 'next';

export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
  const posts = await getAllPosts();
  return [
    { url: 'https://myapp.com', lastModified: new Date(), priority: 1 },
    ...posts.map(p => ({
      url: `https://myapp.com/blog/${p.slug}`,
      lastModified: p.updatedAt,
      priority: 0.7,
    })),
  ];
}

// app/robots.ts
import type { MetadataRoute } from 'next';

export default function robots(): MetadataRoute.Robots {
  return {
    rules: { userAgent: '*', allow: '/', disallow: '/admin' },
    sitemap: 'https://myapp.com/sitemap.xml',
  };
}

External links

Exercise

현재 앱에 production 체크리스트를 실행해. 가장 큰 실패 세 개를 고치고 같은 배포 SHA의 실제 URL에서 재검증해.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.