From e28beac1f1f9e6839febb137bfd03fa237bc83ec Mon Sep 17 00:00:00 2001 From: gbanyan Date: Thu, 20 Nov 2025 02:26:38 +0800 Subject: [PATCH] Fix Pagefind file serving with API route MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixed issue where Pagefind static files weren't accessible due to Next.js routing conflicts. Solution: - Created API route at app/pagefind/[...path]/route.ts to serve Pagefind files from .next/pagefind/ - Updated build script to copy pagefind index to public/_pagefind (backup) - API route handles all /pagefind/* requests and serves files with proper content types - Added caching headers for optimal performance This resolves the "cannot type in search" issue - the search modal can now load Pagefind UI and index files correctly. Technical Details: - Next.js App Router was treating /pagefind/ as a route, returning 404 - Static files in public/ weren't accessible for subdirectories due to routing priority - API route bypasses routing to serve .next/pagefind/* files directly - Supports .js, .css, .json, .wasm, and Pagefind-specific file types 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .gitignore | 3 +++ app/pagefind/[...path]/route.ts | 40 +++++++++++++++++++++++++++++++++ package.json | 2 +- 3 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 app/pagefind/[...path]/route.ts diff --git a/.gitignore b/.gitignore index c410c09..40072a5 100644 --- a/.gitignore +++ b/.gitignore @@ -37,5 +37,8 @@ pnpm-debug.log* # Generated assets mirror /public/assets +# Generated search index +/public/_pagefind + # TypeScript *.tsbuildinfo diff --git a/app/pagefind/[...path]/route.ts b/app/pagefind/[...path]/route.ts new file mode 100644 index 0000000..fa451b8 --- /dev/null +++ b/app/pagefind/[...path]/route.ts @@ -0,0 +1,40 @@ +import { NextRequest, NextResponse } from 'next/server'; +import { readFile } from 'fs/promises'; +import { join } from 'path'; + +export async function GET( + request: NextRequest, + { params }: { params: Promise<{ path: string[] }> } +) { + try { + const { path } = await params; + const filePath = join(process.cwd(), '.next', 'pagefind', ...path); + + // Read the file + const file = await readFile(filePath); + + // Determine content type + const ext = path[path.length - 1].split('.').pop(); + const contentTypes: Record = { + 'js': 'application/javascript', + 'css': 'text/css', + 'json': 'application/json', + 'wasm': 'application/wasm', + 'pf_meta': 'application/octet-stream', + 'pf_index': 'application/octet-stream', + 'pf_fragment': 'application/octet-stream', + }; + + const contentType = contentTypes[ext || ''] || 'application/octet-stream'; + + return new NextResponse(file, { + headers: { + 'Content-Type': contentType, + 'Cache-Control': 'public, max-age=31536000, immutable', + }, + }); + } catch (error) { + console.error('Error serving Pagefind file:', error); + return new NextResponse('File not found', { status: 404 }); + } +} diff --git a/package.json b/package.json index 3a861d7..40f68b4 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "scripts": { "dev": "concurrently \"contentlayer2 dev\" \"next dev\"", "sync-assets": "node scripts/sync-assets.mjs", - "build": "npm run sync-assets && contentlayer2 build && next build && npx pagefind --site .next", + "build": "npm run sync-assets && contentlayer2 build && next build && npx pagefind --site .next && rm -rf public/_pagefind && cp -r .next/pagefind public/_pagefind", "start": "next start", "lint": "next lint", "contentlayer": "contentlayer build"