x
This commit is contained in:
1 parent
f7aa4d099f
commit
ab3e53c4da
33 files changed
+290
-69
No files matched your search
@@ -0,0 +1,80 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
function walkDir(dir, callback) {
|
||||
fs.readdirSync(dir).forEach(f => {
|
||||
let dirPath = path.join(dir, f);
|
||||
if (fs.statSync(dirPath).isDirectory()) {
|
||||
walkDir(dirPath, callback);
|
||||
} else {
|
||||
callback(dirPath);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
walkDir('apps/website/src/app/[lang]', (filePath) => {
|
||||
if (!filePath.endsWith('.tsx') && !filePath.endsWith('.ts')) return;
|
||||
|
||||
let content = fs.readFileSync(filePath, 'utf8');
|
||||
let changed = false;
|
||||
|
||||
// 1. Convert `export const metadata = { title: '...', description: '...' }` to generateMetadata
|
||||
// We need to parse:
|
||||
// export const metadata = {
|
||||
// title: '...',
|
||||
// description: '...',
|
||||
// }
|
||||
|
||||
const metadataRegex = /export const metadata\s*(?::\s*Metadata\s*)?=\s*\{([\s\S]*?)\};?/g;
|
||||
|
||||
// Exclude layout.tsx because we'll keep its global metadata, and handle it separately.
|
||||
if (filePath.endsWith('layout.tsx')) return;
|
||||
|
||||
content = content.replace(metadataRegex, (match, body) => {
|
||||
changed = true;
|
||||
|
||||
// Extract title and description
|
||||
const titleMatch = body.match(/title:\s*['"`](.*?)['"`]/);
|
||||
const descMatch = body.match(/description:\s*['"`](.*?)['"`]/);
|
||||
|
||||
const title = titleMatch ? titleMatch[1] : '';
|
||||
const desc = descMatch ? descMatch[1] : '';
|
||||
|
||||
// Determine the route path (e.g. /shop, /about, /checkout)
|
||||
// from the filePath. e.g. apps/website/src/app/[lang]/shop/page.tsx -> /shop
|
||||
let routePath = '';
|
||||
const relPath = filePath.split('app/[lang]/')[1].replace('/page.tsx', '').replace('page.tsx', '');
|
||||
if (relPath && !relPath.includes('[') && !relPath.includes(']')) {
|
||||
routePath = '/' + relPath;
|
||||
} else if (relPath.includes('[') && relPath.includes(']')) {
|
||||
// Dynamic route, can't just use string replacement easily. We will leave it to be manually fixed or use params.
|
||||
// But wait! If it's a dynamic route, it probably already has `generateMetadata`!
|
||||
// Let's check if there are static metadata in dynamic routes.
|
||||
// Wait, `/order/[id]/page.tsx` has `generateMetadata`.
|
||||
}
|
||||
|
||||
if (relPath.includes('[')) {
|
||||
// Just fallback to empty for dynamic segments if any static metadata exists
|
||||
routePath = '';
|
||||
}
|
||||
|
||||
return `export async function generateMetadata({ params }: { params: Promise<{ lang: string }> }) {
|
||||
const { lang } = await params;
|
||||
return generateSeoMetadata({
|
||||
title: '${title}',
|
||||
description: '${desc}',
|
||||
path: '${routePath}',
|
||||
lang,
|
||||
});
|
||||
}`;
|
||||
});
|
||||
|
||||
if (changed) {
|
||||
if (!content.includes('generateSeoMetadata')) {
|
||||
// Insert import at the top
|
||||
content = `import { generateSeoMetadata } from '@/lib/seo';\n` + content;
|
||||
}
|
||||
fs.writeFileSync(filePath, content, 'utf8');
|
||||
console.log('Converted static metadata in', filePath);
|
||||
}
|
||||
});
|
||||
Reference in new issue
Block a user