docs: add JSON-LD schemas to docs (#14007)

This commit is contained in:
Shahed Nasser
2025-11-07 14:43:50 +02:00
committed by GitHub
parent c9648cc9cc
commit dc6f253d31
26 changed files with 146 additions and 17 deletions

View File

@@ -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<BreadcrumbList>({
"@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 (
<div
className={clsx(
@@ -79,6 +99,12 @@ export const Breadcrumbs = () => {
</Button>
</React.Fragment>
))}
<script
type="application/ld+json"
dangerouslySetInnerHTML={{
__html: jsonLd,
}}
/>
</div>
)
}

View File

@@ -0,0 +1,74 @@
"use client"
import React, { useEffect, useState } from "react"
import type { TechArticle } from "schema-dts"
import { useIsBrowser, useSiteConfig } from "../../providers"
import { getJsonLd } from "../../utils"
import { usePathname } from "next/navigation"
export const TechArticleJsonLd = () => {
const {
config: { baseUrl, basePath, description: configDescription, titleSuffix },
} = useSiteConfig()
const pathname = usePathname()
const { isBrowser } = useIsBrowser()
const [jsonLdData, setJsonLdData] = useState("{}")
useEffect(() => {
if (!isBrowser) {
return
}
// Use a small delay to ensure the document has been updated after navigation
const updateJsonLd = () => {
const baseLink = `${baseUrl}${basePath}`.replace(/\/+$/, "")
const title = document.title.replace(` - ${titleSuffix}`, "")
const description =
document.querySelector("#main p")?.textContent ||
configDescription ||
""
const data = getJsonLd<TechArticle>({
"@context": "https://schema.org",
"@type": "TechArticle",
headline: title,
description,
proficiencyLevel: "Expert",
author: "Medusa",
genre: "Documentation",
keywords: "medusa, ecommerce, open-source",
url: `${baseLink}${pathname}`,
})
setJsonLdData(data)
}
// Update immediately
updateJsonLd()
// Also set up a MutationObserver to watch for title changes
const titleObserver = new MutationObserver(() => {
updateJsonLd()
})
const titleElement = document.querySelector("title")
if (titleElement) {
titleObserver.observe(titleElement, {
childList: true,
characterData: true,
subtree: true,
})
}
return () => {
titleObserver.disconnect()
}
}, [isBrowser, pathname, baseUrl, basePath, configDescription, titleSuffix])
return (
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: jsonLdData }}
/>
)
}

View File

@@ -3,6 +3,7 @@ import clsx from "clsx"
import { RootProviders, Sidebar, SidebarProps } from "@/components"
import { MainContentLayout, MainContentLayoutProps } from "./main-content"
import { AiAssistantChatWindow } from "../components/AiAssistant/ChatWindow"
import { TechArticleJsonLd } from "../components/TechArticleJsonLd"
export type RootLayoutProps = {
bodyClassName?: string
@@ -37,6 +38,7 @@ export const RootLayout = ({
<MainContentLayout {...mainProps} />
<AiAssistantChatWindow />
</div>
<TechArticleJsonLd />
</ProvidersComponent>
</RootProviders>
</div>

View File

@@ -0,0 +1,5 @@
import type { Thing, WithContext } from "schema-dts"
export function getJsonLd<T extends Thing>(data: WithContext<T>): string {
return JSON.stringify(data, null, 2).replace(/</g, "\\u003c")
}

View File

@@ -4,6 +4,7 @@ export * from "./check-sidebar-item-visibility"
export * from "./decode-str"
export * from "./dom-utils"
export * from "./event-parser"
export * from "./get-json-ld"
export * from "./get-link-with-base-path"
export * from "./get-local-search"
export * from "./get-navbar-items"