본문으로 건너뛰기

TanStack Router를 프로덕션에 배포하는 방법

이 가이드에서는 널리 사용되는 호스팅 플랫폼에 TanStack Router 애플리케이션을 배포하는 방법을 설명합니다.

빠른 시작

단일 페이지 애플리케이션(SPA)은 클라이언트 측 라우팅을 처리하기 위해 특별한 서버 구성이 필요합니다. 모든 라우트에 index.html을 제공하도록 호스팅 플랫폼을 구성하면 TanStack Router가 내비게이션을 처리할 수 있습니다.


Netlify 배포

1. _redirects 파일 만들기

public/_redirects 파일(또는 빌드 출력 디렉터리의 _redirects 파일)을 만듭니다.

/*    /index.html   200

2. 대안: netlify.toml

프로젝트 루트에 netlify.toml 파일을 만듭니다.

[[redirects]]
from = "/*"
to = "/index.html"
status = 200

[build]
publish = "dist"
command = "npm run build"

3. TanStack Start(SSR)의 경우

[build]
publish = ".output/public"
command = "npm run build"

[functions]
directory = ".output/server"

[[redirects]]
from = "/api/*"
to = "/.netlify/functions/server"
status = 200

[[redirects]]
from = "/*"
to = "/index.html"
status = 200

Cloudflare Pages

1. _redirects 파일 만들기

public/_redirects 파일을 만듭니다.

/*    /index.html   200

2. 대안: _routes.json

더 세밀하게 제어하려면 public/_routes.json 파일을 만듭니다.

{
"version": 1,
"include": ["/*"],
"exclude": ["/api/*"]
}

3. TanStack Start(SSR)의 경우

SSR을 지원하도록 functions/_middleware.ts를 만듭니다.

export const onRequest: PagesFunction = async (context) => {
// Handle SSR requests
return await handleSSR(context)
}

4. Git으로 배포

  1. GitHub 저장소를 Cloudflare Pages에 연결합니다.
  2. 빌드 설정을 지정합니다.
    • 빌드 명령: npm run build
    • 빌드 출력 디렉터리: dist
    • 루트 디렉터리: (비워 둡니다)

5. Wrangler CLI로 배포

# Install Wrangler
npm install -g wrangler

# Deploy
wrangler pages publish dist --project-name=my-app

Vercel 배포

1. vercel.json 만들기

프로젝트 루트에 vercel.json 파일을 만듭니다.

{
"rewrites": [
{
"source": "/(.*)",
"destination": "/index.html"
}
]
}

2. TanStack Start(SSR) 애플리케이션의 경우

SSR과 함께 TanStack Start를 사용한다면 다음 구성을 대신 사용합니다.

{
"functions": {
"app/server.ts": {
"runtime": "nodejs18.x"
}
},
"routes": [
{
"src": "/(.*)",
"dest": "/api/server"
}
]
}

3. 빌드 구성

package.json에 올바른 빌드 스크립트가 있는지 확인합니다.

{
"scripts": {
"build": "vite build",
"preview": "vite preview"
}
}

4. 배포

# Install Vercel CLI
npm i -g vercel

# Deploy
vercel

GitHub Pages

1. 404.html 만들기

GitHub Pages에는 index.html을 복제한 404.html 파일이 필요합니다.

# After building
cp dist/index.html dist/404.html

2. vite.config.js 업데이트

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { tanstackRouter } from '@tanstack/router-plugin/vite'

export default defineConfig({
base: '/your-repo-name/', // Replace with your repository name
plugins: [
tanstackRouter({
target: 'react',
autoCodeSplitting: true,
}),
react(),
],
build: {
outDir: 'dist',
},
})

3. GitHub Actions 워크플로

.github/workflows/deploy.yml을 만듭니다.

name: Deploy to GitHub Pages

on:
push:
branches: [main]

jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3

- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
cache: 'npm'

- name: Install dependencies
run: npm ci

- name: Build
run: npm run build

- name: Create 404.html
run: cp dist/index.html dist/404.html

- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./dist

Firebase Hosting

1. firebase.json 만들기

{
"hosting": {
"public": "dist",
"ignore": ["firebase.json", "**/.*", "**/node_modules/**"],
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
]
}
}

2. 배포

# Install Firebase CLI
npm install -g firebase-tools

# Login and initialize
firebase login
firebase init hosting

# Build and deploy
npm run build
firebase deploy

Apache 서버

빌드 출력 디렉터리에 .htaccess 파일을 만듭니다.

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]
</IfModule>

Nginx

Nginx 서버 블록에 다음 구성을 추가합니다.

server {
listen 80;
server_name your-domain.com;
root /path/to/your/dist;
index index.html;

location / {
try_files $uri $uri/ /index.html;
}

# Optional: Cache static assets
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
}

Docker 배포

1. Dockerfile 만들기

# Build stage
FROM node:18-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

# Production stage
FROM nginx:alpine
COPY --from=build /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

2. nginx.conf 만들기

server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
index index.html;

location / {
try_files $uri $uri/ /index.html;
}
}

3. 빌드 및 실행

docker build -t my-tanstack-app .
docker run -p 80:80 my-tanstack-app

프로덕션 체크리스트

배포하기 전에 다음 항목을 확인합니다.

  • 호스팅 플랫폼 구성 파일을 만들었는지 확인합니다.
  • 하위 디렉터리에 배포한다면 올바른 base path를 설정했는지 확인합니다.
  • VITE_ 접두사를 사용해 환경 변수를 구성했는지 확인합니다.
  • 직접 URL에 접근해 모든 라우트를 테스트했는지 확인합니다.
  • 정적 애셋이 올바르게 로드되는지 확인합니다.

일반적인 문제

페이지 새로 고침 시 404 오류

문제: 앱 내부에서 이동할 때는 라우트가 작동하지만 페이지를 새로 고치면 404가 표시됩니다.

원인: 서버가 SPA에 존재하지 않는 /about/index.html과 같은 파일을 찾습니다.

해결 방법: 호스팅 플랫폼에 맞게 위에 설명한 구성 파일을 추가합니다.

로컬에서는 작동하지만 배포하면 앱이 중단됨

문제: 개발 환경에서는 앱이 작동하지만 프로덕션에서 오류가 표시됩니다.

해결 방법:

  • 하위 디렉터리 배포: vite.config.js에서 base path를 구성합니다.
    export default defineConfig({
    base: '/my-app/', // Match your deployment path
    })
  • 빌드 출력 불일치: 빌드 디렉터리가 호스팅 구성과 일치하는지 확인합니다.
    export default defineConfig({
    build: {
    outDir: 'dist', // Must match hosting platform setting
    },
    })
  • 환경 변수: VITE_를 접두사로 추가하고 다시 빌드합니다.
    # .env
    VITE_API_URL=https://api.example.com

애셋이 로드되지 않음(CSS/JS 404)

문제: 앱은 로드되지만 스타일이 깨지거나 JavaScript를 로드하지 못합니다.

해결 방법:

  • 호스팅 구성에서 빌드 출력 디렉터리를 확인합니다.
  • Vite의 public path 구성을 확인합니다.
  • 정적 파일 제공이 올바르게 구성되었는지 확인합니다.

일반적인 다음 단계

배포 후 다음 작업을 수행할 수 있습니다.