Skip to content

Commit 7aef3c3

Browse files
ofriwclaude
andcommitted
Add SchemaMarkup component for SEO
🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
1 parent 1f0271b commit 7aef3c3

File tree

1 file changed

+139
-0
lines changed

1 file changed

+139
-0
lines changed
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
import React from 'react';
2+
import Head from '@docusaurus/Head';
3+
4+
interface DefinitionData {
5+
term: string;
6+
description: string;
7+
}
8+
9+
interface ArticleData {
10+
headline: string;
11+
description: string;
12+
datePublished?: string;
13+
dateModified?: string;
14+
}
15+
16+
interface HowToStep {
17+
name: string;
18+
text: string;
19+
}
20+
21+
interface HowToData {
22+
name: string;
23+
description?: string;
24+
steps: HowToStep[];
25+
}
26+
27+
interface FAQItem {
28+
question: string;
29+
answer: string;
30+
}
31+
32+
interface FAQData {
33+
questions: FAQItem[];
34+
}
35+
36+
type SchemaType = 'definition' | 'article' | 'howto' | 'faq';
37+
38+
interface SchemaMarkupProps {
39+
type: SchemaType;
40+
data: DefinitionData | ArticleData | HowToData | FAQData;
41+
}
42+
43+
function generateDefinitionSchema(data: DefinitionData) {
44+
return {
45+
'@context': 'https://schema.org',
46+
'@type': 'DefinedTerm',
47+
name: data.term,
48+
description: data.description,
49+
inDefinedTermSet: {
50+
'@type': 'DefinedTermSet',
51+
name: 'AI Development Methodologies',
52+
},
53+
};
54+
}
55+
56+
function generateArticleSchema(data: ArticleData) {
57+
return {
58+
'@context': 'https://schema.org',
59+
'@type': 'Article',
60+
headline: data.headline,
61+
description: data.description,
62+
...(data.datePublished && { datePublished: data.datePublished }),
63+
...(data.dateModified && { dateModified: data.dateModified }),
64+
author: {
65+
'@type': 'Organization',
66+
name: 'Agentic Coding',
67+
url: 'https://agenticoding.ai',
68+
},
69+
publisher: {
70+
'@type': 'Organization',
71+
name: 'Agentic Coding',
72+
url: 'https://agenticoding.ai',
73+
},
74+
mainEntityOfPage: {
75+
'@type': 'WebPage',
76+
'@id': 'https://agenticoding.ai',
77+
},
78+
};
79+
}
80+
81+
function generateHowToSchema(data: HowToData) {
82+
return {
83+
'@context': 'https://schema.org',
84+
'@type': 'HowTo',
85+
name: data.name,
86+
...(data.description && { description: data.description }),
87+
step: data.steps.map((step, index) => ({
88+
'@type': 'HowToStep',
89+
position: index + 1,
90+
name: step.name,
91+
text: step.text,
92+
})),
93+
};
94+
}
95+
96+
function generateFAQSchema(data: FAQData) {
97+
return {
98+
'@context': 'https://schema.org',
99+
'@type': 'FAQPage',
100+
mainEntity: data.questions.map((q) => ({
101+
'@type': 'Question',
102+
name: q.question,
103+
acceptedAnswer: {
104+
'@type': 'Answer',
105+
text: q.answer,
106+
},
107+
})),
108+
};
109+
}
110+
111+
export default function SchemaMarkup({
112+
type,
113+
data,
114+
}: SchemaMarkupProps): React.ReactElement {
115+
let schema: object;
116+
117+
switch (type) {
118+
case 'definition':
119+
schema = generateDefinitionSchema(data as DefinitionData);
120+
break;
121+
case 'article':
122+
schema = generateArticleSchema(data as ArticleData);
123+
break;
124+
case 'howto':
125+
schema = generateHowToSchema(data as HowToData);
126+
break;
127+
case 'faq':
128+
schema = generateFAQSchema(data as FAQData);
129+
break;
130+
default:
131+
throw new Error(`Unknown schema type: ${type}`);
132+
}
133+
134+
return (
135+
<Head>
136+
<script type="application/ld+json">{JSON.stringify(schema)}</script>
137+
</Head>
138+
);
139+
}

0 commit comments

Comments
 (0)