fix(seo): 详情页服务端渲染写入静态HTML并修复skills预渲染报错

- courses/skills/contents/practices 详情页改为服务端取数 + initialData 渲染,正文进入静态 HTML(解决百度弱 JS 收录盲点)
- contents 的 markdown 由 useEffect+setState 改为 useMemo 同步输出
- 四个 generateStaticParams 改用 API 真实 id;getX 校验 data.id 防后端 200+error 体被当有效数据导致 undefined.map 报错
- 更新进度文档至 v1.3.0
This commit is contained in:
TradeMate Dev
2026-07-11 17:46:31 +08:00
parent 09bf329544
commit 6850ceff56
9 changed files with 117 additions and 73 deletions
+14 -5
View File
@@ -7,15 +7,24 @@ async function getSkill(id: string) {
try {
const res = await fetch(`${API_BASE}/skills/${id}`, { next: { revalidate: 3600 } });
if (!res.ok) return null;
return res.json();
const data = await res.json();
if (!data || !data.id) return null;
return data;
} catch {
return null;
}
}
export function generateStaticParams() {
const skillIds = ['general-chat', 'coding', 'writing', 'study', 'english', 'prompt-engineering', 'data-analysis', 'career'];
return skillIds.map((id) => ({ id }));
export async function generateStaticParams() {
try {
const res = await fetch(`${API_BASE}/skills?pageSize=200`, { next: { revalidate: 3600 } });
if (!res.ok) return [];
const data = await res.json();
const list = Array.isArray(data) ? data : data?.items ?? [];
return list.map((s: { id: string }) => ({ id: s.id }));
} catch {
return [];
}
}
export async function generateMetadata({ params }: { params: { id: string } }): Promise<Metadata> {
@@ -51,7 +60,7 @@ export default async function SkillDetailPage({ params }: { params: { id: string
{jsonLd && (
<script type="application/ld+json" dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }} />
)}
<SkillDetailClient />
<SkillDetailClient initialSkill={skill} />
</>
);
}