feat(seo): 结构化数据/每页元数据/列表页metadata/hreflang修正/OG分享图
- 详情页注入 Article+BreadcrumbList JSON-LD,工具页 SoftwareApplication - 课程/技能/文章/练习 动态 generateMetadata(canonical/OG) - 新增 skills/contents/practices/prompts/models 列表页 metadata - 修正 hreflang(删除不存在的/en),用 next/og 生成 OG 分享图
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
import { SITE_URL } from './config';
|
||||
|
||||
export function absoluteUrl(path: string): string {
|
||||
if (/^https?:\/\//.test(path)) return path;
|
||||
return `${SITE_URL}${path.startsWith('/') ? '' : '/'}${path}`;
|
||||
}
|
||||
|
||||
export function articleJsonLd(data: {
|
||||
headline: string;
|
||||
description?: string;
|
||||
url: string;
|
||||
datePublished?: string;
|
||||
image?: string;
|
||||
authorName?: string;
|
||||
}) {
|
||||
return {
|
||||
'@context': 'https://schema.org',
|
||||
'@type': 'Article',
|
||||
headline: data.headline,
|
||||
description: data.description || '',
|
||||
url: data.url,
|
||||
...(data.datePublished ? { datePublished: data.datePublished } : {}),
|
||||
author: { '@type': 'Organization', name: data.authorName || '宇之然 AI', url: SITE_URL },
|
||||
publisher: {
|
||||
'@type': 'Organization',
|
||||
name: '宇之然 AI',
|
||||
url: SITE_URL,
|
||||
logo: { '@type': 'ImageObject', url: `${SITE_URL}/favicon.png` },
|
||||
},
|
||||
...(data.image ? { image: data.image } : {}),
|
||||
};
|
||||
}
|
||||
|
||||
export function softwareAppJsonLd(data: { name: string; description?: string; url: string }) {
|
||||
return {
|
||||
'@context': 'https://schema.org',
|
||||
'@type': 'SoftwareApplication',
|
||||
name: data.name,
|
||||
description: data.description || '',
|
||||
url: data.url,
|
||||
applicationCategory: 'UtilitiesApplication',
|
||||
operatingSystem: 'Web',
|
||||
offers: { '@type': 'Offer', price: '0', priceCurrency: 'CNY' },
|
||||
publisher: { '@type': 'Organization', name: '宇之然 AI', url: SITE_URL },
|
||||
};
|
||||
}
|
||||
|
||||
export function breadcrumbJsonLd(items: { name: string; url: string }[]) {
|
||||
return {
|
||||
'@context': 'https://schema.org',
|
||||
'@type': 'BreadcrumbList',
|
||||
itemListElement: items.map((it, i) => ({
|
||||
'@type': 'ListItem',
|
||||
position: i + 1,
|
||||
name: it.name,
|
||||
item: it.url,
|
||||
})),
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user