Skip to content

Commit 2b08d82

Browse files
committed
chore: set seo
1 parent 0ddd577 commit 2b08d82

File tree

12 files changed

+205
-32
lines changed

12 files changed

+205
-32
lines changed

app/[lang]/leaderboards/page.tsx

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import type {Metadata} from 'next';
12
import type {ReactElement} from 'react';
23
import clsx from 'clsx';
34
import {Inter} from 'next/font/google';
@@ -21,6 +22,24 @@ type Props = {
2122
params: Promise<{lang: string}>;
2223
};
2324

25+
export async function generateMetadata({params}: Props): Promise<Metadata> {
26+
const {lang} = await params;
27+
const {leaderboards} = await getTranslates(lang as Locale);
28+
29+
return {
30+
title: leaderboards.title,
31+
description:
32+
'Discover top GitHub developers ranked by their contributions, achievements, and coding activity.',
33+
alternates: {
34+
canonical: `/${lang}/leaderboards`,
35+
languages: {
36+
en: '/en/leaderboards',
37+
ko: '/ko/leaderboards',
38+
},
39+
},
40+
};
41+
}
42+
2443
export default async function Page(props: Props): Promise<ReactElement> {
2544
const params = await props.params;
2645
const lang = params.lang as Locale;

app/[lang]/page.tsx

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import type {Metadata} from 'next';
12
import type {ReactElement} from 'react';
23

34
import type {StatsInfo} from '../../src/fetches/github';
@@ -10,6 +11,23 @@ type Props = {
1011
params: Promise<{lang: string}>;
1112
};
1213

14+
export async function generateMetadata({params}: Props): Promise<Metadata> {
15+
const {lang} = await params;
16+
const {home} = await getTranslates(lang as Locale);
17+
18+
return {
19+
title: home.developerPowerMeter,
20+
description: home.developerPowerMeterDesc,
21+
alternates: {
22+
canonical: `/${lang}`,
23+
languages: {
24+
en: '/en',
25+
ko: '/ko',
26+
},
27+
},
28+
};
29+
}
30+
1331
export default async function Page(props: Props): Promise<ReactElement> {
1432
const params = await props.params;
1533
const lang = params.lang as Locale;

app/[lang]/stats/[login]/page.tsx

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1+
import type {Metadata} from 'next';
12
import type {ReactElement} from 'react';
23

34
import {
45
getDoobooStats,
56
getMonthlyContribution,
67
} from '../../../../server/services/githubService';
78
import {getTranslates} from '../../../../src/localization';
9+
import {siteUrl} from '../../../../src/utils/const';
810
import Container from '../Container';
911

1012
import Scouter from './Scouter';
@@ -18,9 +20,43 @@ export const dynamic = 'force-dynamic';
1820

1921
type Props = {
2022
params: Promise<{lang: string; login: string}>;
21-
searchParams: Promise<{endDate?: string}>;
23+
searchParams: Promise<{endDate?: string}>
2224
};
2325

26+
export async function generateMetadata({params}: Props): Promise<Metadata> {
27+
const {lang, login} = await params;
28+
29+
const title = `${login}'s GitHub Stats`;
30+
const description = `Check ${login}'s GitHub contribution stats, achievements, and developer power level.`;
31+
32+
return {
33+
title,
34+
description,
35+
alternates: {
36+
canonical: `/${lang}/stats/${login}`,
37+
},
38+
openGraph: {
39+
title,
40+
description,
41+
url: `${siteUrl}/${lang}/stats/${login}`,
42+
images: [
43+
{
44+
url: `${siteUrl}/api/github-stats-advanced?login=${login}`,
45+
width: 800,
46+
height: 400,
47+
alt: `${login}'s GitHub Stats`,
48+
},
49+
],
50+
},
51+
twitter: {
52+
card: 'summary_large_image',
53+
title,
54+
description,
55+
images: [`${siteUrl}/api/github-stats-advanced?login=${login}`],
56+
},
57+
};
58+
}
59+
2460
export default async function Page(props: Props): Promise<ReactElement> {
2561
const params = await props.params;
2662
const searchParams = await props.searchParams;

app/[lang]/stats/page.tsx

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import type {Metadata} from 'next';
12
import type {ReactElement} from 'react';
23

34
import type {Locale} from '../../../src/i18n';
@@ -11,6 +12,23 @@ type Props = {
1112
params: Promise<{lang: string}>;
1213
};
1314

15+
export async function generateMetadata({params}: Props): Promise<Metadata> {
16+
const {lang} = await params;
17+
const {stats} = await getTranslates(lang as Locale);
18+
19+
return {
20+
title: stats.title,
21+
description: stats.searchUserHint,
22+
alternates: {
23+
canonical: `/${lang}/stats`,
24+
languages: {
25+
en: '/en/stats',
26+
ko: '/ko/stats',
27+
},
28+
},
29+
};
30+
}
31+
1432
export default async function Page(props: Props): Promise<ReactElement> {
1533
const params = await props.params;
1634
const lang = params.lang as Locale;

app/layout.tsx

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,68 @@ import '../styles/output.css';
22
import type {Metadata} from 'next';
33
import type {ReactNode} from 'react';
44

5+
import {siteUrl} from '../src/utils/const';
6+
57
export const metadata: Metadata = {
6-
title: 'github-stats',
7-
description: 'All stats for developers',
8+
metadataBase: new URL(siteUrl),
9+
title: {
10+
default: 'GitHub Stats - Developer Power Meter',
11+
template: '%s | GitHub Stats',
12+
},
13+
description:
14+
'Analyze your GitHub contributions and showcase your developer stats. Get detailed insights into your coding activity, contributions, and achievements.',
15+
keywords: [
16+
'GitHub',
17+
'GitHub Stats',
18+
'Developer Stats',
19+
'GitHub Analytics',
20+
'Contribution Graph',
21+
'Developer Portfolio',
22+
'GitHub Profile',
23+
'Coding Stats',
24+
],
25+
authors: [{name: 'hyochan', url: 'https://github.com/hyochan'}],
26+
creator: 'hyochan',
27+
publisher: 'github-stats',
828
icons: {
929
icon: '/favicon.ico',
30+
apple: '/apple-touch-icon.png',
31+
},
32+
openGraph: {
33+
type: 'website',
34+
locale: 'en_US',
35+
url: siteUrl,
36+
siteName: 'GitHub Stats',
37+
title: 'GitHub Stats - Developer Power Meter',
38+
description:
39+
'Analyze your GitHub contributions and showcase your developer stats. Get detailed insights into your coding activity.',
40+
images: [
41+
{
42+
url: '/og-image.png',
43+
width: 1200,
44+
height: 630,
45+
alt: 'GitHub Stats - Developer Power Meter',
46+
},
47+
],
48+
},
49+
twitter: {
50+
card: 'summary_large_image',
51+
title: 'GitHub Stats - Developer Power Meter',
52+
description:
53+
'Analyze your GitHub contributions and showcase your developer stats.',
54+
images: ['/og-image.png'],
55+
creator: '@peterCho001',
56+
},
57+
robots: {
58+
index: true,
59+
follow: true,
60+
googleBot: {
61+
index: true,
62+
follow: true,
63+
'max-video-preview': -1,
64+
'max-image-preview': 'large',
65+
'max-snippet': -1,
66+
},
1067
},
1168
};
1269

app/robots.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import type {MetadataRoute} from 'next';
2+
3+
import {siteUrl} from '../src/utils/const';
4+
5+
export default function robots(): MetadataRoute.Robots {
6+
return {
7+
rules: [
8+
{
9+
userAgent: '*',
10+
allow: '/',
11+
disallow: ['/api/', '/sign-in'],
12+
},
13+
],
14+
sitemap: `${siteUrl}/sitemap.xml`,
15+
};
16+
}

app/sitemap.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import type {MetadataRoute} from 'next';
2+
3+
import {siteUrl} from '../src/utils/const';
4+
5+
export default function sitemap(): MetadataRoute.Sitemap {
6+
const locales = ['en', 'ko'];
7+
8+
const staticPages = ['', '/stats', '/leaderboards', '/sign-in'];
9+
10+
const sitemapEntries: MetadataRoute.Sitemap = [];
11+
12+
for (const locale of locales) {
13+
for (const page of staticPages) {
14+
sitemapEntries.push({
15+
url: `${siteUrl}/${locale}${page}`,
16+
lastModified: new Date(),
17+
changeFrequency: page === '' ? 'daily' : 'weekly',
18+
priority: page === '' ? 1 : 0.8,
19+
});
20+
}
21+
}
22+
23+
return sitemapEntries;
24+
}

proxy.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ export async function proxy(
7878
}
7979

8080
export const config = {
81-
// Matcher ignoring `/_next/`, `/api/`, `/auth/` and `/assets/`
82-
matcher: ['/((?!api|auth|assets|_next/static|_next/image|favicon.ico|public).*)'],
81+
// Matcher ignoring `/_next/`, `/api/`, `/auth/`, `/assets/`, sitemap.xml, robots.txt
82+
matcher: [
83+
'/((?!api|auth|assets|_next/static|_next/image|favicon.ico|public|sitemap.xml|robots.txt).*)',
84+
],
8385
};

public/apple-touch-icon.png

16 KB
Loading

public/og-image.png

715 KB
Loading

0 commit comments

Comments
 (0)