Skip to content

Commit 0410b2c

Browse files
committed
feat: add seo common Comp
1 parent d1840fc commit 0410b2c

File tree

3 files changed

+97
-8
lines changed

3 files changed

+97
-8
lines changed

src/components/SEO.tsx

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import Head from 'next/head'
2+
import { useRouter } from 'next/router'
3+
import { seoConfig, type RoutePath } from '@/config/seo'
4+
5+
interface SEOProps {
6+
title?: string
7+
description?: string
8+
keywords?: string
9+
ogTitle?: string
10+
ogDescription?: string
11+
ogImage?: string
12+
ogType?: string
13+
twitterCard?: string
14+
twitterTitle?: string
15+
twitterDescription?: string
16+
twitterImage?: string
17+
}
18+
19+
export default function SEO(props?: SEOProps) {
20+
const router = useRouter()
21+
const pathname = router.pathname as RoutePath
22+
23+
// 获取路由对应的配置,如果没有配置则使用首页配置作为默认值
24+
const routeConfig = seoConfig[pathname] || seoConfig['/']
25+
26+
// 合并路由配置和传入的 props,props 优先级更高
27+
const config = {
28+
...routeConfig,
29+
...props
30+
}
31+
32+
const {
33+
title = '开源社',
34+
description,
35+
keywords,
36+
ogTitle,
37+
ogDescription,
38+
ogImage,
39+
ogType = 'website',
40+
twitterCard = 'summary_large_image',
41+
twitterTitle,
42+
twitterDescription,
43+
twitterImage
44+
} = config
45+
46+
return (
47+
<Head>
48+
{/* 基础 SEO */}
49+
<title>{title}</title>
50+
{description && <meta name="description" content={description} />}
51+
{keywords && <meta name="keywords" content={keywords} />}
52+
53+
{/* Open Graph / Facebook */}
54+
{ogTitle && <meta property="og:title" content={ogTitle} />}
55+
{ogDescription && <meta property="og:description" content={ogDescription} />}
56+
<meta property="og:type" content={ogType} />
57+
{ogImage && <meta property="og:image" content={ogImage} />}
58+
59+
{/* Twitter */}
60+
<meta name="twitter:card" content={twitterCard} />
61+
{(twitterTitle || ogTitle) && (
62+
<meta name="twitter:title" content={twitterTitle || ogTitle || title} />
63+
)}
64+
{(twitterDescription || ogDescription) && (
65+
<meta name="twitter:description" content={twitterDescription || ogDescription || description || ''} />
66+
)}
67+
{(twitterImage || ogImage) && (
68+
<meta name="twitter:image" content={twitterImage || ogImage || ''} />
69+
)}
70+
</Head>
71+
)
72+
}

src/config/seo.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
export const seoConfig = {
2+
'/charter': {
3+
title: '开源社章程 - 开源社',
4+
description:
5+
'开源社章程 2025年修订版。开源社是由志愿贡献于开源事业的个人志愿者,依贡献、共识、共治原则所组成的开源社区。了解开源社的愿景、使命、宗旨、治理结构和成员权利义务。',
6+
keywords:
7+
'开源社,章程,开源治理,社区发展,开源社区,KAIYUANSHE,开源人宣言,治理机构',
8+
ogTitle: '开源社章程 - 开源社',
9+
ogDescription: '开源社章程 2025年修订版 - 推动开源成为新时代的生活方式'
10+
}
11+
} as const
12+
13+
export type SeoConfig = typeof seoConfig
14+
export type RoutePath = keyof SeoConfig

src/pages/charter/index.tsx

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1-
import React from 'react'
1+
import SEO from '@/components/SEO'
22
import styles from './index.module.css'
33

44
const CharterPage = () => {
55
return (
6-
<div className={styles.charterPage}>
6+
<>
7+
<SEO />
8+
<div className={styles.charterPage}>
79
{/* Hero Section */}
810
<div className={styles.heroSection}>
911
<div className={styles.heroOverlay}>
@@ -24,14 +26,14 @@ const CharterPage = () => {
2426
<div className={styles.article}>
2527
<span className={styles.articleNumber}>第一条</span>
2628
<span className={styles.articleContent}>
27-
开源社是由志愿贡献于开源事业的个人志愿者,依 <span className={styles.highlight}>"贡献、共识、共治"</span> 原则所组成的开源社区。
29+
开源社是由志愿贡献于开源事业的个人志愿者,依 <span className={styles.highlight}>&quot;贡献、共识、共治&ldquo;</span> 原则所组成的开源社区。
2830
</span>
2931
</div>
3032

3133
<div className={styles.article}>
3234
<span className={styles.articleNumber}>第二条</span>
3335
<span className={styles.articleContent}>
34-
开源社的英文名称为<span className={styles.emphasis}>"KAIYUANSHE"</span>,官方网站地址为: https://kaiyuanshe.cn 。
36+
开源社的英文名称为<span className={styles.emphasis}>&quot;KAIYUANSHE&ldquo;</span>,官方网站地址为: https://kaiyuanshe.cn 。
3537
</span>
3638
</div>
3739

@@ -132,7 +134,7 @@ const CharterPage = () => {
132134
</div>
133135

134136
<ul className={styles.rightsList}>
135-
<li className={styles.rightsItem}>享有"开源社正式成员"的称号</li>
137+
<li className={styles.rightsItem}>享有&quot;开源社正式成员&ldquo;的称号</li>
136138
<li className={styles.rightsItem}>享有在开源社官网正式成员名单中进行展示的权利</li>
137139
<li className={styles.rightsItem}>可申请获得开源社的官方邮箱账号</li>
138140
<li className={styles.rightsItem}>可申请获得开源社名片,并印制在开源社所担任的志愿者职衔(如组长、副组长、秘书、正式成员等)</li>
@@ -154,8 +156,8 @@ const CharterPage = () => {
154156

155157
<ul className={styles.dutiesList}>
156158
<li className={styles.dutiesItem}>理解并认同开源社愿景</li>
157-
<li className={styles.dutiesItem}>支持并践行开源社"开源治理、国际接轨、社区发展、项目孵化"的核心使命</li>
158-
<li className={styles.dutiesItem}>理解并认同开源社"贡献、共识、共治"的原则及《开源人宣言》</li>
159+
<li className={styles.dutiesItem}>支持并践行开源社&quot;开源治理、国际接轨、社区发展、项目孵化&ldquo;的核心使命</li>
160+
<li className={styles.dutiesItem}>理解并认同开源社&quot;贡献、共识、共治&ldquo;的原则及《开源人宣言》</li>
159161
<li className={styles.dutiesItem}>理解并拥护开源社的章程</li>
160162
<li className={styles.dutiesItem}>选择至少一个工作组或项目组加入,并做出相应贡献</li>
161163
<li className={styles.dutiesItem}>积极参与正式成员纳新投票及理事选举投票等开源社重要活动</li>
@@ -366,7 +368,8 @@ const CharterPage = () => {
366368
</section>
367369
</main>
368370
</div>
369-
</div>
371+
</div>
372+
</>
370373
)
371374
}
372375

0 commit comments

Comments
 (0)