diff --git a/demo/docs/customization/doccard.mdx b/demo/docs/customization/doccard.mdx
new file mode 100644
index 000000000..0a304bf02
--- /dev/null
+++ b/demo/docs/customization/doccard.mdx
@@ -0,0 +1,165 @@
+---
+id: doccard
+hide_title: true
+sidebar_label: DocCard Markdown
+title: DocCard Markdown
+description: Swizzle the DocCard component to render Markdown in card descriptions.
+---
+
+## Overview
+
+The default DocCard component used by Docusaurus displays the `description` field
+as plain text. Any Markdown inside the description is escaped rather than
+rendered. To support Markdown, you can swizzle the component and update it to use
+`@theme/Markdown`.
+
+## Swizzling the component
+
+Run the swizzle command from your site directory and choose the **eject** option
+when prompted:
+
+```bash
+npx docusaurus swizzle @docusaurus/theme-classic DocCard
+```
+
+This will create `src/theme/DocCard/index.tsx` in your project. Replace its
+contents with the following:
+
+```tsx title="src/theme/DocCard/index.tsx"
+import React, { type ReactNode } from "react";
+
+import isInternalUrl from "@docusaurus/isInternalUrl";
+import Link from "@docusaurus/Link";
+import type {
+ PropSidebarItemCategory,
+ PropSidebarItemLink,
+} from "@docusaurus/plugin-content-docs";
+import {
+ useDocById,
+ findFirstSidebarItemLink,
+} from "@docusaurus/plugin-content-docs/lib/client/docsUtils";
+import { usePluralForm } from "@docusaurus/theme-common";
+import { translate } from "@docusaurus/Translate";
+import type { Props } from "@theme/DocCard";
+import Heading from "@theme/Heading";
+import Markdown from "@theme/Markdown";
+import clsx from "clsx";
+
+import styles from "./styles.module.css";
+
+function useCategoryItemsPlural() {
+ const { selectMessage } = usePluralForm();
+ return (count: number) =>
+ selectMessage(
+ count,
+ translate(
+ {
+ message: "1 item|{count} items",
+ id: "theme.docs.DocCard.categoryDescription.plurals",
+ description:
+ "The default description for a category card in the generated index about how many items this category includes",
+ },
+ { count }
+ )
+ );
+}
+
+function CardContainer({
+ className,
+ href,
+ children,
+}: {
+ className?: string;
+ href: string;
+ children: ReactNode;
+}): ReactNode {
+ return (
+
+ {children}
+
+ );
+}
+
+function CardLayout({
+ className,
+ href,
+ icon,
+ title,
+ description,
+}: {
+ className?: string;
+ href: string;
+ icon: ReactNode;
+ title: string;
+ description?: string;
+}): ReactNode {
+ return (
+
+
+ {icon} {title}
+
+ {description && (
+
+ {description}
+
+ )}
+
+ );
+}
+
+function CardCategory({ item }: { item: PropSidebarItemCategory }): ReactNode {
+ const href = findFirstSidebarItemLink(item);
+ const categoryItemsPlural = useCategoryItemsPlural();
+
+ // Unexpected: categories that don't have a link have been filtered upfront
+ if (!href) {
+ return null;
+ }
+
+ return (
+
+ );
+}
+
+function CardLink({ item }: { item: PropSidebarItemLink }): ReactNode {
+ const icon = isInternalUrl(item.href) ? "📄️" : "🔗";
+ const doc = useDocById(item.docId ?? undefined);
+ return (
+
+ );
+}
+
+export default function DocCard({ item }: Props): ReactNode {
+ switch (item.type) {
+ case "link":
+ return ;
+ case "category":
+ return ;
+ default:
+ throw new Error(`unknown item type ${JSON.stringify(item)}`);
+ }
+}
+```
+