Skip to content

Commit 56c2e2f

Browse files
authored
Merge pull request #768 from javaistic/feat/enhance-seo
Enhance SEO with structured data and improved metadata
2 parents 8b231ce + 6e987e7 commit 56c2e2f

File tree

4 files changed

+90
-30
lines changed

4 files changed

+90
-30
lines changed

bun.lock

Lines changed: 5 additions & 17 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
"build": "next build",
77
"dev": "next dev --turbo",
88
"start": "next start",
9+
"lint": "eslint .",
910
"format": "prettier \"src/**/*.{ts,tsx,js,jsx,json,css}\" \"content/**/*.{md,mdx}\" --write",
1011
"format:check": "prettier \"src/**/*.{ts,tsx,js,jsx,json,css}\" \"content/**/*.{md,mdx}\" --check",
1112
"postinstall": "fumadocs-mdx"
@@ -31,6 +32,7 @@
3132
"react": "^19.1.0",
3233
"react-dom": "^19.1.0",
3334
"react-simple-code-editor": "^0.14.1",
35+
"schema-dts": "^1.1.5",
3436
"sharp": "^0.34.3",
3537
"tailwind-merge": "^3.3.1",
3638
"use-debounce": "^10.0.5"

src/app/docs/[[...slug]]/page.tsx

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,41 @@ import {
77
DocsPage,
88
DocsTitle,
99
} from "fumadocs-ui/page";
10+
import type { Metadata, ResolvingMetadata } from "next";
1011
import { notFound } from "next/navigation";
12+
import { Article, WithContext } from "schema-dts";
1113

1214
export default async function Page(props: {
1315
params: Promise<{ slug?: string[] }>;
1416
}) {
1517
const params = await props.params;
1618
const page = source.getPage(params.slug);
19+
const owner = "javaistic";
20+
const repo = "javaistic";
21+
1722
if (!page) notFound();
1823

1924
const MDXContent = page.data.body;
2025

26+
const jsonLd: WithContext<Article> = {
27+
"@context": "https://schema.org",
28+
"@type": "Article",
29+
headline: page.data.title,
30+
description: page.data.description,
31+
author: {
32+
"@type": "Organization",
33+
name: "Javaistic",
34+
},
35+
publisher: {
36+
"@type": "Organization",
37+
name: "Javaistic",
38+
},
39+
mainEntityOfPage: {
40+
"@type": "WebPage",
41+
"@id": `https://javaistic.vercel.app${page.url}`,
42+
},
43+
};
44+
2145
return (
2246
<DocsPage
2347
toc={page.data.toc}
@@ -31,6 +55,7 @@ export default async function Page(props: {
3155
<DocsDescription className="mb-3">
3256
{page.data.description}
3357
</DocsDescription>
58+
3459
<DocsBody>
3560
<MDXContent
3661
components={getMDXComponents({
@@ -39,6 +64,12 @@ export default async function Page(props: {
3964
})}
4065
/>
4166
</DocsBody>
67+
<script
68+
type="application/ld+json"
69+
dangerouslySetInnerHTML={{
70+
__html: JSON.stringify(jsonLd).replace(/</g, "\\u003c"),
71+
}}
72+
/>
4273
</DocsPage>
4374
);
4475
}
@@ -47,11 +78,19 @@ export async function generateStaticParams() {
4778
return source.generateParams();
4879
}
4980

50-
export async function generateMetadata(props: {
81+
type Props = {
5182
params: Promise<{ slug?: string[] }>;
52-
}) {
53-
const params = await props.params;
54-
const page = source.getPage(params.slug);
83+
searchParams: Promise<{ [key: string]: string | string[] | undefined }>;
84+
};
85+
86+
export async function generateMetadata(
87+
{ params, searchParams }: Props,
88+
parent: ResolvingMetadata,
89+
): Promise<Metadata> {
90+
const { slug } = await params;
91+
92+
const page = source.getPage(slug);
93+
5594
if (!page) notFound();
5695

5796
return {
@@ -60,7 +99,8 @@ export async function generateMetadata(props: {
6099
openGraph: {
61100
title: `${page.data.title} - Javaistic`,
62101
description: page.data.description,
63-
sitename: "Javaistic",
102+
siteName: "Javaistic",
103+
url: `https://javaistic.vercel.app${page.url}`,
64104
images: `https://og-javaistic.vercel.app/og?title=${page.data.title}`,
65105
},
66106
twitter: {

src/app/programs/[[...slug]]/page.tsx

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
import { programsSource } from "@/lib/source";
2+
import { getMDXComponents } from "@/mdx-components";
3+
import { createRelativeLink } from "fumadocs-ui/mdx";
24
import {
3-
DocsPage,
45
DocsBody,
56
DocsDescription,
7+
DocsPage,
68
DocsTitle,
79
} from "fumadocs-ui/page";
10+
import type { Metadata, ResolvingMetadata } from "next";
811
import { notFound } from "next/navigation";
9-
import { createRelativeLink } from "fumadocs-ui/mdx";
10-
import { getMDXComponents } from "@/mdx-components";
12+
import { HowTo, WithContext } from "schema-dts";
1113

1214
export default async function Page(props: {
1315
params: Promise<{ slug?: string[] }>;
@@ -18,6 +20,21 @@ export default async function Page(props: {
1820

1921
const MDXContent = page.data.body;
2022

23+
const jsonLd: WithContext<HowTo> = {
24+
"@context": "https://schema.org",
25+
"@type": "HowTo",
26+
name: page.data.title,
27+
description: page.data.description,
28+
provider: {
29+
"@type": "Organization",
30+
name: "Javaistic",
31+
},
32+
mainEntityOfPage: {
33+
"@type": "WebPage",
34+
"@id": `https://javaistic.vercel.app${page.url}`,
35+
},
36+
};
37+
2138
return (
2239
<DocsPage
2340
toc={page.data.toc}
@@ -36,6 +53,12 @@ export default async function Page(props: {
3653
})}
3754
/>
3855
</DocsBody>
56+
<script
57+
type="application/ld+json"
58+
dangerouslySetInnerHTML={{
59+
__html: JSON.stringify(jsonLd).replace(/</g, "\\u003c"),
60+
}}
61+
/>
3962
</DocsPage>
4063
);
4164
}
@@ -44,11 +67,17 @@ export async function generateStaticParams() {
4467
return programsSource.generateParams();
4568
}
4669

47-
export async function generateMetadata(props: {
70+
type Props = {
4871
params: Promise<{ slug?: string[] }>;
49-
}) {
50-
const params = await props.params;
51-
const page = programsSource.getPage(params.slug);
72+
searchParams: Promise<{ [key: string]: string | string[] | undefined }>;
73+
};
74+
75+
export async function generateMetadata(
76+
{ params, searchParams }: Props,
77+
parent: ResolvingMetadata,
78+
): Promise<Metadata> {
79+
const { slug } = await params;
80+
const page = programsSource.getPage(slug);
5281
if (!page) notFound();
5382

5483
return {
@@ -57,7 +86,8 @@ export async function generateMetadata(props: {
5786
openGraph: {
5887
title: `${page.data.title} - Javaistic`,
5988
description: page.data.description,
60-
sitename: "Javaistic",
89+
siteName: "Javaistic",
90+
url: `https://javaistic.vercel.app${page.url}`,
6191
images: `https://og-javaistic.vercel.app/og?title=${page.data.title}`,
6292
},
6393
twitter: {

0 commit comments

Comments
 (0)