diff --git a/src/components/seo/JsonLd.tsx b/src/components/seo/JsonLd.tsx
new file mode 100644
index 0000000..2f3b167
--- /dev/null
+++ b/src/components/seo/JsonLd.tsx
@@ -0,0 +1,12 @@
+/**
+ * Renders a JSON-LD structured-data block. Server-safe; Google reads it from the
+ * rendered HTML. Keep the data plain and serialisable.
+ */
+export function JsonLd({ data }: { data: Record }) {
+ return (
+
+ );
+}
diff --git a/src/lib/images.ts b/src/lib/images.ts
index bc00803..86361c0 100644
--- a/src/lib/images.ts
+++ b/src/lib/images.ts
@@ -23,6 +23,8 @@ export const images = {
sanjay: "/team-sanjay.jpg",
ashwika: "/team-ashwika.jpg",
bhoumik: "/team-bhoumik.jpeg",
+ hannah: "/team-hannah.jpeg",
+ vetri: "/team-vetri.png",
},
gallery: [
{ src: "/opt/IMG_2625.jpg", alt: "In the classroom" },
diff --git a/src/lib/seo.ts b/src/lib/seo.ts
new file mode 100644
index 0000000..b8c2cb1
--- /dev/null
+++ b/src/lib/seo.ts
@@ -0,0 +1,65 @@
+import { SITE_URL } from "@/lib/links";
+
+/** Absolute URL with a trailing slash, matching how pages are served. */
+function abs(path: string): string {
+ return `${SITE_URL}${path === "/" ? "/" : path.endsWith("/") ? path : `${path}/`}`;
+}
+
+const PROVIDER = {
+ "@type": "Organization",
+ name: "CodeWithPurpose",
+ url: SITE_URL,
+} as const;
+
+/** Course schema for a free, online track landing page. */
+export function courseJsonLd(opts: {
+ name: string;
+ description: string;
+ path: string;
+}): Record {
+ return {
+ "@context": "https://schema.org",
+ "@type": "Course",
+ name: opts.name,
+ description: opts.description,
+ url: abs(opts.path),
+ provider: PROVIDER,
+ inLanguage: "en",
+ isAccessibleForFree: true,
+ offers: {
+ "@type": "Offer",
+ price: 0,
+ priceCurrency: "USD",
+ category: "Free",
+ },
+ hasCourseInstance: {
+ "@type": "CourseInstance",
+ courseMode: "online",
+ },
+ };
+}
+
+export function breadcrumbJsonLd(items: { name: string; path: string }[]): Record {
+ return {
+ "@context": "https://schema.org",
+ "@type": "BreadcrumbList",
+ itemListElement: items.map((it, i) => ({
+ "@type": "ListItem",
+ position: i + 1,
+ name: it.name,
+ item: abs(it.path),
+ })),
+ };
+}
+
+export function faqJsonLd(items: { question: string; answer: string }[]): Record {
+ return {
+ "@context": "https://schema.org",
+ "@type": "FAQPage",
+ mainEntity: items.map((it) => ({
+ "@type": "Question",
+ name: it.question,
+ acceptedAnswer: { "@type": "Answer", text: it.answer },
+ })),
+ };
+}