GitHub Pages에 Nuxt.js로 개발된 정적 사이트를 배포할 때, 자산(Asset) 경로가 깨지는 문제는 흔히 발생하는 문제입니다. 이는 주로 GitHub Pages가 저장소 이름을 포함하는 서브 경로(예: username.github.io/repository-name/)로 사이트를 제공하기 때문에 발생합니다. Nuxt.js 프로젝트의 nuxt.config.ts 파일에서 app.baseURL 설정을 올바르게 지정함으로써 이 문제를 해결할 수 있습니다.

원인: GitHub Pages의 서브 경로 문제

GitHub Pages는 크게 두 가지 방식으로 웹사이트를 호스팅합니다.

  1. 사용자/조직 페이지: username.github.io 또는 organization.github.io와 같이 루트 도메인에서 직접 호스팅됩니다.
  2. 프로젝트 페이지: username.github.io/repository-name/과 같이 저장소 이름을 포함하는 서브 경로에서 호스팅됩니다.

Nuxt.js와 같은 정적 사이트 생성기는 기본적으로 자산 경로를 웹사이트의 루트(/)를 기준으로 생성합니다. 예를 들어, assets/image.png/assets/image.png로 빌드됩니다. 사용자/조직 페이지에서는 이 경로가 올바르게 작동하지만, 프로젝트 페이지에서는 실제 경로가 /repository-name/assets/image.png여야 합니다. repository-name이 누락되면서 브라우저는 자산을 찾지 못해 "404 Not Found" 오류를 발생시키고, 결과적으로 사이트의 스타일이나 기능이 깨지게 됩니다.

Nuxt.js에서 자산 경로 설정하기

Nuxt.js 3에서는 nuxt.config.ts 파일의 app.baseURL 옵션을 사용하여 모든 자산(이미지, CSS, JavaScript 등) 및 클라이언트 측 라우팅의 기본 경로를 지정할 수 있습니다. 이 값을 GitHub 저장소 이름과 동일하게 설정하면 GitHub Pages의 서브 경로 문제를 해결할 수 있습니다.

app.baseURL은 Nuxt 애플리케이션의 모든 상대 경로(자산, 라우팅)에 적용되는 기본 URL을 정의합니다. ssr: false와 함께 사용하면 정적 사이트 배포 시 경로 문제가 효과적으로 해결됩니다.

nuxt.config.ts 수정 예시

아래 예시에서는 d-korea-law라는 저장소 이름을 사용합니다. 실제 프로젝트에서는 '/d-korea-law/' 부분을 본인의 GitHub 저장소 이름으로 변경해야 합니다.

// nuxt.config.ts
import { defineNuxtConfig } from 'nuxt'

// 배포 환경에 따라 baseURL을 다르게 설정합니다.
// NODE_ENV가 'production'일 경우 GitHub Pages 저장소 이름을 사용하고,
// 그 외의 경우 (예: 개발 환경)에는 루트 경로를 사용합니다.
const isProduction = process.env.NODE_ENV === 'production'
const githubRepoName = '/d-korea-law/' // 본인의 GitHub 저장소 이름으로 변경하세요 (예: '/my-project-name/')
const baseURL = isProduction ? githubRepoName : '/'

export default defineNuxtConfig({
  // SSR(서버 사이드 렌더링)을 비활성화하여 정적 사이트로 빌드합니다.
  // GitHub Pages와 같은 정적 호스팅 환경에 적합합니다.
  ssr: false,

  app: {
    // 애플리케이션의 모든 자산(이미지, CSS, JS) 및 클라이언트 측 라우팅의 기본 URL을 설정합니다.
    // GitHub Pages의 서브 경로를 반영하여 자산 및 라우팅 경로가 올바르게 로드되도록 합니다.
    baseURL: baseURL,
    // head: {
    //   // <base href="..."> 태그를 설정하여 모든 상대 URL의 기준을 변경할 수 있으나,
    //   // Nuxt 3에서는 `app.baseURL` 설정이 더 권장되고 효과적입니다.
    // }
  },

  // Nuxt 3에서는 `ssr: false`와 `nuxt build` 명령으로 정적 파일을 생성합니다.
  // `output.publicDir` 등의 설정은 빌드 결과물의 위치를 정의할 때 사용됩니다.
  // `_nuxt` 폴더 등의 자산 경로가 `baseURL`에 따라 올바르게 생성됩니다.

  // 기타 Nuxt 설정 (예: CSS, 모듈 등)은 필요에 따라 추가합니다.
  css: ['~/assets/css/main.scss'], // 예시: 전역 CSS 파일 경로
  // modules: [],
  // plugins: [],
  // build: {},
})

빌드 및 배포

nuxt.config.ts 파일 수정 후, 다음 단계를 통해 프로젝트를 빌드하고 배포합니다.

  1. 프로젝트 빌드: 터미널에서 다음 명령어를 실행하여 정적 파일을 생성합니다.

    npm run build
    # 또는 pnpm run build, yarn build, bun run build
    

    이 명령어를 실행하면 기본적으로 프로젝트 루트에 .output/public (또는 dist 등) 폴더가 생성되며, 이 안에 배포 가능한 정적 파일들이 포함됩니다.

  2. GitHub Pages 배포: 생성된 .output/public 폴더의 내용을 GitHub Pages 배포 브랜치(일반적으로 gh-pages 브랜치 또는 main 브랜치의 /docs 폴더)에 업로드합니다.

    • 수동 배포: .output/public 내용을 복사하여 배포 브랜치에 커밋하고 푸시합니다.
    • GitHub Actions: .github/workflows/deploy.yml 파일에서 빌드 후 .output/public 폴더를 GitHub Pages로 배포하도록 설정할 수 있습니다. actions/upload-pages-artifactactions/deploy-pages 액션을 활용하면 자동화된 배포 파이프라인을 구축할 수 있습니다.

흔히 하는 실수 및 주의점

  • 저장소 이름 오타: baseURL에 설정하는 저장소 이름이 GitHub 저장소 이름과 정확히 일치해야 합니다. 대소문자도 구분하니 주의하십시오.
  • 배포 브랜치 확인: GitHub 저장소 설정(Settings > Pages)에서 올바른 브랜치(예: gh-pages 또는 main 브랜치의 /docs 폴더)를 소스로 선택했는지 확인해야 합니다.
  • 환경 변수 활용: 여러 환경에서 다른 baseURL을 사용해야 할 경우, process.env.NUXT_APP_BASE_URL과 같은 환경 변수를 사용하여 유연하게 관리하는 것이 좋습니다. 예를 들어, package.json 스크립트에서 NUXT_APP_BASE_URL=/your-repo/ npm run build와 같이 설정할 수 있습니다.
  • Nuxt 버전: 이 가이드는 Nuxt 3를 기준으로 작성되었습니다. Nuxt 2에서는 router.base 옵션을 주로 사용했습니다. 사용하는 Nuxt 버전에 따라 설정 방식에 약간의 차이가 있을 수 있으니 공식 문서를 참고하는 것이 좋습니다.