feat: serve content files via catch-all route, use content-relative cover images

This commit is contained in:
2026-06-01 23:53:28 -05:00
parent 74dfb82069
commit 8d582b6ae3
5 changed files with 46 additions and 6 deletions

View File

@@ -0,0 +1,42 @@
import { NextResponse } from 'next/server';
import { readFileSync, existsSync } from 'node:fs';
import { join } from 'node:path';
const CONTENT_DIR = join(process.cwd(), 'content');
const MIME_TYPES: Record<string, string> = {
'.jpg': 'image/jpeg',
'.jpeg': 'image/jpeg',
'.png': 'image/png',
'.gif': 'image/gif',
'.webp': 'image/webp',
'.svg': 'image/svg+xml',
'.pdf': 'application/pdf',
'.txt': 'text/plain',
'.md': 'text/plain',
'.mdx': 'text/plain',
};
export async function GET(
_request: Request,
{ params }: { params: Promise<{ path: string[] }> },
) {
const { path } = await params;
const decodedPath = decodeURIComponent(path.join('/'));
const fullPath = join(CONTENT_DIR, decodedPath);
if (!fullPath.startsWith(CONTENT_DIR) || !existsSync(fullPath)) {
return new NextResponse('Not found', { status: 404 });
}
const ext = '.' + fullPath.split('.').pop()!;
const contentType = MIME_TYPES[ext] ?? 'application/octet-stream';
const data = readFileSync(fullPath);
return new NextResponse(data, {
headers: {
'Content-Type': contentType,
'Cache-Control': 'public, max-age=31536000, immutable',
},
});
}

View File

@@ -7,7 +7,7 @@ tags:
- mathematics - mathematics
- euler - euler
- complex-numbers - complex-numbers
coverImage: /images/euler-cover.jpg coverImage: /content/posts/euler-identity/euler-cover.jpg
--- ---
Euler's identity is widely regarded as the most beautiful equation in all of mathematics: Euler's identity is widely regarded as the most beautiful equation in all of mathematics:

View File

@@ -7,7 +7,7 @@ tags:
- typescript - typescript
- programming - programming
- tutorial - tutorial
coverImage: /images/typescript-cover.jpg coverImage: /content/posts/hello-world/typescript-cover.jpg
--- ---
Welcome to this comprehensive TypeScript tutorial! Whether you are migrating a JavaScript project or starting fresh, this guide will walk you through TypeScript's type system from fundamentals to advanced patterns used in production codebases. Welcome to this comprehensive TypeScript tutorial! Whether you are migrating a JavaScript project or starting fresh, this guide will walk you through TypeScript's type system from fundamentals to advanced patterns used in production codebases.

View File

@@ -8,7 +8,7 @@ tags:
- signal-processing - signal-processing
- tutorial - tutorial
author: James Liu author: James Liu
coverImage: /images/fourier-cover.jpg coverImage: /content/posts/hybrid-post/fourier-cover.jpg
--- ---
## Fourier Analysis: From Mathematical Theory to Python Practice ## Fourier Analysis: From Mathematical Theory to Python Practice

View File

@@ -1,9 +1,7 @@
import type { NextConfig } from 'next' import type { NextConfig } from 'next'
const nextConfig: NextConfig = { const nextConfig: NextConfig = {
// Static export — generates out/ directory with plain HTML // Trailing slash for clean URLs
output: 'export',
// Trailing slash for clean static URLs
trailingSlash: true, trailingSlash: true,
// Images: unoptimized required for static export // Images: unoptimized required for static export
images: { images: {