feat: serve content files via catch-all route, use content-relative cover images
This commit is contained in:
42
app/content/[...path]/route.ts
Normal file
42
app/content/[...path]/route.ts
Normal 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',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -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:
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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: {
|
||||||
|
|||||||
Reference in New Issue
Block a user