1. 문제의 원인: GitHub Pages의 서브 경로 배포
GitHub Pages는 보통 username.github.io 또는 organization.github.io와 같은 도메인 루트에 배포되거나, 특정 저장소의 경우 username.github.io/repository-name/과 같은 서브 경로에 배포됩니다. Next.js의 output: 'export' 기능을 사용하여 정적 사이트를 빌드하면, 기본적으로 모든 자산 경로가 애플리케이션의 루트(/)를 기준으로 생성됩니다.
예를 들어, public/images/logo.png 파일은 빌드 후 HTML에서 /images/logo.png로 참조될 것입니다. 하지만 이 사이트가 username.github.io/my-repo/ 경로에 배포되면, 브라우저는 username.github.io/images/logo.png에서 자산을 찾으려 시도하여 404 에러를 발생시키고 이미지가 깨지는 현상이 나타납니다.
2. 해결 방법: basePath 설정 (Next.js 기준)
Next.js는 이러한 서브 경로 배포 환경을 지원하기 위해 basePath 설정을 제공합니다. next.config.js 파일에 basePath를 저장소 이름과 동일하게 설정하면, Next.js는 내부적으로 모든 라우팅 및 자산 경로를 이 basePath에 맞춰 재작성합니다.
next.config.js 파일을 다음과 같이 수정하세요:
/** @type {import('next').NextConfig} */
const nextConfig = {
output: 'export', // 정적 HTML 파일로 내보내기 위해 필요
basePath: '/frame-pick', // GitHub 저장소 이름과 동일하게 설정
images: {
unoptimized: true, // Next.js Image 컴포넌트를 정적 내보내기에서 사용하려면 필요
},
// 기타 Next.js 설정...
};
module.exports = nextConfig;
여기서 basePath는 배포될 GitHub 저장소의 이름(예: HDomi/frame-pick의 경우 /frame-pick)과 일치해야 합니다. unoptimized: true는 next/image 컴포넌트를 사용하는 경우 정적 사이트에서 이미지 최적화 기능을 비활성화하고 이미지가 올바르게 로드되도록 합니다.
3. 코드 내 자산 경로 수정
basePath를 설정했더라도, public 폴더 내의 자산을 코드에서 직접 참조할 때는 수동으로 basePath를 경로에 추가해야 합니다. Next.js는 public 폴더 내의 파일에 대해 basePath를 자동으로 접두사로 붙여주지 않습니다.
이를 위해 process.env.NEXT_PUBLIC_BASE_PATH와 같은 환경 변수를 활용하는 것이 좋습니다. next.config.js에 설정한 basePath 값을 NEXT_PUBLIC_BASE_PATH 환경 변수로 노출할 수 있습니다.
예를 들어, public/stickers/arrow.svg 파일을 로드하는 경우:
// next.config.js에 basePath가 '/frame-pick'으로 설정되어 있다고 가정
// 1. 환경 변수를 통해 basePath를 동적으로 가져와 사용
const BASE_PATH = process.env.NEXT_PUBLIC_BASE_PATH || ''; // 기본값 설정
// 2. Fabric.js의 loadSVGFromURL 함수를 사용하여 SVG 로드
// 'loadSVGFromURL'과 같이 직접 URL을 지정하는 경우 basePath를 명시적으로 포함해야 합니다.
fabric.loadSVGFromURL(`${BASE_PATH}/stickers/arrow.svg`, (objects, options) => {
const svg = fabric.util.groupSVGElements(objects, options);
// 캔버스에 SVG 추가 또는 다른 작업 수행
canvas.add(svg).renderAll();
});
// 3. 일반적인 이미지 태그나 CSS 배경 이미지 경로 설정 시
// <img src={`${BASE_PATH}/images/my-logo.png`} alt="Logo" />
// 혹은 CSS: background-image: url('${BASE_PATH}/styles/background.jpg');
Next.js의 Image 컴포넌트는 basePath가 설정되어 있으면 자동으로 처리하는 경우가 많지만, public 폴더의 자산에 대한 직접적인 <img> 태그나 CSS url() 참조, 그리고 Fabric.js의 loadSVGFromURL과 같이 JavaScript에서 동적으로 로드하는 경우에는 위와 같이 basePath를 포함하여 경로를 구성해야 합니다.
4. 배포 워크플로우 수정 (선택 사항)
GitHub Actions를 사용하여 배포하는 경우, .github/workflows/deploy.yml 파일에서 NEXT_PUBLIC_BASE_PATH 환경 변수를 설정하여 빌드 시점에 basePath를 주입할 수 있습니다. 이는 next.config.js에서 basePath를 직접 설정하는 것과 별개로, 코드 내에서 process.env.NEXT_PUBLIC_BASE_PATH를 사용할 때 유용합니다.
# .github/workflows/deploy.yml 예시
name: Deploy to GitHub Pages
on:
push:
branches:
- main
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20 # 또는 프로젝트에 맞는 Node.js 버전
cache: 'pnpm'
- name: Install dependencies
run: pnpm install
- name: Build project
run: pnpm build
env:
NEXT_PUBLIC_BASE_PATH: /frame-pick # 여기에 저장소 이름 명시
# 기타 필요한 환경 변수...
- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v3
if: ${{ github.ref == 'refs/heads/main' }}
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./out # Next.js static export의 기본 출력 디렉토리
# 기타 배포 설정...
5. 확인 방법
배포 후 웹 브라우저의 개발자 도구(F12)를 열어 "Network" 탭을 확인하세요. 깨졌던 자산들이 올바른 경로(예: username.github.io/frame-pick/images/logo.png)로 요청되고 200 OK 응답을 받는지 확인합니다. CSS 파일이나 JavaScript 콘솔에 경로 관련 오류가 없는지도 함께 확인하면 좋습니다.
6. 흔히 하는 실수 및 주의점
basePath오타:next.config.js의basePath값이 GitHub 저장소 이름과 정확히 일치하는지 확인하세요. 대소문자도 중요합니다.- 캐싱 문제: 배포 후에도 자산 경로가 깨져 보인다면, 브라우저 캐시를 지우거나 시크릿 모드(InPrivate)로 접속하여 확인해보세요. CDN을 사용하는 경우 CDN 캐시를 무효화해야 할 수도 있습니다.
next/image컴포넌트:output: 'export'와 함께next/image를 사용하는 경우,next.config.js에images: { unoptimized: true }를 반드시 추가해야 합니다. 이 설정을 누락하면 이미지가 로드되지 않을 수 있습니다.- 절대 경로 사용:
basePath를 설정한 후에는public폴더의 자산을 참조할 때./image.png와 같은 상대 경로보다는/${process.env.NEXT_PUBLIC_BASE_PATH}/image.png와 같은 절대 경로를 사용하는 것이 일관성과 안정성을 높이는 데 도움이 됩니다. - 다른 프레임워크: Next.js가 아닌 다른 정적 사이트 생성기(예: Gatsby, Astro, Vite 등)를 사용하는 경우, 각 프레임워크가 제공하는
basePath또는publicPath와 같은 유사한 설정을 찾아 적용해야 합니다. 환경에 따라 설정 방식이 다를 수 있으니 해당 프레임워크의 문서를 확인하는 것이 중요합니다.