Skip to content
2글자 이상 입력하세요
cloudflare으로

Serving Pages

9 min 읽기
cloudflarepagesroutingspa404cachingclean-urls

Serving Pages

Cloudflare Pages가 정적 에셋을 서빙하고 라우팅을 처리하는 방식을 설명합니다.

라우팅 규칙

기본 라우팅

Pages는 요청된 경로와 일치하는 HTML 파일을 자동으로 서빙합니다:

요청 경로서빙되는 파일
//index.html
/about/about.html 또는 /about/index.html
/blog/post/blog/post.html 또는 /blog/post/index.html

Clean URLs

Pages는 자동으로 Clean URL을 적용합니다:

/contact.html → 리다이렉트 → /contact
/about.html → 리다이렉트 → /about
/blog/post.html → 리다이렉트 → /blog/post

HTML 확장자가 있는 URL로 접근하면 확장자가 없는 URL로 자동 리다이렉트됩니다.

디렉토리 인덱스

디렉토리의 index.html은 해당 디렉토리 경로로 서빙됩니다:

/blog/index.html → /blog/ 또는 /blog
/docs/guide/index.html → /docs/guide/ 또는 /docs/guide

404 에러 처리

기본 404 페이지

프로젝트 루트에 404.html 파일을 생성하면 커스텀 404 페이지로 사용됩니다:

dist/
├── index.html
├── about.html
└── 404.html ← 커스텀 404 페이지

계층적 404 페이지

Pages는 디렉토리 구조를 따라 가장 가까운 404 페이지를 찾습니다:

dist/
├── index.html
├── 404.html ← 기본 404 페이지
├── blog/
│ ├── index.html
│ └── 404.html ← /blog/* 요청용 404 페이지
└── docs/
├── index.html
└── 404.html ← /docs/* 요청용 404 페이지

404 페이지 매칭 순서:

  1. /blog/unknown 요청 시 → /blog/404.html 확인
  2. 없으면 → /404.html 확인
  3. 없으면 → 기본 Pages 404 페이지

섹션별 404 예시

/blog/404.html
<!DOCTYPE html>
<html>
<head>
<title>블로그 글을 찾을 수 없습니다</title>
</head>
<body>
<h1>블로그 글을 찾을 수 없습니다</h1>
<p>요청하신 블로그 글이 존재하지 않습니다.</p>
<a href="/blog">블로그 목록으로 돌아가기</a>
</body>
</html>

Single-Page Application (SPA) 모드

SPA 모드 활성화

루트 레벨에 404.html이 없으면, Pages는 SPA 프레임워크(React, Vue, Angular 등)로 가정하고 SPA 모드를 활성화합니다.

SPA 모드에서는:

SPA 프로젝트 구조

dist/
├── index.html ← 모든 경로에서 이 파일 서빙
├── assets/
│ ├── app.js
│ └── style.css
└── (404.html 없음) ← SPA 모드 활성화

SPA 모드 비활성화

SPA 모드를 비활성화하려면 루트에 404.html을 추가합니다:

dist/
├── index.html
├── 404.html ← SPA 모드 비활성화
└── assets/

SPA vs 정적 사이트

기능SPA 모드정적 사이트 모드
404.html없음있음
알 수 없는 경로index.html 반환404.html 반환
라우팅클라이언트 사이드서버 사이드
SEO추가 설정 필요기본 지원

캐싱

자동 캐싱

Pages는 최적의 신선도를 위해 자동 캐싱을 적용합니다:

캐시 동작

첫 번째 요청:
GET /assets/app.js
Response: 200 OK
ETag: "abc123"
두 번째 요청 (캐시 검증):
GET /assets/app.js
If-None-Match: "abc123"
Response: 304 Not Modified (본문 없음)

커스텀 도메인에서의 캐싱

주의: 커스텀 도메인에서 별도의 캐싱 설정을 추가하지 마세요.

커스텀 캐싱이 문제를 일으킬 수 있는 경우:

Pages의 기본 캐싱 전략을 그대로 사용하는 것을 권장합니다.

기본 HTTP 헤더

Pages는 모든 응답에 다음 헤더를 자동으로 포함합니다:

보안 헤더

X-Content-Type-Options: nosniff

MIME 타입 스니핑을 방지합니다.

CORS 헤더

Access-Control-Allow-Origin: *

모든 출처에서의 리소스 접근을 허용합니다.

캐시 헤더

Cache-Control: public, max-age=0, must-revalidate
ETag: "hash-value"

콘텐츠 타입

Content-Type: text/html; charset=utf-8
Content-Type: application/javascript
Content-Type: text/css

파일 확장자에 따라 적절한 MIME 타입이 설정됩니다.

에셋 서빙

정적 에셋

다음 파일들은 자동으로 적절한 Content-Type과 함께 서빙됩니다:

확장자Content-Type
.htmltext/html
.csstext/css
.jsapplication/javascript
.jsonapplication/json
.pngimage/png
.jpg, .jpegimage/jpeg
.svgimage/svg+xml
.woff2font/woff2
.pdfapplication/pdf

압축

Pages는 자동으로 응답을 압축합니다:

클라이언트의 Accept-Encoding 헤더에 따라 적절한 압축 방식이 선택됩니다.

실전 구성 예시

Astro 정적 사이트

dist/
├── index.html
├── about/
│ └── index.html
├── blog/
│ ├── index.html
│ ├── post-1/
│ │ └── index.html
│ └── post-2/
│ └── index.html
├── 404.html
└── _astro/
├── app.abc123.js
└── style.def456.css

React SPA

dist/
├── index.html ← 모든 라우트의 진입점
├── static/
│ ├── js/
│ │ └── main.js
│ └── css/
│ └── main.css
└── assets/
└── images/

Next.js 정적 내보내기

out/
├── index.html
├── about.html
├── blog/
│ ├── index.html
│ └── [slug].html
├── 404.html
├── _next/
│ └── static/
└── images/

문제 해결

404가 예상대로 동작하지 않음

  1. SPA 모드 확인: 루트에 404.html이 있는지 확인
  2. 파일 위치 확인: 빌드 출력에 404.html이 포함되었는지 확인
  3. 계층 구조 확인: 섹션별 404 페이지의 경로가 올바른지 확인

Clean URL이 작동하지 않음

  1. 파일 구조 확인: .html 파일이 올바른 위치에 있는지 확인
  2. 리다이렉트 충돌: _redirects 파일의 규칙이 충돌하지 않는지 확인

캐시 문제

  1. 브라우저 캐시 삭제: 개발 중에는 하드 리프레시 (Ctrl+Shift+R)
  2. 배포 확인: 새 배포가 완료되었는지 확인
  3. 커스텀 캐시 규칙 제거: 커스텀 도메인의 추가 캐시 설정 제거

SPA 라우팅 문제

  1. 404.html 제거: SPA 모드를 위해 루트 404.html 삭제
  2. base URL 확인: 프레임워크의 base URL 설정 확인
  3. 정적 에셋 경로: 에셋이 절대 경로를 사용하는지 확인

출처: Cloudflare Pages - Serving Pages


이전 글

Redirects

다음 글

Wrangler CLI