How to Return 410 Gone on Cloudflare Pages (The _redirects Gotcha

작성자

카테고리:

← 피드로
DEV Community · Junyi Zhang · 2026-07-28 개발(SW)

Junyi Zhang

Background

I registered a domain for a new project. Shortly after launch, Google Search Console started flooding with mysterious 404 errors — URLs like /post/xxx and /category-xxx, the classic WordPress path patterns. Turns out the domain had a previous owner who ran a WordPress site, and Google still had those old pages indexed.

When search engines see 404s on old URLs, they keep retrying. Better to tell them unequivocally: “This content is gone for good” — that’s what 410 Gone is for.

The Pitfall: _redirects Only Supports 3xx

My first instinct was to add rules to _redirects:

/post/*    410
/category-*    410

Enter fullscreen mode Exit fullscreen mode

Deployed it. Nothing happened — those URLs still returned 404.

After digging into the Cloudflare Pages docs, the answer emerged: _redirects only supports five status codes — 301, 302, 303, 307, and 308. Writing 410 gets silently ignored. No warning, no error, nothing.

As a bonus facepalm: my test 301 redirect wasn’t working either, because I had the format backwards:

/test-redirect  301  /     ← Wrong: destination and status code are swapped
/test-redirect  /  301     ← Correct: source → destination → status code

Enter fullscreen mode Exit fullscreen mode

The Fix: Cloudflare Pages Functions

Use a Cloudflare Pages Function as middleware. Create functions/[[path]].js at the project root:

// Intercept old WordPress URLs, return 410 Gone
// Pass everything else through to static assets

const GONE_PATTERNS = [
  /^\/post\//,
  /^\/category-/,
  /^\/author-/,
  /^\/page_/,
  /^\/date-/,
];

const GONE_EXACT = [
  '/.IGV0hOcNusVJOgqoD1HuWTk0PssdueKB',
];

export async function onRequest(context) {
  const { pathname } = new URL(context.request.url);

  if (GONE_PATTERNS.some((p) => p.test(pathname))
      || GONE_EXACT.includes(pathname)) {
    return new Response('410 Gone — This content has been permanently removed.', {
      status: 410,
      headers: { 'Content-Type': 'text/plain; charset=utf-8' },
    });
  }

  return context.next();
}

Enter fullscreen mode Exit fullscreen mode

  • Matches old WordPress URL patterns → returns 410
  • Everything else → context.next() passes through to static assets with zero overhead

Deployment

Place the functions/ directory at the project root (not inside src/ or public/). Cloudflare Pages auto-detects it and enables the Functions runtime — no extra configuration needed.

✨ Uploading _redirects
✨ Uploading Functions bundle

Enter fullscreen mode Exit fullscreen mode

Verification

$ curl -s -o /dev/null -w "HTTP %{http_code}" https://example.com/post/hello-world
HTTP 410

$ curl -s -o /dev/null -w "HTTP %{http_code}" https://example.com/category-tech
HTTP 410

$ curl -s -o /dev/null -w "HTTP %{http_code}" https://example.com/
HTTP 200

Enter fullscreen mode Exit fullscreen mode

TL;DR

Need Solution 3xx redirects _redirects file 4xx / 5xx status codes Cloudflare Pages Functions Complex routing (rate limiting, auth, etc.) Functions or Workers

This was a real-world pitfall encountered while building BGM Box, a free online BRSTM converter and player for Nintendo game audio. Convert 100+ formats (MP3, WAV, OGG, FLAC, ADX, HCA, FSB, WEM…) to BRSTM, BCSTM, and BFSTM — all in your browser with no sign-up and no file uploads. Give it a try!

원문에서 계속 ↗

코멘트

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다