Skip to content

Commit 3f5abc3

Browse files
committed
Add structured data for articles and FAQs using schema.org
1 parent f4bdcc3 commit 3f5abc3

File tree

4 files changed

+75
-1
lines changed

4 files changed

+75
-1
lines changed

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

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,45 @@ import { notFound } from 'next/navigation';
99
import { getMDXComponents } from '@/mdx-components';
1010
import type { Metadata } from 'next';
1111
import { createRelativeLink } from 'fumadocs-ui/mdx';
12+
import { Article, WithContext } from 'schema-dts';
1213

1314
export default async function Page(props: PageProps<'/docs/[[...slug]]'>) {
1415
const params = await props.params;
1516
const page = source.getPage(params.slug);
1617
if (!page) notFound();
1718

19+
const jsonLd: WithContext<Article> = {
20+
"@context": "https://schema.org",
21+
"@type": "Article",
22+
"headline": page.data.title,
23+
"description": page.data.description,
24+
"url": `https://riven.tv/docs/${(params.slug ?? []).join('/')}`,
25+
"image": getPageImage(page).url,
26+
"author": {
27+
"@type": "Organization",
28+
"name": "Riven Media",
29+
"url": "https://riven.tv"
30+
},
31+
"publisher": {
32+
"@type": "Organization",
33+
"name": "Riven Media",
34+
"logo": {
35+
"@type": "ImageObject",
36+
"url": "https://riven.tv/icons/icon-192x192.png"
37+
}
38+
}
39+
};
40+
1841
const MDX = page.data.body;
1942

2043
return (
2144
<DocsPage toc={page.data.toc} full={page.data.full} tableOfContent={{style: 'clerk'}}>
45+
<script
46+
type="application/ld+json"
47+
dangerouslySetInnerHTML={{
48+
__html: JSON.stringify(jsonLd).replace(/</g, '\\u003c'),
49+
}}
50+
/>
2251
<DocsTitle>{page.data.title}</DocsTitle>
2352
<DocsDescription>{page.data.description}</DocsDescription>
2453
<DocsBody>

app/layout.tsx

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,55 @@ import '@/app/global.css';
22
import { RootProvider } from 'fumadocs-ui/provider/next';
33
import { Inter } from 'next/font/google';
44
import SearchDialog from '@/components/search';
5+
import { FAQPage, WithContext } from 'schema-dts';
56

67
const inter = Inter({
78
subsets: ['latin'],
89
});
910

11+
const jsonLd: WithContext<FAQPage> = {
12+
"@context": "https://schema.org",
13+
"@type": "FAQPage",
14+
"mainEntity": [
15+
{
16+
"@type": "Question",
17+
"name": "What is Riven?",
18+
"acceptedAnswer": {
19+
"@type": "Answer",
20+
"text": "Riven is a powerful media management solution that works together with debrid services to help you find, organize, stream, and enjoy your media effortlessly."
21+
}
22+
},
23+
{
24+
"@type": "Question",
25+
"name": "How do I get started with Riven?",
26+
"acceptedAnswer": {
27+
"@type": "Answer",
28+
"text": "To get started with Riven, visit our documentation at https://riven.tv/docs to learn about installation and setup."
29+
}
30+
},
31+
{
32+
"@type": "Question",
33+
"name": "Where can I find support for Riven?",
34+
"acceptedAnswer": {
35+
"@type": "Answer",
36+
"text": "For support, please refer to our documentation, send us a message in our discord server at https://discord.riven.tv, or reach out via contact@riven.tv"
37+
}
38+
}
39+
]
40+
};
41+
1042
export default function Layout({ children }: LayoutProps<'/'>) {
1143
return (
1244
<html lang="en" className={inter.className} suppressHydrationWarning>
45+
<head>
46+
<script
47+
type="application/ld+json"
48+
dangerouslySetInnerHTML={{
49+
__html: JSON.stringify(jsonLd).replace(/</g, '\\u003c'),
50+
}}
51+
/>
52+
</head>
53+
1354
<body className="flex flex-col min-h-screen">
1455
<RootProvider
1556
search={{

bun.lock

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
"next": "15.5.4",
1313
"react": "^19.2.0",
1414
"react-dom": "^19.2.0",
15+
"schema-dts": "^1.1.5",
1516
},
1617
"devDependencies": {
1718
"@eslint/eslintrc": "^3",
@@ -1127,6 +1128,8 @@
11271128

11281129
"scheduler": ["scheduler@0.27.0", "", {}, "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q=="],
11291130

1131+
"schema-dts": ["schema-dts@1.1.5", "", {}, "sha512-RJr9EaCmsLzBX2NDiO5Z3ux2BVosNZN5jo0gWgsyKvxKIUL5R3swNvoorulAeL9kLB0iTSX7V6aokhla2m7xbg=="],
1132+
11301133
"scroll-into-view-if-needed": ["scroll-into-view-if-needed@3.1.0", "", { "dependencies": { "compute-scroll-into-view": "^3.0.2" } }, "sha512-49oNpRjWRvnU8NyGVmUaYG4jtTkNonFZI86MmGRDqBphEK2EXT9gdEUoQPZhuBM8yWHxCWbobltqYO5M4XrUvQ=="],
11311134

11321135
"semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@
1717
"lucide-react": "^0.544.0",
1818
"next": "15.5.4",
1919
"react": "^19.2.0",
20-
"react-dom": "^19.2.0"
20+
"react-dom": "^19.2.0",
21+
"schema-dts": "^1.1.5"
2122
},
2223
"devDependencies": {
2324
"@types/node": "24.6.2",

0 commit comments

Comments
 (0)