Fix search on Vercel by serving Pagefind as static files

The previous approach using an API route to serve Pagefind files
doesn't work on Vercel's serverless environment because fs.readFile
can't reliably access files in the deployed output.

Solution: Serve Pagefind files directly from public/_pagefind as
static assets, which is the standard Next.js approach and works
reliably on all deployment platforms.

Changes:
- Update search modal to load from /_pagefind/ instead of /pagefind/
- Remove app/pagefind/[...path]/route.ts API route (no longer needed)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-20 16:46:10 +08:00
parent a7aa930759
commit 854c5a1097
2 changed files with 3 additions and 43 deletions

View File

@@ -1,40 +0,0 @@
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(), 'public', '_pagefind', ...path);
// Read the file
const file = await readFile(filePath);
// Determine content type
const ext = path[path.length - 1].split('.').pop();
const contentTypes: Record<string, string> = {
'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 });
}
}

View File

@@ -32,17 +32,17 @@ export function SearchModal({ isOpen, onClose }: SearchModalProps) {
// Load Pagefind UI CSS // Load Pagefind UI CSS
link = document.createElement('link'); link = document.createElement('link');
link.rel = 'stylesheet'; link.rel = 'stylesheet';
link.href = '/pagefind/pagefind-ui.css'; link.href = '/_pagefind/pagefind-ui.css';
document.head.appendChild(link); document.head.appendChild(link);
// Load Pagefind UI JS // Load Pagefind UI JS
script = document.createElement('script'); script = document.createElement('script');
script.src = '/pagefind/pagefind-ui.js'; script.src = '/_pagefind/pagefind-ui.js';
script.onload = () => { script.onload = () => {
if (searchContainerRef.current && (window as any).PagefindUI) { if (searchContainerRef.current && (window as any).PagefindUI) {
pagefindUIRef.current = new (window as any).PagefindUI({ pagefindUIRef.current = new (window as any).PagefindUI({
element: searchContainerRef.current, element: searchContainerRef.current,
bundlePath: '/pagefind/', bundlePath: '/_pagefind/',
showSubResults: true, showSubResults: true,
showImages: false, showImages: false,
excerptLength: 15, excerptLength: 15,