Skip to content

Commit 9ffd06b

Browse files
alchaincyfclaude
andcommitted
fix(seo): sitemap全是undefined、域名写错;固定Node 22构建
- sitemap返回的是字符串数组,Next.js要的是{url}对象,所以每条都是undefined; 同时改成收全部嵌套教程页(原来只取第一层目录) - og:url、JSON-LD、sitemap、robots里的域名写成了别人家的codewithai.com,统一改成www.coderwithai.top - 教程页加canonical,www和裸域都能打开时收口到www - Vercel已停止支持Node 20,项目设置还是20.x,构建直接失败;用engines固定22.x(同Bookai做法) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent 5105892 commit 9ffd06b

6 files changed

Lines changed: 41 additions & 22 deletions

File tree

‎app/[language]/[...tutorial]/page.tsx‎

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,18 @@ export async function generateMetadata(
2828
title,
2929
description: metadata.description,
3030
keywords: metadata.keywords,
31+
alternates: {
32+
// www 和裸域都能打开,用 canonical 收口到 www
33+
canonical: `https://www.coderwithai.top/${language}/${tutorialPath}`,
34+
},
3135
openGraph: {
3236
title,
3337
description: metadata.description,
34-
url: `https://www.codewithai.com/${language}/${tutorialPath}`,
38+
url: `https://www.coderwithai.top/${language}/${tutorialPath}`,
3539
siteName: 'CoderWithAI',
3640
images: [
3741
{
38-
url: metadata.image || 'https://www.codewithai.com/images/default-og-image.jpg',
42+
url: metadata.image || 'https://www.coderwithai.top/images/default-og-image.jpg',
3943
width: 1200,
4044
height: 630,
4145
},
@@ -48,7 +52,7 @@ export async function generateMetadata(
4852
card: 'summary_large_image',
4953
title,
5054
description: metadata.description,
51-
images: [metadata.image || 'https://www.codewithai.com/images/default-twitter-image.jpg'],
55+
images: [metadata.image || 'https://www.coderwithai.top/images/default-twitter-image.jpg'],
5256
},
5357
}
5458
}

‎app/layout.tsx‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,11 @@ export const metadata: Metadata = {
2929
openGraph: {
3030
title: "CoderWithAI - 学习编程的最佳资源",
3131
description: "全面的编程教程和交互式学习平台",
32-
url: "https://www.codewithai.com",
32+
url: "https://www.coderwithai.top",
3333
siteName: "CoderWithAI",
3434
images: [
3535
{
36-
url: "https://www.codewithai.com/images/og-image.jpg",
36+
url: "https://www.coderwithai.top/images/og-image.jpg",
3737
width: 1200,
3838
height: 630,
3939
},
@@ -45,7 +45,7 @@ export const metadata: Metadata = {
4545
card: "summary_large_image",
4646
title: "CoderWithAI - 学习编程的最佳资源",
4747
description: "全面的编程教程和交互式学习平台",
48-
images: ["https://www.codewithai.com/images/twitter-image.jpg"],
48+
images: ["https://www.coderwithai.top/images/twitter-image.jpg"],
4949
},
5050
};
5151

@@ -84,11 +84,11 @@ export default async function RootLayout({
8484
"@context": "https://schema.org",
8585
"@type": "WebSite",
8686
"name": "CoderWithAI",
87-
"url": "https://www.codewithai.com",
87+
"url": "https://www.coderwithai.top",
8888
"description": "CoderWithAI 提供全面的编程教程,涵盖多种编程语言和框架。通过我们的交互式学习平台,提升您的编程技能。",
8989
"potentialAction": {
9090
"@type": "SearchAction",
91-
"target": "https://www.codewithai.com/search?q={search_term_string}",
91+
"target": "https://www.coderwithai.top/search?q={search_term_string}",
9292
"query-input": "required name=search_term_string"
9393
}
9494
}

‎app/sitemap.ts‎

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,30 @@
1-
import { getAvailableLanguages, getTutorials } from "@/lib/tutorials";
1+
import type { MetadataRoute } from "next";
2+
import { getAvailableLanguages, getTutorials, Tutorial } from "@/lib/tutorials";
23

3-
export default async function sitemap() {
4-
const baseUrl = "https://www.codewithai.com";
5-
const languages = await getAvailableLanguages();
4+
const baseUrl = "https://www.coderwithai.top";
5+
6+
// 教程是按目录嵌套的:目录本身不是页面,只收叶子上的 .md 页面
7+
function collectPaths(items: Tutorial[], out: string[]) {
8+
for (const t of items) {
9+
if (t.items) collectPaths(t.items, out);
10+
else out.push(t.path);
11+
}
12+
}
613

7-
const urls: string[] = [];
14+
const encodePath = (p: string) => p.split("/").map(encodeURIComponent).join("/");
15+
16+
export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
17+
const languages = await getAvailableLanguages();
18+
const entries: MetadataRoute.Sitemap = [{ url: baseUrl }];
819

920
for (const lang of languages) {
10-
const tutorials = await getTutorials(lang);
11-
urls.push(`${baseUrl}/${lang}`);
12-
tutorials.forEach((tutorial) => {
13-
urls.push(`${baseUrl}/${lang}/${tutorial.path}`);
14-
});
21+
entries.push({ url: `${baseUrl}/${encodeURIComponent(lang)}` });
22+
const paths: string[] = [];
23+
collectPaths(await getTutorials(lang), paths);
24+
for (const p of paths) {
25+
entries.push({ url: `${baseUrl}/${encodeURIComponent(lang)}/${encodePath(p)}` });
26+
}
1527
}
1628

17-
return urls;
18-
}
29+
return entries;
30+
}

‎next.config.js‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ const nextConfig = {
4646
];
4747
},
4848
images: {
49-
domains: ['www.codewithai.com'], // 添加你的图片域名
49+
domains: ['www.coderwithai.top'], // 添加你的图片域名
5050
unoptimized: true,
5151
},
5252
};

‎package.json‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,5 +47,8 @@
4747
"postcss": "^8",
4848
"tailwindcss": "^3.4.1",
4949
"typescript": "^5"
50+
},
51+
"engines": {
52+
"node": "22.x"
5053
}
5154
}

‎public/robots.txt‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
User-agent: *
22
Allow: /
33

4-
Sitemap: https://www.codewithai.com/sitemap.xml
4+
Sitemap: https://www.coderwithai.top/sitemap.xml

0 commit comments

Comments
 (0)