From dc6f253d31d2e5d7a80246d703f2a33379b9fc3d Mon Sep 17 00:00:00 2001 From: Shahed Nasser Date: Fri, 7 Nov 2025 14:43:50 +0200 Subject: [PATCH] docs: add JSON-LD schemas to docs (#14007) --- www/apps/api-reference/app/globals.css | 2 +- www/apps/api-reference/app/layout.tsx | 5 +- www/apps/api-reference/config/index.ts | 3 + www/apps/book/app/globals.css | 2 +- www/apps/book/app/layout.tsx | 2 +- www/apps/book/config/index.ts | 2 + www/apps/cloud/app/globals.css | 2 +- www/apps/cloud/app/layout.tsx | 3 +- www/apps/cloud/config/index.ts | 2 + www/apps/resources/app/globals.css | 2 +- www/apps/resources/app/layout.tsx | 3 +- www/apps/resources/config/index.ts | 2 + www/apps/ui/app/globals.css | 2 +- www/apps/ui/app/layout.tsx | 3 +- www/apps/ui/config/index.ts | 2 + www/apps/user-guide/app/globals.css | 2 +- www/apps/user-guide/app/layout.tsx | 2 +- www/apps/user-guide/config/index.ts | 2 + www/packages/docs-ui/package.json | 1 + .../src/components/Breadcrumbs/index.tsx | 28 ++++++- .../components/TechArticleJsonLd/index.tsx | 74 +++++++++++++++++++ www/packages/docs-ui/src/layouts/root.tsx | 2 + www/packages/docs-ui/src/utils/get-json-ld.ts | 5 ++ www/packages/docs-ui/src/utils/index.ts | 1 + www/packages/types/src/config.ts | 1 + www/yarn.lock | 8 ++ 26 files changed, 146 insertions(+), 17 deletions(-) create mode 100644 www/packages/docs-ui/src/components/TechArticleJsonLd/index.tsx create mode 100644 www/packages/docs-ui/src/utils/get-json-ld.ts diff --git a/www/apps/api-reference/app/globals.css b/www/apps/api-reference/app/globals.css index 2ec89e36d4..61f8279a57 100644 --- a/www/apps/api-reference/app/globals.css +++ b/www/apps/api-reference/app/globals.css @@ -41,7 +41,7 @@ } *::selection { - @apply bg-medusa-bg-highlight; + @apply bg-medusa-fg-subtle text-medusa-fg-on-inverted; } * { diff --git a/www/apps/api-reference/app/layout.tsx b/www/apps/api-reference/app/layout.tsx index e83ae89cf5..a5b47e47ee 100644 --- a/www/apps/api-reference/app/layout.tsx +++ b/www/apps/api-reference/app/layout.tsx @@ -4,13 +4,14 @@ import { BareboneLayout, WideLayout } from "docs-ui" import clsx from "clsx" import { Metadata } from "next" import { inter, robotoMono } from "./fonts" +import { config } from "@/config" const ogImage = "https://res.cloudinary.com/dza7lstvk/image/upload/v1732200992/Medusa%20Resources/opengraph-image_daq6nx.jpg" export const metadata: Metadata = { - title: "Medusa API Reference", - description: "Check out Medusa's API reference", + title: `%s - ${config.titleSuffix}`, + description: config.description, metadataBase: new URL( process.env.NEXT_PUBLIC_BASE_URL || "http://localhost:3000" ), diff --git a/www/apps/api-reference/config/index.ts b/www/apps/api-reference/config/index.ts index 360c4cefe3..a8009ccfdf 100644 --- a/www/apps/api-reference/config/index.ts +++ b/www/apps/api-reference/config/index.ts @@ -5,6 +5,9 @@ const baseUrl = process.env.NEXT_PUBLIC_BASE_URL || "http://localhost:3000" export const config: DocsConfig = { ...globalConfig, + titleSuffix: "Medusa API Reference", + description: + "Comprehensive reference for Medusa's API routes, request/response structures, authentication methods, and error handling.", baseUrl, basePath: process.env.NEXT_PUBLIC_BASE_PATH, // sidebar is auto generated diff --git a/www/apps/book/app/globals.css b/www/apps/book/app/globals.css index 4a75d63add..7e717516f1 100644 --- a/www/apps/book/app/globals.css +++ b/www/apps/book/app/globals.css @@ -14,7 +14,7 @@ } *::selection { - @apply bg-medusa-bg-highlight; + @apply bg-medusa-fg-subtle text-medusa-fg-on-inverted; } *:not(.code-block-elm) { diff --git a/www/apps/book/app/layout.tsx b/www/apps/book/app/layout.tsx index 1d160dde2c..c586048655 100644 --- a/www/apps/book/app/layout.tsx +++ b/www/apps/book/app/layout.tsx @@ -13,7 +13,7 @@ export const metadata: Metadata = { template: `%s - ${config.titleSuffix}`, default: config.titleSuffix || "", }, - description: "Explore and learn how to use Medusa.", + description: config.description, metadataBase: new URL( process.env.NEXT_PUBLIC_BASE_URL || "http://localhost:3000" ), diff --git a/www/apps/book/config/index.ts b/www/apps/book/config/index.ts index 789247fd1e..3df407a59a 100644 --- a/www/apps/book/config/index.ts +++ b/www/apps/book/config/index.ts @@ -8,6 +8,8 @@ const baseUrl = process.env.NEXT_PUBLIC_BASE_URL || "http://localhost:3000" export const config: DocsConfig = { ...globalConfig, titleSuffix: "Medusa Documentation", + description: + "Explore and learn how to use Medusa. Learn how to get started, the fundamental concepts, how to customize Medusa, and more.", baseUrl, basePath: process.env.NEXT_PUBLIC_BASE_PATH, sidebars: generatedSidebars as Sidebar.Sidebar[], diff --git a/www/apps/cloud/app/globals.css b/www/apps/cloud/app/globals.css index 4a75d63add..7e717516f1 100644 --- a/www/apps/cloud/app/globals.css +++ b/www/apps/cloud/app/globals.css @@ -14,7 +14,7 @@ } *::selection { - @apply bg-medusa-bg-highlight; + @apply bg-medusa-fg-subtle text-medusa-fg-on-inverted; } *:not(.code-block-elm) { diff --git a/www/apps/cloud/app/layout.tsx b/www/apps/cloud/app/layout.tsx index 5e50973837..92c6cc1aa1 100644 --- a/www/apps/cloud/app/layout.tsx +++ b/www/apps/cloud/app/layout.tsx @@ -15,8 +15,7 @@ export const metadata: Metadata = { template: `%s - ${config.titleSuffix}`, default: config.titleSuffix || "", }, - description: - "Learn about Cloud, Medusa's PaaS offering for scalable deployments.", + description: config.description, metadataBase: new URL( process.env.NEXT_PUBLIC_BASE_URL || "http://localhost:3000" ), diff --git a/www/apps/cloud/config/index.ts b/www/apps/cloud/config/index.ts index 732febcfcf..d35accbe0e 100644 --- a/www/apps/cloud/config/index.ts +++ b/www/apps/cloud/config/index.ts @@ -8,6 +8,8 @@ const baseUrl = process.env.NEXT_PUBLIC_BASE_URL || "http://localhost:3000" export const config: DocsConfig = { ...globalConfig, titleSuffix: "Medusa Cloud Documentation", + description: + "Learn about Cloud, Medusa's PaaS offering for scalable deployments. Learn how to sign up, deploy, and manage your Medusa Cloud projects.", baseUrl, basePath: process.env.NEXT_PUBLIC_BASE_PATH, sidebars: generatedSidebars as Sidebar.Sidebar[], diff --git a/www/apps/resources/app/globals.css b/www/apps/resources/app/globals.css index a5b9e80f86..3056d5b51c 100644 --- a/www/apps/resources/app/globals.css +++ b/www/apps/resources/app/globals.css @@ -20,7 +20,7 @@ } *::selection { - @apply bg-medusa-bg-highlight; + @apply bg-medusa-fg-subtle text-medusa-fg-on-inverted; } * { diff --git a/www/apps/resources/app/layout.tsx b/www/apps/resources/app/layout.tsx index 1e8f3cb58a..92c6cc1aa1 100644 --- a/www/apps/resources/app/layout.tsx +++ b/www/apps/resources/app/layout.tsx @@ -15,8 +15,7 @@ export const metadata: Metadata = { template: `%s - ${config.titleSuffix}`, default: config.titleSuffix || "", }, - description: - "Explore Medusa's recipes, API references, configurations, storefront guides, and more.", + description: config.description, metadataBase: new URL( process.env.NEXT_PUBLIC_BASE_URL || "http://localhost:3000" ), diff --git a/www/apps/resources/config/index.ts b/www/apps/resources/config/index.ts index 7c73b307a5..f80340d34f 100644 --- a/www/apps/resources/config/index.ts +++ b/www/apps/resources/config/index.ts @@ -7,6 +7,8 @@ const baseUrl = process.env.NEXT_PUBLIC_BASE_URL || "http://localhost:3000" export const config: DocsConfig = { ...globalConfig, titleSuffix: "Medusa Documentation", + description: + "Explore Medusa's recipes, Commerce and Infrastructure modules, API and SDK references, storefront guides, how-to guides, tutorials, and more.", baseUrl, basePath: process.env.NEXT_PUBLIC_BASE_PATH, sidebars: [], diff --git a/www/apps/ui/app/globals.css b/www/apps/ui/app/globals.css index 0e8da8bc7d..d65a4c02db 100644 --- a/www/apps/ui/app/globals.css +++ b/www/apps/ui/app/globals.css @@ -14,7 +14,7 @@ } *::selection { - @apply bg-medusa-bg-highlight; + @apply bg-medusa-fg-subtle text-medusa-fg-on-inverted; } *:not(.code-block-elm) { diff --git a/www/apps/ui/app/layout.tsx b/www/apps/ui/app/layout.tsx index a8645ca6c1..748ba68a5d 100644 --- a/www/apps/ui/app/layout.tsx +++ b/www/apps/ui/app/layout.tsx @@ -15,8 +15,7 @@ export const metadata: Metadata = { template: `%s - ${config.titleSuffix}`, default: config.titleSuffix || "", }, - description: - "Learn about Medusa UI, A React package with primitives for building Medusa applications.", + description: config.description, metadataBase: new URL( process.env.NEXT_PUBLIC_BASE_URL || "http://localhost:3000" ), diff --git a/www/apps/ui/config/index.ts b/www/apps/ui/config/index.ts index bb3275768b..726430cd08 100644 --- a/www/apps/ui/config/index.ts +++ b/www/apps/ui/config/index.ts @@ -7,6 +7,8 @@ const baseUrl = process.env.NEXT_PUBLIC_BASE_URL || "http://localhost:3000" export const config: DocsConfig = { ...globalConfig, titleSuffix: "Medusa UI", + description: + "Learn about Medusa UI, A React package with primitives for building Medusa applications. Explore components, hooks, colors, icons, and more.", baseUrl, basePath: process.env.NEXT_PUBLIC_BASE_PATH, sidebars: generatedSidebars as Sidebar.Sidebar[], diff --git a/www/apps/user-guide/app/globals.css b/www/apps/user-guide/app/globals.css index 4a75d63add..7e717516f1 100644 --- a/www/apps/user-guide/app/globals.css +++ b/www/apps/user-guide/app/globals.css @@ -14,7 +14,7 @@ } *::selection { - @apply bg-medusa-bg-highlight; + @apply bg-medusa-fg-subtle text-medusa-fg-on-inverted; } *:not(.code-block-elm) { diff --git a/www/apps/user-guide/app/layout.tsx b/www/apps/user-guide/app/layout.tsx index 88a9a2828a..92c6cc1aa1 100644 --- a/www/apps/user-guide/app/layout.tsx +++ b/www/apps/user-guide/app/layout.tsx @@ -15,7 +15,7 @@ export const metadata: Metadata = { template: `%s - ${config.titleSuffix}`, default: config.titleSuffix || "", }, - description: "Explore and learn how to use the Medusa Admin.", + description: config.description, metadataBase: new URL( process.env.NEXT_PUBLIC_BASE_URL || "http://localhost:3000" ), diff --git a/www/apps/user-guide/config/index.ts b/www/apps/user-guide/config/index.ts index ba9317d09a..8818ec8cd4 100644 --- a/www/apps/user-guide/config/index.ts +++ b/www/apps/user-guide/config/index.ts @@ -8,6 +8,8 @@ const baseUrl = process.env.NEXT_PUBLIC_BASE_URL || "http://localhost:3000" export const config: DocsConfig = { ...globalConfig, titleSuffix: "Medusa Admin User Guide", + description: + "Explore and learn how to use the Medusa Admin. Learn how to manage products, orders, customers, and more within the Medusa Admin dashboard.", baseUrl, basePath: process.env.NEXT_PUBLIC_BASE_PATH, sidebars: generatedSidebars as Sidebar.Sidebar[], diff --git a/www/packages/docs-ui/package.json b/www/packages/docs-ui/package.json index c560fae1bc..eb43cafc82 100644 --- a/www/packages/docs-ui/package.json +++ b/www/packages/docs-ui/package.json @@ -41,6 +41,7 @@ "eslint": "^9.13.0", "next": "15.3.5", "rimraf": "^5.0.1", + "schema-dts": "^1.1.5", "tailwind": "*", "tailwindcss": "^3.3.3", "tsc-alias": "^1.8.7", diff --git a/www/packages/docs-ui/src/components/Breadcrumbs/index.tsx b/www/packages/docs-ui/src/components/Breadcrumbs/index.tsx index 97fc268ec2..271ea8f748 100644 --- a/www/packages/docs-ui/src/components/Breadcrumbs/index.tsx +++ b/www/packages/docs-ui/src/components/Breadcrumbs/index.tsx @@ -7,6 +7,8 @@ import { useSidebar, useSiteConfig } from "../../providers" import { Button } from "../Button" import { TriangleRightMini } from "@medusajs/icons" import { Sidebar } from "types" +import { getJsonLd } from "../../utils" +import type { BreadcrumbList } from "schema-dts" type BreadcrumbItems = { title: string @@ -16,7 +18,7 @@ type BreadcrumbItems = { export const Breadcrumbs = () => { const { sidebarHistory, getSidebarFirstLinkChild, getSidebar } = useSidebar() const { - config: { breadcrumbOptions }, + config: { breadcrumbOptions, baseUrl, basePath }, } = useSiteConfig() const getLinkPath = (item: Sidebar.SidebarItemLink): string => { @@ -51,6 +53,24 @@ export const Breadcrumbs = () => { return items }, [sidebarHistory, breadcrumbOptions]) + const jsonLd = useMemo(() => { + const baseLink = `${baseUrl}${basePath}`.replace(/\/+$/, "") + return getJsonLd({ + "@context": "https://schema.org", + "@type": "BreadcrumbList", + itemListElement: breadcrumbItems.map((item, index) => ({ + "@type": "ListItem", + position: index + 1, + name: item.title, + item: item.link.startsWith("#") + ? baseLink + : item.link.startsWith("/") + ? `${baseLink}${item.link}` + : item.link, + })), + }) + }, [breadcrumbItems, baseUrl, basePath]) + return (
{ ))} +