diff --git a/src/plugins/recent-guides-plugin.ts b/src/plugins/recent-guides-plugin.ts
index 49a307ca17..a6d520254c 100644
--- a/src/plugins/recent-guides-plugin.ts
+++ b/src/plugins/recent-guides-plugin.ts
@@ -12,9 +12,10 @@ export interface Guide {
tags: { label: string; permalink: string }[];
lastUpdatedAt: number;
description?: string;
- image?: string | { light: string; dark: string };
+ image?: string;
+ img_alt?: string;
icon?: IconName;
- externalUrl?: string;
+ external_url?: string;
}
export interface PluginData {
@@ -40,7 +41,7 @@ function getFiles(dir: string, files: string[] = []) {
return files;
}
-const recentGuidesPlugin: Plugin = function recentGuidesPlugin(context, _options) {
+export default function recentGuidesPlugin(context, _options): Plugin {
return {
name: "recent-guides-plugin",
async loadContent() {
@@ -57,7 +58,6 @@ const recentGuidesPlugin: Plugin = function recentGuidesPlugin(context, _options
const fileContent = fs.readFileSync(tagsYmlPath, "utf8");
predefinedTags = (yaml.load(fileContent) as any) || {};
} catch (e) {
- // eslint-disable-next-line no-console
console.error("Failed to load tags.yml", e);
}
}
@@ -85,9 +85,9 @@ const recentGuidesPlugin: Plugin = function recentGuidesPlugin(context, _options
const slug = baseName.endsWith("/index") ? baseName.replace(/\/index$/, "") : baseName;
const permalink = `/guides/${slug === "index" ? "" : slug}`;
- const externalUrl: string | undefined = (data as any).externalUrl || (data as any).external_url;
+ const externalUrl: string | undefined = (data as any).external_url;
- const frontmatterDate: unknown = (data as any).publishedAt;
+ const frontmatterDate: unknown = (data as any).published_at;
let lastUpdatedAt: number;
if (frontmatterDate) {
@@ -133,14 +133,15 @@ const recentGuidesPlugin: Plugin = function recentGuidesPlugin(context, _options
return {
id: path.basename(filePath, path.extname(filePath)),
- title: data.title || path.basename(filePath, path.extname(filePath)),
+ title: data.title,
permalink: data.slug || permalink,
tags: formattedTags,
lastUpdatedAt,
description: data.description,
image: data.image,
+ img_alt: data.img_alt,
icon: data.icon,
- externalUrl,
+ external_url: externalUrl,
};
});
@@ -160,6 +161,4 @@ const recentGuidesPlugin: Plugin = function recentGuidesPlugin(context, _options
setGlobalData(content);
},
};
-};
-
-export default recentGuidesPlugin;
+}
diff --git a/src/plugins/recent-samples-plugin.ts b/src/plugins/recent-samples-plugin.ts
new file mode 100644
index 0000000000..7f9d06a2f4
--- /dev/null
+++ b/src/plugins/recent-samples-plugin.ts
@@ -0,0 +1,177 @@
+import type { Plugin } from "@docusaurus/types";
+import path from "path";
+import fs from "fs";
+import matter from "gray-matter";
+const yaml = require("js-yaml");
+
+interface TagDefinition {
+ label: string;
+ description?: string;
+}
+
+interface TagsByCategory {
+ [category: string]: {
+ [tagKey: string]: TagDefinition;
+ };
+}
+
+export interface Sample {
+ id: string;
+ title: string;
+ permalink: string;
+ tags: { label: string; key: string; category: string }[];
+ description?: string;
+ image?: string;
+ imgAlt?: string;
+}
+
+export interface PluginData {
+ samples: Sample[];
+ tags: Array<{
+ label: string;
+ key: string;
+ count: number;
+ category: string;
+ }>;
+}
+
+function getFiles(dir: string, files: string[] = []) {
+ const fileList = fs.readdirSync(dir);
+ for (const file of fileList) {
+ const name = path.join(dir, file);
+ if (fs.statSync(name).isDirectory()) {
+ getFiles(name, files);
+ } else {
+ files.push(name);
+ }
+ }
+ return files;
+}
+
+export default function recentSamplesPlugin(context, _options): Plugin {
+ return {
+ name: "recent-samples-plugin",
+ async loadContent() {
+ const samplesDir = path.join(context.siteDir, "samples");
+
+ if (!fs.existsSync(samplesDir)) {
+ return [];
+ }
+
+ const tagsByCategory: TagsByCategory = {};
+ const tagsDir = path.join(samplesDir, "tags");
+
+ if (fs.existsSync(tagsDir)) {
+ const categoryFiles = fs.readdirSync(tagsDir).filter((f) => f.endsWith(".yml"));
+ for (const file of categoryFiles) {
+ const category = path.basename(file, ".yml");
+ const filePath = path.join(tagsDir, file);
+ try {
+ const fileContent = fs.readFileSync(filePath, "utf8");
+ tagsByCategory[category] = (yaml.load(fileContent) as any) || {};
+ } catch (e) {
+ console.error(`Failed to load tags/${file}`, e);
+ }
+ }
+ }
+
+ const tagCounts: Record
= {};
+
+ const files = getFiles(samplesDir)
+ .filter((f) => /\.(md|mdx)$/.test(f))
+ .filter((f) => {
+ const relativePath = path.relative(samplesDir, f);
+ const normalized = relativePath.split(path.sep).join("/");
+ return normalized !== "home.mdx";
+ });
+
+ const samples = files.map((filePath) => {
+ const fileContent = fs.readFileSync(filePath, "utf-8");
+ const { data } = matter(fileContent);
+
+ const relativePath = path.relative(samplesDir, filePath);
+ const relativePathNormalized = relativePath.split(path.sep).join("/");
+ const baseName = relativePathNormalized.replace(/\.(md|mdx)$/, "");
+
+ const slug = baseName.endsWith("/index") ? baseName.replace(/\/index$/, "") : baseName;
+ const permalink = `/samples/${slug === "index" ? "" : slug}`;
+
+ const allTagsArray: Array<{ key: string; category: string }> = [];
+
+ const challengesSolutionsTags = data.challenges_solutions_tags;
+
+ if (Array.isArray(challengesSolutionsTags)) {
+ challengesSolutionsTags.forEach((tag: string) => {
+ allTagsArray.push({ key: tag, category: "challenges-solutions" });
+ });
+ }
+
+ const featureTags = data.feature_tags;
+ if (Array.isArray(featureTags)) {
+ featureTags.forEach((tag: string) => {
+ allTagsArray.push({ key: tag, category: "feature" });
+ });
+ }
+
+ const techStackTags = data.tech_stack_tags;
+ if (Array.isArray(techStackTags)) {
+ techStackTags.forEach((tag: string) => {
+ allTagsArray.push({ key: tag, category: "tech-stack" });
+ });
+ }
+
+ allTagsArray.forEach(({ key }) => {
+ tagCounts[key] = (tagCounts[key] || 0) + 1;
+ });
+
+ const formattedTags = allTagsArray.map(({ key, category }) => {
+ const categoryTags = tagsByCategory[category];
+ const definedTag = categoryTags[key];
+
+ return {
+ label: definedTag?.label || key,
+ key,
+ category,
+ };
+ });
+
+ return {
+ id: path.basename(filePath, path.extname(filePath)),
+ title: data.title,
+ permalink: data.slug || permalink,
+ tags: formattedTags,
+ description: data.description,
+ image: data.image,
+ img_alt: data.img_alt,
+ };
+ });
+
+ const allTags: Array<{
+ label: string;
+ key: string;
+ count: number;
+ category: string;
+ }> = [];
+
+ Object.entries(tagsByCategory).forEach(([category, tags]) => {
+ Object.entries(tags).forEach(([key, value]) => {
+ allTags.push({
+ label: value.label,
+ key,
+ count: tagCounts[key] || 0,
+ category,
+ });
+ });
+ });
+
+ return {
+ samples: samples,
+ tags: allTags,
+ };
+ },
+ async contentLoaded({ content, actions }) {
+ const { setGlobalData } = actions;
+ setGlobalData(content);
+ },
+ };
+}
diff --git a/src/theme/DocItem/Authors/index.tsx b/src/theme/DocItem/Authors/index.tsx
index 1bba0891f8..19ded05074 100644
--- a/src/theme/DocItem/Authors/index.tsx
+++ b/src/theme/DocItem/Authors/index.tsx
@@ -18,7 +18,6 @@ type Author = {
function getAuthorData(authorKey: string): Author | null {
const authorInfo = authorsData[authorKey];
if (!authorInfo) {
- // eslint-disable-next-line no-console
console.warn(`No author data found for key '${authorKey}' in authors.json`);
return null;
}
diff --git a/src/theme/DocItem/BannerImage/index.tsx b/src/theme/DocItem/BannerImage/index.tsx
index 9a0634a55e..b1bc65db3f 100644
--- a/src/theme/DocItem/BannerImage/index.tsx
+++ b/src/theme/DocItem/BannerImage/index.tsx
@@ -6,7 +6,7 @@ import { IconName } from "@site/src/typescript/iconName";
import LazyImage from "@site/src/components/Common/LazyImage";
export interface BannerImageProps {
- imgSrc?: string | { light: string; dark: string };
+ imgSrc?: string;
imgAlt?: string;
imgIcon?: IconName;
className?: string;
diff --git a/src/theme/DocItem/Metadata/DocPageMetadata.tsx b/src/theme/DocItem/Metadata/DocPageMetadata.tsx
index 0d9a4c0d65..9dda519921 100644
--- a/src/theme/DocItem/Metadata/DocPageMetadata.tsx
+++ b/src/theme/DocItem/Metadata/DocPageMetadata.tsx
@@ -17,11 +17,16 @@ export interface DocPageMetadataProps {
ogImageUrl: string;
// Shared (optional)
lastUpdatedAt?: number;
+ keywords?: string[];
// Guide-only (optional)
proficiencyLevel?: string;
authorKey?: string;
publishedAt?: string;
- keywords?: string[];
+ // Sample-only (optional)
+ schemaType?: "TechArticle" | "SoftwareSourceCode";
+ repositoryUrl?: string;
+ licenseUrl?: string;
+ languages?: string[];
}
export default function DocPageMetadata({
@@ -34,9 +39,46 @@ export default function DocPageMetadata({
authorKey,
publishedAt,
keywords,
+ schemaType = "TechArticle",
+ repositoryUrl,
+ licenseUrl,
+ languages,
}: DocPageMetadataProps): ReactNode {
const authorInfo = authorKey ? authorsData[authorKey as keyof typeof authorsData] : null;
+ // Generate SoftwareSourceCode schema for samples
+ if (schemaType === "SoftwareSourceCode") {
+ const softwareSourceCodeJsonLd = JSON.stringify({
+ "@context": "https://schema.org",
+ "@type": "SoftwareSourceCode",
+ name: title,
+ ...(description ? { description } : {}),
+ url: canonicalUrl,
+ ...(repositoryUrl ? { codeRepository: repositoryUrl } : {}),
+ ...(licenseUrl ? { license: licenseUrl } : {}),
+ ...(languages?.length ? { programmingLanguage: languages } : {}),
+ ...(keywords?.length ? { keywords } : {}),
+ runtimePlatform: "RavenDB",
+ publisher: {
+ "@type": "Organization",
+ name: "RavenDB",
+ url: "https://ravendb.net",
+ },
+ isPartOf: {
+ "@type": "CollectionPage",
+ "@id": `${canonicalUrl.split("/samples/")[0]}/samples`,
+ name: "RavenDB Code Samples",
+ },
+ });
+
+ return (
+
+
+
+ );
+ }
+
+ // Generate TechArticle schema for guides and docs
const techArticleJsonLd = JSON.stringify({
"@context": "https://schema.org",
"@type": "TechArticle",
diff --git a/src/theme/DocItem/Metadata/index.tsx b/src/theme/DocItem/Metadata/index.tsx
index 55db8ac27f..893e9a8307 100644
--- a/src/theme/DocItem/Metadata/index.tsx
+++ b/src/theme/DocItem/Metadata/index.tsx
@@ -21,10 +21,12 @@ export default function MetadataWrapper(props: Props): ReactNode {
const isCloud = source?.startsWith("@site/cloud/") || source?.startsWith("cloud/") || false;
const isTemplate = source?.startsWith("@site/templates/") || source?.startsWith("templates/") || false;
const isDocumentationPage = !isGuide && !isCloud && !isTemplate;
+ const isSample = source?.startsWith("@site/samples/") || source?.startsWith("samples/") || false;
- // Exclude landing pages (e.g. guides/home.mdx) from guide-specific metadata
+ // Exclude landing pages (e.g. guides/home.mdx, samples/home.mdx) from type-specific metadata
const fileName = source?.split("/").pop();
const isGuidePage = isGuide && fileName !== "home.mdx";
+ const isSamplePage = isSample && fileName !== "home.mdx";
// Strip trailing slash from base URL to avoid double slashes
const baseUrl = (siteConfig.url as string).replace(/\/$/, "");
@@ -76,6 +78,23 @@ export default function MetadataWrapper(props: Props): ReactNode {
lastUpdatedAt={metadata.lastUpdatedAt}
/>
)}
+ {isSamplePage && (
+ tag.replace(/-/g, " "))}
+ />
+ )}
>
);
@@ -105,19 +124,19 @@ function ValidatedGuideDocPageMetadata({
if (!title) {
throw new Error(`Guide "${permalink}" is missing a required "title" in frontmatter.`);
}
- if (!frontMatter.proficiencyLevel) {
- throw new Error(`Guide "${permalink}" is missing a required "proficiencyLevel" in frontmatter.`);
+ if (!frontMatter.proficiency_level) {
+ throw new Error(`Guide "${permalink}" is missing a required "proficiency_level" in frontmatter.`);
}
return (
diff --git a/src/theme/DocItem/TOC/useFilteredToc.ts b/src/theme/DocItem/TOC/useFilteredToc.ts
index 2d0bd321ab..a813d0f44e 100644
--- a/src/theme/DocItem/TOC/useFilteredToc.ts
+++ b/src/theme/DocItem/TOC/useFilteredToc.ts
@@ -34,7 +34,6 @@ function getFilteredToc(originalToc: readonly TOCItem[]): readonly TOCItem[] {
const filteredToc: TOCItem[] = [];
uniqueIds.forEach((id) => {
- // eslint-disable-next-line no-undef
const headingEl = markdownEl.querySelector(`#${CSS.escape(id)}`);
if (headingEl) {
diff --git a/src/theme/DocItem/index.tsx b/src/theme/DocItem/index.tsx
index 4c27d8108e..b32f23df66 100644
--- a/src/theme/DocItem/index.tsx
+++ b/src/theme/DocItem/index.tsx
@@ -4,6 +4,7 @@ import type DocItemType from "@theme/DocItem";
import type { WrapperProps } from "@docusaurus/types";
import DocsTopbar from "@site/src/components/DocsTopbar";
import { CustomDocFrontMatter } from "@site/src/typescript/docMetadata";
+import { useActivePlugin } from "@docusaurus/plugin-content-docs/client";
type Props = WrapperProps;
@@ -11,6 +12,8 @@ export default function DocItemWrapper(props: Props): ReactNode {
const title = props.content.metadata?.title;
const source = props.content.metadata?.source as string | undefined;
const frontMatter = props.content.frontMatter as CustomDocFrontMatter;
+ const activePlugin = useActivePlugin();
+ const pluginId = activePlugin?.pluginId;
const isDocsOrVersioned =
source?.startsWith("@site/docs/") ||
@@ -25,8 +28,15 @@ export default function DocItemWrapper(props: Props): ReactNode {
const showTopbar = Boolean(isDocsOrVersioned && !isExcluded);
+ const isTemplatesPlugin = pluginId === "templates";
+
return (
<>
+ {isTemplatesPlugin && (
+
+
+
+ )}
{showTopbar && }
diff --git a/src/theme/DocSidebar/Desktop/index.tsx b/src/theme/DocSidebar/Desktop/index.tsx
index 227d09dcf4..bf55cb4632 100644
--- a/src/theme/DocSidebar/Desktop/index.tsx
+++ b/src/theme/DocSidebar/Desktop/index.tsx
@@ -30,6 +30,8 @@ function DocSidebarDesktop({ path, sidebar, onCollapse, isHidden }: Props) {
const pathType = getPathType(path);
const landingPagePath = getLandingPagePath(pathType, versionLabel);
+ const shouldDisplayContent = pathType !== PathType.Guides && pathType !== PathType.Samples;
+
return (
)}
+ {pathType !== PathType.Samples && (
+
+ Samples
+
+ Switch
+
+
+ )}
{pathType !== PathType.Documentation && (
RavenDB Docs
@@ -83,9 +93,9 @@ function DocSidebarDesktop({ path, sidebar, onCollapse, isHidden }: Props) {
)}
- {pathType !== PathType.Guides &&
}
+ {shouldDisplayContent &&
}
{pathType === PathType.Documentation &&
}
- {pathType !== PathType.Guides &&
}
+ {shouldDisplayContent &&
}
{hideable &&
}
);
diff --git a/src/theme/DocSidebar/Mobile/index.tsx b/src/theme/DocSidebar/Mobile/index.tsx
index efc62ea098..f9fd75907d 100644
--- a/src/theme/DocSidebar/Mobile/index.tsx
+++ b/src/theme/DocSidebar/Mobile/index.tsx
@@ -22,6 +22,8 @@ function DocSidebarMobileSecondaryMenu({ sidebar, path }: DocSidebarProps) {
const pathType = getPathType(path);
const landingPagePath = getLandingPagePath(pathType, versionLabel);
+ const shouldDisplayContent = pathType !== PathType.Guides && pathType !== PathType.Samples;
+
return (
-
@@ -47,6 +49,14 @@ function DocSidebarMobileSecondaryMenu({ sidebar, path }: DocSidebarProps) {
)}
+ {pathType !== PathType.Samples && (
+
+ Samples
+
+ Switch
+
+
+ )}
{pathType !== PathType.Cloud && (
RavenDB Cloud Docs
@@ -59,7 +69,7 @@ function DocSidebarMobileSecondaryMenu({ sidebar, path }: DocSidebarProps) {
Community
- {pathType !== PathType.Cloud && pathType !== PathType.Guides && (
+ {pathType === PathType.Documentation && (
-
)}
- {pathType !== PathType.Guides && (
+ {shouldDisplayContent && (
-
)}
- {pathType !== PathType.Cloud && pathType !== PathType.Guides && }
- {pathType !== PathType.Guides && (
+ {pathType === PathType.Documentation && }
+ {shouldDisplayContent && (
{
- // Mobile sidebar should only be closed if the category has a link
if (item.type === "category" && item.href) {
mobileSidebar.toggle();
}
diff --git a/src/theme/DocTagDocListPage/index.tsx b/src/theme/DocTagDocListPage/index.tsx
index 751d4e873e..0ad9f15d6c 100644
--- a/src/theme/DocTagDocListPage/index.tsx
+++ b/src/theme/DocTagDocListPage/index.tsx
@@ -87,7 +87,7 @@ function DocTagDocListPageContent({ tag }: Props): ReactNode {
"animate-in fade-in"
)}
>
- {sortedItems.map((doc, index) => {
+ {sortedItems.map((doc) => {
const guide = guides.find((g: Guide) => g.permalink === doc.permalink);
const formattedDate = guide?.lastUpdatedAt
? new Date(guide.lastUpdatedAt * 1000).toLocaleDateString("en-US", {
@@ -101,19 +101,18 @@ function DocTagDocListPageContent({ tag }: Props): ReactNode {
key={doc.id}
title={doc.title}
description={doc.description}
- url={guide?.externalUrl || doc.permalink}
+ url={guide?.external_url || doc.permalink}
imgSrc={guide?.image}
imgIcon={guide?.icon}
tags={guide?.tags}
date={formattedDate}
- animationDelay={index * 50}
/>
);
})}
) : (
- {sortedItems.map((doc, index) => {
+ {sortedItems.map((doc) => {
const guide = guides.find((g: Guide) => g.permalink === doc.permalink);
const formattedDate = guide?.lastUpdatedAt
? new Date(guide.lastUpdatedAt * 1000).toLocaleDateString("en-US", {
@@ -123,18 +122,10 @@ function DocTagDocListPageContent({ tag }: Props): ReactNode {
})
: undefined;
return (
-
+
diff --git a/src/theme/Tag/index.tsx b/src/theme/Tag/index.tsx
index 42e0de194f..fedfc4eb9a 100644
--- a/src/theme/Tag/index.tsx
+++ b/src/theme/Tag/index.tsx
@@ -3,10 +3,7 @@ import clsx from "clsx";
import Link from "@docusaurus/Link";
import type { Props as DocusaurusTagProps } from "@theme/Tag";
-export interface Props
- extends Partial
,
- // eslint-disable-next-line no-undef
- React.HTMLAttributes {
+export interface Props extends Partial, React.HTMLAttributes {
children?: React.ReactNode;
to?: string;
size?: "xs" | "default";
diff --git a/src/typescript/docMetadata.d.ts b/src/typescript/docMetadata.d.ts
index d40e3f782d..f6219efc5d 100644
--- a/src/typescript/docMetadata.d.ts
+++ b/src/typescript/docMetadata.d.ts
@@ -3,15 +3,41 @@ import { DocsLanguage } from "@site/src/components/LanguageStore";
import { SeeAlsoItemType } from "@site/src/components/SeeAlso/types";
import { IconName } from "@site/src/typescript/iconName";
+export interface GalleryImage {
+ src: string;
+ alt?: string;
+}
+
+export interface RelatedResourceFrontMatter {
+ type: "guide" | "documentation" | "video";
+ documentation_type?: "docs" | "cloud";
+ subtitle: string;
+ article_key?: string;
+ url?: string;
+}
+
export interface CustomDocFrontMatter extends DocFrontMatter {
supported_languages?: DocsLanguage[];
see_also?: SeeAlsoItemType[];
author?: string;
icon?: IconName;
- image?: string | { light: string; dark: string };
- publishedAt?: string;
- proficiencyLevel?: string;
+ image?: string;
+ img_alt?: string;
+ published_at?: string;
+ proficiency_level?: string;
keywords?: string[];
+ gallery?: GalleryImage[];
+ challenges_solutions_tags?: string[];
+ feature_tags?: string[];
+ tech_stack_tags?: string[];
+ category?: string;
+ license?: string;
+ license_url?: string;
+ repository_url?: string;
+ demo_url?: string;
+ languages?: string[];
+ external_url?: string;
+ related_resources?: RelatedResourceFrontMatter[];
}
type CustomDocContextValue = Omit & {
diff --git a/src/typescript/pathUtils.ts b/src/typescript/pathUtils.ts
index 438fe3e043..48abb5d651 100644
--- a/src/typescript/pathUtils.ts
+++ b/src/typescript/pathUtils.ts
@@ -3,6 +3,7 @@ export const PathType = {
Guides: "GUIDES",
Documentation: "DOCUMENTATION",
Templates: "TEMPLATES",
+ Samples: "SAMPLES",
} as const;
export type PathTypeValue = (typeof PathType)[keyof typeof PathType];
@@ -14,6 +15,9 @@ export function getPathType(path: string): PathTypeValue {
if (path.includes("/guides")) {
return PathType.Guides;
}
+ if (path.includes("/samples")) {
+ return PathType.Samples;
+ }
if (path.includes("/templates")) {
return PathType.Templates;
}
@@ -27,6 +31,9 @@ export function getLandingPagePath(pathType: PathTypeValue, versionLabel: string
if (pathType === PathType.Guides) {
return "/guides";
}
+ if (pathType === PathType.Samples) {
+ return "/samples";
+ }
if (pathType === PathType.Templates) {
return "/templates";
}
diff --git a/static/img/samples/library-of-ravens/01.webp b/static/img/samples/library-of-ravens/01.webp
new file mode 100644
index 0000000000..83addb6c52
Binary files /dev/null and b/static/img/samples/library-of-ravens/01.webp differ
diff --git a/static/img/samples/library-of-ravens/02.webp b/static/img/samples/library-of-ravens/02.webp
new file mode 100644
index 0000000000..a99e320f42
Binary files /dev/null and b/static/img/samples/library-of-ravens/02.webp differ
diff --git a/static/img/samples/library-of-ravens/03.webp b/static/img/samples/library-of-ravens/03.webp
new file mode 100644
index 0000000000..2122e3a367
Binary files /dev/null and b/static/img/samples/library-of-ravens/03.webp differ
diff --git a/static/img/samples/library-of-ravens/cover.webp b/static/img/samples/library-of-ravens/cover.webp
new file mode 100644
index 0000000000..d60815d443
Binary files /dev/null and b/static/img/samples/library-of-ravens/cover.webp differ
diff --git a/static/llms.txt b/static/llms.txt
index c5eb0d8c5f..652c498398 100644
--- a/static/llms.txt
+++ b/static/llms.txt
@@ -149,6 +149,11 @@ Documentation is versioned. The current version is 7.2. Use the `/7.2/` URL pref
- [Data Migration](https://docs.ravendb.net/7.2/migration/server/data-migration): Migrate data between RavenDB versions
- [Breaking Changes](https://docs.ravendb.net/7.2/migration/server/server-breaking-changes): Server-side breaking changes by version
+## Sample Applications
+
+- [Samples Home](https://docs.ravendb.net/samples/): Browse production-ready code samples, architecture patterns, and starter kits built with RavenDB
+- [The Library of Ravens](https://docs.ravendb.net/samples/the-ravens-library): Library management app demonstrating vector search, Azure Storage Queues ETL, Include for N+1 elimination, and Document Refresh — built with C#, Aspire, and Azure Functions
+
## Cloud
- [RavenDB Cloud Documentation](https://docs.ravendb.net/cloud/): Cloud service portal documentation
diff --git a/templates/authors.mdx b/templates/authors.mdx
index c5bd3c277d..e0e7fb0382 100644
--- a/templates/authors.mdx
+++ b/templates/authors.mdx
@@ -12,10 +12,6 @@ see_also:
import Admonition from "@theme/Admonition";
import Panel from "@site/src/components/Panel";
-
-
-
-
# Authors
## Add a new author
diff --git a/templates/best-practices-samples.mdx b/templates/best-practices-samples.mdx
new file mode 100644
index 0000000000..1cb1d679ae
--- /dev/null
+++ b/templates/best-practices-samples.mdx
@@ -0,0 +1,274 @@
+---
+title: "Samples: Best practices"
+hide_table_of_contents: false
+sidebar_label: Best practices
+see_also:
+ - title: "Adding new samples"
+ link: "/templates/new-samples"
+ source: "docs"
+ path: "Templates > Samples"
+ - title: "Samples Introduction"
+ link: "/templates/introduction-samples"
+ source: "docs"
+ path: "Templates > Samples"
+---
+
+import Admonition from "@theme/Admonition";
+import Panel from "@site/src/components/Panel";
+
+Guidelines and recommendations for creating high-quality sample documentation.
+
+## Content Guidelines
+
+### Tag Selection
+
+**Challenges & Solutions Tags:**
+- Focus on primary business problems
+- Be specific: `semantic-search` not just `search`
+
+**Feature Tags:**
+- Select key RavenDB features
+- Prioritize features with code examples
+- Include both basic and advanced features
+
+**Tech Stack Tags:**
+- List all major technologies
+- Include language, framework, and cloud services
+- Order by importance: language first, then frameworks
+
+**Example:**
+
+```yaml
+challenges_solutions_tags: [semantic-search, integration-patterns]
+feature_tags: [vector-search, include, document-refresh, azure-storage-queues-etl]
+tech_stack_tags: [csharp, aspire, azure-storage-queues, azure-functions]
+```
+
+### Images
+
+**Cover Image:**
+- Recommended size: 1200x630px
+- Format: WebP for best compression
+- Show the app in action, not just a logo
+- Use high-quality screenshots
+- Ensure text is readable
+
+**Gallery Screenshots:**
+- At least 2 images showing key features
+- Consistent size and aspect ratio
+- Add descriptive alt text
+- Show different parts of the app
+- Highlight unique features
+
+**File organization:**
+
+```
+static/img/samples/{sample-name}/
+├── cover.webp # Main cover image
+├── 01.webp # Gallery image 1
+├── 02.webp # Gallery image 2
+└── 03.webp # Gallery image 3
+```
+
+## Structure Guidelines
+
+### Features Section
+
+Use `FeatureAccordion` components for each major feature:
+
+**Guidelines:**
+- 3-5 accordions per sample
+- Order by importance
+
+**Template:**
+
+```mdx
+## Features used
+
+
+ [Detailed explanation of how and why this feature is used]
+
+ Implementation example:
+
+ // Code showing the feature in action
+
+ [Additional context or benefits]
+
+```
+
+### Related Resources
+
+**Guidelines:**
+- Link to 2-3 related resources
+- Mix guides and documentation
+
+**Priority order:**
+1. Related guides (how-to articles)
+2. Feature documentation (RavenDB docs)
+3. Cloud documentation (if applicable)
+
+## Component Usage
+
+### Sidebar (frontmatter-driven)
+
+The metadata sidebar is fully driven by frontmatter — no JSX props needed.
+
+**Actions (repository_url / demo_url):**
+- Always provide `repository_url` if the code is public
+- Add `demo_url` only if a live demo is available and maintained
+- Don't link to private repositories or broken demo URLs
+
+**Related resources (related_resources):**
+- Link to 2–3 related resources
+- Mix guides and documentation
+- Verify links are correct and current; use descriptive `subtitle` values
+- Don't link to deprecated documentation, use vague subtitles like "Related Article", or duplicate links
+
+### FeatureAccordion
+
+**Do:**
+- Use descriptive icons matching the feature
+- Keep descriptions to one sentence
+
+**Don't:**
+- Leave children empty (omit the accordion instead)
+- Include broken code examples
+
+## Tag Management
+
+### Adding New Tags
+
+**Before adding a tag:**
+1. Check if a similar tag exists
+2. Verify it fits the category (challenges-solutions/feature/tech-stack)
+3. Ensure it will be used by multiple samples
+4. Use consistent naming conventions
+
+**Naming conventions:**
+- Use kebab-case: `azure-storage-queues` not `AzureStorageQueues`
+- Be specific: `azure-storage-queues-etl` not `etl`
+- Avoid abbreviations: `semantic-search` not `sem-search`
+- Use full names: `csharp` not `cs`
+
+### Tag Maintenance
+
+**Periodically review:**
+- Unused tags (count = 0)
+- Duplicate or similar tags
+- Outdated technology tags
+- Inconsistent naming
+
+## Common Mistakes
+
+### ❌ Missing Required Frontmatter
+
+```yaml
+---
+title: "My Sample"
+# Missing description, tags
+---
+```
+
+### ✅ Complete Frontmatter
+
+```yaml
+---
+title: "My Sample"
+description: "Complete description"
+challenges_solutions_tags: [semantic-search]
+feature_tags: [vector-search]
+tech_stack_tags: [csharp]
+license: "MIT License"
+license_url: "https://opensource.org/licenses/MIT"
+repository_url: "https://github.com/ravendb/my-sample-repo"
+languages: ["C#"]
+---
+```
+
+### ❌ Adding H1 Heading
+
+```mdx
+---
+title: "My Sample"
+---
+
+# My Sample
+
+## Overview
+```
+
+### ✅ Start with H2
+
+```mdx
+---
+title: "My Sample"
+---
+
+## Overview
+```
+
+### ❌ Undefined Tags
+
+```yaml
+challenges_solutions_tags: [nonexistent-tag] # Tag doesn't exist in YAML
+```
+
+### ✅ Valid Tags
+
+```yaml
+challenges_solutions_tags: [semantic-search] # Tag exists in samples/tags/challenges-solutions.yml
+```
+
+### ❌ Empty FeatureAccordion
+
+```tsx
+
+ {/* Empty - don't do this */}
+
+```
+
+### ✅ Complete FeatureAccordion
+
+```tsx
+
+ Detailed explanation with code examples...
+
+```
+
+## Testing Checklist
+
+Before publishing a sample:
+
+- [ ] All frontmatter fields are present and valid
+- [ ] `repository_url` and `languages` are set (feeds `SoftwareSourceCode` JSON-LD)
+- [ ] All tags exist in their respective YAML files
+- [ ] Cover image loads correctly
+- [ ] Gallery images load and have alt text
+- [ ] GitHub repository link works
+- [ ] Demo URL works (if provided)
+- [ ] All related resource links work
+- [ ] Code examples are syntactically correct
+- [ ] Sample appears in hub page grid
+- [ ] Filtering works with all tags
+- [ ] Metadata sidebar displays correctly
+- [ ] No console errors or warnings
+
+## Performance Tips
+
+**Images:**
+- Use WebP format for smaller file sizes
+- Optimize images before committing
+- Use appropriate dimensions (don't serve 4K images)
+
+**Code Examples:**
+- Keep examples concise
+- Use syntax highlighting
+
+**Content:**
+- Keep descriptions brief
+- Link to external resources instead of duplicating content
+
diff --git a/templates/components-samples.mdx b/templates/components-samples.mdx
new file mode 100644
index 0000000000..f1cc582992
--- /dev/null
+++ b/templates/components-samples.mdx
@@ -0,0 +1,228 @@
+---
+title: "Samples: Components"
+hide_table_of_contents: false
+sidebar_label: Components
+see_also:
+ - title: "Adding new samples"
+ link: "/templates/new-samples"
+ source: "docs"
+ path: "Templates > Samples"
+ - title: "Samples Introduction"
+ link: "/templates/introduction-samples"
+ source: "docs"
+ path: "Templates > Samples"
+---
+
+import Admonition from "@theme/Admonition";
+import Panel from "@site/src/components/Panel";
+
+This guide documents all React components used in the Samples system.
+
+## Import Statement
+
+All sample components are exported from a single entry point:
+
+```tsx
+import {
+ // Layout (includes sidebar and gallery automatically)
+ SampleLayout,
+
+ // Content
+ FeatureAccordion,
+
+ // Hub (not imported in sample pages)
+ SamplesHomePage,
+ SampleCard,
+ SamplesGrid,
+ SamplesFilter,
+} from '@site/src/components/Samples';
+```
+
+## Layout Components
+
+### SampleLayout
+
+Two-column responsive layout for sample detail pages. Renders the metadata sidebar and gallery automatically from frontmatter — no props needed beyond `children`.
+
+**Location:** `src/components/Samples/Overview/SampleLayout.tsx`
+
+**Props:**
+
+| Prop | Type | Required | Description |
+|---|---|---|---|
+| `children` | `ReactNode` | ✅ | Main content area |
+
+**Usage:**
+
+```tsx
+
+ {/* Main content */}
+
+```
+
+**Auto-rendered from frontmatter:**
+- Sidebar — `SampleMetadataColumn` (tags, actions, license, related resources)
+- Gallery — `gallery` field; omitted automatically when the field is absent
+
+**Behavior:**
+- Desktop (lg+): Two columns, sidebar on right (300px fixed width); gallery above content
+- Mobile: Stacked, sidebar and gallery appear above content
+
+---
+
+## Metadata Sidebar Components
+
+### SampleMetadataColumn
+
+Container for the metadata sidebar. Reads all data from frontmatter — no props required.
+
+**Location:** `src/components/Samples/Overview/Partials/SampleMetadataColumn.tsx`
+
+**Props:**
+
+| Prop | Type | Required | Description |
+|---|---|---|---|
+| `className` | `string` | ❌ | Additional CSS classes |
+
+**Usage:**
+
+```tsx
+
+```
+
+**Populated from frontmatter:**
+- `repository_url` — renders "Browse code" button
+- `demo_url` — renders "View demo" button
+- `challenges_solutions_tags` — Challenges & Solutions tag pills
+- `feature_tags` — Feature tag pills
+- `tech_stack_tags` — Tech stack tag pills
+- `category` — optional, displayed in sidebar
+- `license` / `license_url` — optional, displayed in sidebar
+- `related_resources` — renders linked resource items (see schema below)
+
+**`related_resources` item schema (frontmatter):**
+
+| Field | Type | Required | Description |
+|---|---|---|---|
+| `type` | `"guide"` \| `"documentation"` | ✅ | Resource type |
+| `documentation_type` | `"docs"` \| `"cloud"` | ❌ | Documentation section |
+| `subtitle` | `string` | ✅ | Display text |
+| `article_key` | `string` | ✅ | Article path without version prefix |
+
+**Example frontmatter:**
+
+```yaml
+repository_url: "https://github.com/ravendb/my-sample-repo"
+demo_url: "https://demo.example.com"
+related_resources:
+ - type: guide
+ subtitle: "Bookkeeping with RavenDB & ETLs"
+ article_key: "bookkeeping-with-ravendb"
+ - type: documentation
+ documentation_type: docs
+ subtitle: "Vector Search Overview"
+ article_key: "ai-integration/vector-search/overview"
+ - type: documentation
+ documentation_type: cloud
+ subtitle: "Cloud Backup"
+ article_key: "portal-backup"
+```
+
+**Auto-versioning for docs links:**
+- `documentation_type: docs` → current version is automatically prepended
+- Example: `ai-integration/vector-search/overview` → `/7.2/ai-integration/vector-search/overview`
+
+---
+
+## Content Components
+
+### FeatureAccordion
+
+Expandable accordion for describing RavenDB features used in the sample.
+
+**Location:** `src/components/Samples/Overview/Partials/FeatureAccordion.tsx`
+
+**Props:**
+
+| Prop | Type | Required | Default | Description |
+|---|---|---|---|---|
+| `className` | `string` | ❌ | - | Additional CSS classes |
+| `title` | `string` | ✅ | - | Feature name |
+| `description` | `string` | ✅ | - | Short description (visible when collapsed) |
+| `icon` | `IconName` | ❌ | `"link"` | Icon name from icon gallery |
+| `children` | `ReactNode` | ❌ | - | Detailed content (visible when expanded) |
+| `defaultExpanded` | `boolean` | ❌ | `false` | Initial expanded state |
+
+**Usage:**
+
+```tsx
+
+ Detailed explanation of how vector search is used...
+
+ // Code example
+
+```
+
+**Behavior:**
+- Click header to expand/collapse
+- Smooth animation with Framer Motion
+- Chevron icon rotates on expand/collapse
+
+---
+
+## Hub Components
+
+These components power the `/samples` hub page. They are typically not used in individual sample pages.
+
+### SamplesHomePage
+
+Main hub page component with filters and grid.
+
+**Location:** `src/components/Samples/Hub/SamplesHomePage.tsx`
+
+**Usage:**
+
+```mdx
+---
+title: Samples
+slug: /
+---
+
+import { SamplesHomePage } from "@site/src/components/Samples";
+
+
+```
+**Features:**
+- URL-based filter state (`?tags=vector-search,include&match=all`)
+- Responsive filter sidebar
+- Sample grid with cards
+- Match logic toggle (Any/All)
+
+---
+
+### SampleCard
+
+Individual sample card in the grid.
+
+**Location:** `src/components/Samples/Hub/Partials/SampleCard.tsx`
+
+**Auto-rendered by `SamplesGrid`** - not typically used directly.
+
+---
+
+### SamplesFilter
+
+Filter sidebar with tag categories.
+
+**Location:** `src/components/Samples/Hub/Partials/SamplesFilter.tsx`
+
+**Auto-rendered by `SamplesHomePage`** - not typically used directly.
+
+
+ All components are re-exported from `src/components/Samples/index.ts` for convenient importing.
+
+
diff --git a/templates/featured-guides.mdx b/templates/featured-guides.mdx
index 7ade1167af..59d715022a 100644
--- a/templates/featured-guides.mdx
+++ b/templates/featured-guides.mdx
@@ -16,10 +16,6 @@ see_also:
import Admonition from "@theme/Admonition";
import Panel from "@site/src/components/Panel";
-
-
-
-
# Featured guides
## Mark a guide as featured
@@ -50,7 +46,7 @@ import FeaturedGuides from "@site/src/components/Guides/FeaturedGuides";
```mdx
---
title: "Example Guide"
- publishedAt: 2026-02-27
+ published_at: 2026-02-27
author: "Author Name"
tags: [ai, demo]
image: "/img/guides-ai-agents.webp"
@@ -71,5 +67,5 @@ import FeaturedGuides from "@site/src/components/Guides/FeaturedGuides";
section will update automatically.
- If you omit the `guidesTitles` prop, `FeaturedGuides` will fall back to showing the two most recently updated guides based on file timestamps or `publishedAt`.
+ If you omit the `guidesTitles` prop, `FeaturedGuides` will fall back to showing the two most recently updated guides based on file timestamps or `published_at`.
diff --git a/templates/filtering-samples.mdx b/templates/filtering-samples.mdx
new file mode 100644
index 0000000000..26b3c7b594
--- /dev/null
+++ b/templates/filtering-samples.mdx
@@ -0,0 +1,173 @@
+---
+title: "Samples: Filtering"
+hide_table_of_contents: false
+sidebar_label: Filtering
+see_also:
+ - title: "Samples Introduction"
+ link: "/templates/introduction-samples"
+ source: "docs"
+ path: "Templates > Samples"
+ - title: "Sample tags"
+ link: "/templates/tags-samples"
+ source: "docs"
+ path: "Templates > Samples"
+---
+
+import Admonition from "@theme/Admonition";
+import Panel from "@site/src/components/Panel";
+
+The Samples hub page features a powerful filtering system with URL-based state, multi-category tag selection, and flexible match logic.
+
+## Features
+
+### 1. Multi-Category Filtering
+
+Tags are organized into three categories:
+- **Challenges & Solutions** - Business problems solved
+- **Features** - RavenDB features demonstrated
+- **Tech Stack** - Technologies used
+
+Users can select tags from any or all categories simultaneously.
+
+### 2. Match Logic Toggle
+
+Two matching modes:
+- **Any** (OR logic) - Show samples matching *any* selected tag
+- **All** (AND logic) - Show samples matching *all* selected tags
+
+### 3. URL-Based State
+
+Filter state is stored in URL query parameters for:
+- Shareable filtered views
+- Browser back/forward navigation
+- Bookmarkable searches
+
+**Example URLs:**
+```
+/samples?tags=vector-search
+/samples?tags=vector-search,include&match=all
+/samples?tags=csharp,aspire
+```
+
+### 4. Tag Search
+
+Filter sidebar includes a search box to quickly find tags by name.
+
+### 5. Expandable Categories
+
+Each category can be expanded/collapsed independently. Categories with many tags show only the first 5 by default with a "More" button.
+
+## User Flows
+
+### Flow 1: Browse and Filter
+
+1. User visits `/samples`
+2. Sees all samples in grid
+3. Clicks "Vector Search" tag in filter sidebar
+4. URL updates to `/samples?tags=vector-search`
+5. Grid filters to show only samples with vector search
+6. User clicks "Include" tag
+7. URL updates to `/samples?tags=vector-search,include`
+8. Grid shows samples with *either* tag (Any mode)
+
+### Flow 2: Refine with AND Logic
+
+1. User has selected `vector-search` and `include` tags
+2. Switches match logic from "Any" to "All"
+3. URL updates to `/samples?tags=vector-search,include&match=all`
+4. Grid shows only samples with *both* tags
+
+### Flow 3: Quick Filter from Card
+
+1. User sees a sample card with "C#" language badge
+2. Clicks the "C#" badge
+3. All filters clear, only "C#" is selected
+4. URL updates to `/samples?tags=csharp`
+5. Grid shows all C# samples
+
+### Flow 4: Share Filtered View
+
+1. User has filtered to `csharp,aspire` with "All" logic
+2. Copies URL: `/samples?tags=csharp,aspire&match=all`
+3. Shares URL with colleague
+4. Colleague opens URL and sees the same filtered view
+
+## UI Components
+
+### SamplesFilter
+
+**Features:**
+- Search box for filtering tags by name
+- Match logic toggle (Any/All)
+- Clear filters button
+- Expandable categories
+- Tag checkboxes with counts
+
+**Props:**
+
+```typescript
+interface SamplesFilterProps {
+ categories: FilterCategoryData[];
+ selectedTags: Set;
+ onTagToggle: (tagKey: string) => void;
+ matchLogic: "any" | "all";
+ onMatchLogicChange: (logic: "any" | "all") => void;
+ onClearFilters?: () => void;
+}
+```
+
+### FilterCategory
+
+**Features:**
+- Collapsible category header
+- Shows first 5 tags by default
+- "More" button to expand remaining tags
+- Checkbox for each tag with label
+
+**Props:**
+
+```typescript
+interface FilterCategoryProps {
+ name: string;
+ label: string;
+ tags: FilterTag[];
+ selectedTags: Set;
+ onTagToggle: (tagKey: string) => void;
+ isExpanded: boolean;
+ onToggleExpanded: () => void;
+}
+```
+
+### SamplesGrid
+
+**Features:**
+- Displays filtered samples
+- Shows sample count badge
+- Responsive grid (1 column mobile, 2 columns desktop)
+- Staggered animation on load
+
+**Props:**
+
+```typescript
+interface SamplesGridProps {
+ samples: Sample[];
+ selectedTags: Set;
+ matchLogic: "any" | "all";
+ onTagClick?: (tagKey: string) => void;
+}
+```
+
+## Styling
+
+### Active Tag State
+
+Selected tags are highlighted in the filter sidebar:
+
+```tsx
+ onTagToggle(tag.key)}
+ label={tag.label}
+/>
+```
diff --git a/templates/frames.mdx b/templates/frames.mdx
index b1bbadf41f..c5964d7e3b 100644
--- a/templates/frames.mdx
+++ b/templates/frames.mdx
@@ -10,10 +10,6 @@ import Panel from '@site/src/components/Panel';
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
-
-
-
-
# Frames overview
This guide shows how to use content frames in MDX: lightweight `ContentFrame` for small/medium chunks and `Panel` for larger sections with a built‑in heading and body.
@@ -26,15 +22,13 @@ import ContentFrame from '@site/src/components/ContentFrame';
```
### Basic usage
-````mdx
+```mdx
Text, lists, images, and even code blocks.
- ```ts
- console.log('Hello world!')
- ```
+ // Code example
-````
+```
#### Live example
@@ -167,41 +161,31 @@ You can combine `Panel` and `ContentFrame`:
### Panels with code and tabs
-````mdx
+```mdx
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
- ```csharp
- // sample code
- Console.WriteLine("Hello");
- ```
+ // Code example 1
- ```csharp
- await Console.Out.WriteLineAsync("Hello");
- ```
+ // Code example 2
-````
+```
#### Live example
- ```csharp
- // sample code
- Console.WriteLine("Hello");
- ```
+ // Code example 1
- ```csharp
- await Console.Out.WriteLineAsync("Hello");
- ```
+ // Code example 2
diff --git a/templates/gallery-example.mdx b/templates/gallery-example.mdx
new file mode 100644
index 0000000000..fb362c7751
--- /dev/null
+++ b/templates/gallery-example.mdx
@@ -0,0 +1,97 @@
+---
+title: "Gallery Component Example"
+description: "Example of using the Gallery component with multiple images"
+gallery:
+ - src: "/img/samples/library-of-ravens/01.webp"
+ alt: "First example image"
+ - src: "/img/samples/library-of-ravens/02.webp"
+ alt: "Second example image"
+ - src: "/img/samples/library-of-ravens/03.webp"
+ alt: "Third example image"
+ - src: "/img/discord.webp"
+ alt: "Fourth example image"
+ - src: "/img/webinar.webp"
+ alt: "Fifth example image"
+---
+
+import Gallery from '@site/src/components/Common/Gallery';
+
+# Gallery Component Example
+
+This page demonstrates how to use the Gallery component with images defined in frontmatter.
+
+## Basic Usage
+
+The Gallery component provides responsive layouts optimized for each device:
+
+### Desktop (≥ lg breakpoint)
+- One large image on the left (taking ~2/3 of the width)
+- Two smaller images stacked on the right (taking ~1/3 of the width)
+- If there are more than 3 images, a "+x" overlay appears on the third image
+
+### Mobile (< lg breakpoint)
+- Single-image carousel with swipe navigation
+- All images accessible via horizontal scroll
+- Dot indicators showing current position
+- Tap dots to jump to specific images
+- Images display in their natural aspect ratio
+
+### Example Gallery
+
+
+
+## How to Use
+
+### 1. Define images in frontmatter
+
+```yaml
+---
+title: "Your Page Title"
+gallery:
+ - src: "/img/path/to/image1.png"
+ alt: "Description of first image"
+ - src: "/img/path/to/image2.png"
+ alt: "Description of second image"
+ - src: "/img/path/to/image3.png"
+ alt: "Description of third image"
+ - src: "/img/path/to/image4.png"
+ alt: "Description of fourth image"
+---
+```
+
+### 2. Import and use the Gallery component
+
+#### Standalone Usage
+```mdx
+import Gallery from '@site/src/components/Common/Gallery';
+
+
+```
+
+#### With SampleLayout
+```mdx
+import { SampleLayout } from '@site/src/components/Samples';
+import Gallery from '@site/src/components/Common/Gallery';
+
+}
+>
+ ## Overview
+ ...
+
+```
+
+When using the `gallery` prop with `SampleLayout`:
+- **Mobile**: Gallery appears at the top, right after the title and above the ActionsCard
+- **Desktop**: Gallery appears in the main content area before the Overview section
+
+
+## Customization
+
+You can pass a custom className to adjust the gallery styling:
+
+```mdx
+
+```
+
diff --git a/templates/home.mdx b/templates/home.mdx
index 4899092a28..8d174f3a7f 100644
--- a/templates/home.mdx
+++ b/templates/home.mdx
@@ -5,10 +5,6 @@ pagination_prev: null
title: "Documentation Templates"
---
-
-
-
-
# Documentation Templates
Welcome to the documentation authoring toolkit. This section serves as a reference library for the standardized building blocks used throughout our documentation.
diff --git a/templates/icon-gallery.mdx b/templates/icon-gallery.mdx
index a96fa529c9..dd3391a16a 100644
--- a/templates/icon-gallery.mdx
+++ b/templates/icon-gallery.mdx
@@ -12,10 +12,6 @@ see_also:
import IconGallery from "@site/src/components/IconGallery/IconGallery";
import Admonition from "@theme/Admonition";
-
-
-
-
# Icon Gallery
This page showcases all available icons in the project along with their names. Click on any icon to copy its name to the clipboard.
diff --git a/templates/introduction-samples.mdx b/templates/introduction-samples.mdx
new file mode 100644
index 0000000000..ed287592f2
--- /dev/null
+++ b/templates/introduction-samples.mdx
@@ -0,0 +1,112 @@
+---
+title: "Samples: Introduction"
+hide_table_of_contents: false
+sidebar_label: Introduction
+see_also:
+ - title: "Adding new samples"
+ link: "/templates/new-samples"
+ source: "docs"
+ path: "Templates > Samples"
+ - title: "Sample tags"
+ link: "/templates/tags-samples"
+ source: "docs"
+ path: "Templates > Samples"
+---
+
+import Admonition from "@theme/Admonition";
+import Panel from "@site/src/components/Panel";
+
+The Samples system provides a comprehensive platform for showcasing production-ready code samples, architecture patterns, and starter kits. It features a filterable hub page, detailed sample pages with metadata, and a plugin-based architecture for automatic indexing.
+
+## Architecture Overview
+
+The Samples system consists of three main parts:
+
+### 1. Samples Hub (`/samples`)
+
+A filterable, searchable landing page that displays all available samples with:
+- **Filter sidebar** with three tag categories (Challenges & Solutions, Features, Tech Stack)
+- **Sample cards** showing title, description, image, and tags
+- **Match logic toggle** (Any/All) for flexible filtering
+- **URL-based state** for shareable filtered views
+
+### 2. Sample Detail Pages
+
+Individual sample pages with a two-column layout:
+- **Main content area** for documentation, code examples, and feature descriptions
+- **Metadata sidebar** with actions, tags, and related resources
+
+### 3. Plugin System
+
+The `recent-samples-plugin` automatically:
+- Scans the `samples/` directory for `.mdx` files
+- Loads tag definitions from `samples/tags/` (organized by category)
+- Indexes samples with their metadata and tags
+- Exposes data via Docusaurus global plugin data
+
+## Key Components
+
+| Component | Purpose | Location |
+|---|---|---|
+| `SamplesHomePage` | Main hub page with filters and grid | `src/components/Samples/Hub/SamplesHomePage.tsx` |
+| `SampleCard` | Individual sample card in the grid | `src/components/Samples/Hub/Partials/SampleCard.tsx` |
+| `SamplesFilter` | Filter sidebar with categories | `src/components/Samples/Hub/Partials/SamplesFilter.tsx` |
+| `SampleLayout` | Two-column layout for detail pages | `src/components/Samples/Overview/SampleLayout.tsx` |
+| `SampleMetadataColumn` | Sidebar with tags and metadata | `src/components/Samples/Overview/Partials/SampleMetadataColumn.tsx` |
+| `ActionsCard` | GitHub and demo links | `src/components/Samples/Overview/Partials/ActionsCard.tsx` |
+| `RelatedResource` | Links to guides/docs | `src/components/Samples/Overview/Partials/RelatedResource.tsx` |
+| `FeatureAccordion` | Expandable feature descriptions | `src/components/Samples/Overview/Partials/FeatureAccordion.tsx` |
+
+## Tag System
+
+Samples use a **three-category tag system**:
+
+1. **Challenges & Solutions** (`samples/tags/challenges-solutions.yml`) - What business problems the sample solves
+ - Examples: `cloud-tax`, `semantic-search`, `integration-patterns`
+
+2. **Features** (`samples/tags/feature.yml`) - Which RavenDB features are demonstrated
+ - Examples: `vector-search`, `document-refresh`, `include`, `ai-agents`
+
+3. **Tech Stack** (`samples/tags/tech-stack.yml`) - Technologies and frameworks used
+ - Examples: `csharp`, `nodejs`, `aspire`, `azure-functions`
+
+
+ Unlike Guides which use a single `tags.yml` file, Samples organize tags into separate category files. This enables the filter UI to group tags logically and allows for "Any/All" matching within categories.
+
+
+## File Structure
+
+```
+samples/
+├── home.mdx # Hub page (uses SamplesHomePage component)
+├── the-ravens-library.mdx # Example sample
+├── tags/
+│ ├── challenges-solutions.yml # Challenges & solutions tags
+│ ├── feature.yml # RavenDB feature tags
+│ └── tech-stack.yml # Technology stack tags
+└── ... # Additional sample files
+
+src/components/Samples/
+├── Hub/ # Hub page components
+│ ├── SamplesHomePage.tsx
+│ └── Partials/
+│ ├── SampleCard.tsx
+│ ├── SamplesGrid.tsx
+│ ├── SamplesFilter.tsx
+│ ├── FilterCategory.tsx
+│ ├── SamplesHeader.tsx
+│ └── SamplesDecoration.tsx
+├── Overview/ # Detail page components
+│ ├── SampleLayout.tsx
+│ └── Partials/
+│ ├── SampleMetadataColumn.tsx
+│ ├── ActionsCard.tsx
+│ ├── RelatedResource.tsx
+│ └── FeatureAccordion.tsx
+├── index.ts # Component exports
+└── types.ts # TypeScript types
+
+src/plugins/
+└── recent-samples-plugin.ts # Indexing plugin
+```
+
diff --git a/templates/introduction.mdx b/templates/introduction.mdx
index 3cc39ff65c..ac6233ed75 100644
--- a/templates/introduction.mdx
+++ b/templates/introduction.mdx
@@ -8,10 +8,6 @@ import CardWithImage from "@site/src/components/Common/CardWithImage";
import CardWithImageHorizontal from "@site/src/components/Common/CardWithImageHorizontal";
import ColGrid from "@site/src/components/ColGrid";
-
-
-
-
# Start template
Use RavenDB to ship AI functionalities faster
diff --git a/templates/new-guides.mdx b/templates/new-guides.mdx
index 17de6c17d0..9494184ae2 100644
--- a/templates/new-guides.mdx
+++ b/templates/new-guides.mdx
@@ -17,10 +17,6 @@ import Admonition from "@theme/Admonition";
import Panel from "@site/src/components/Panel";
import Link from "@docusaurus/Link";
-
-
-
-
# Adding new guides
This template explains how to create new Guides.
@@ -56,7 +52,7 @@ Intro paragraph...
**Fields explained**
- `title` – main page title displayed in the header.
-- `publishedAt` – publication date (YYYY-MM-DD format). Displayed in the article header.
+- `published_at` – publication date (YYYY-MM-DD format). Displayed in the article header.
- `author` – name of the guide author (single author only). Displayed in the article header below the title. Must match exactly with a key in `docs/authors.json`.
- `tags` – keys from `guides/tags.yml` (see Tags). Displayed below the title.
- `image` – banner image displayed at the top of the article; can be a string or a themed image object (see Themed Images template). If not provided, a gradient background with icon is shown.
@@ -104,11 +100,11 @@ Use this pattern when the actual content lives elsewhere but you still want it l
```mdx
---
title: "Begin analysis with OLAP ETL"
-publishedAt: 2025-12-23
+published_at: 2025-12-23
author: "Author Name"
tags: [integration, getting-started]
description: "Short description shown in cards and lists."
-externalUrl: "https://ravendb.net/articles/begin-analysis-with-olap-etl"
+external_url: "https://ravendb.net/articles/begin-analysis-with-olap-etl"
image: "https://ravendb.net/wp-content/uploads/2025/12/OLAP-article-image.svg"
---
diff --git a/templates/new-samples.mdx b/templates/new-samples.mdx
new file mode 100644
index 0000000000..7c397d3294
--- /dev/null
+++ b/templates/new-samples.mdx
@@ -0,0 +1,192 @@
+---
+title: "Samples: Adding new samples"
+hide_table_of_contents: false
+sidebar_label: Adding new samples
+see_also:
+ - title: "Samples Introduction"
+ link: "/templates/introduction-samples"
+ source: "docs"
+ path: "Templates > Samples"
+ - title: "Sample tags"
+ link: "/templates/tags-samples"
+ source: "docs"
+ path: "Templates > Samples"
+ - title: "Sample components"
+ link: "/templates/components-samples"
+ source: "docs"
+ path: "Templates > Samples"
+---
+
+import Admonition from "@theme/Admonition";
+import Panel from "@site/src/components/Panel";
+import Link from "@docusaurus/Link";
+
+This guide explains how to create new sample pages in the Samples section.
+
+## Create the file
+
+Place the file under the `samples` directory:
+
+```
+samples/my-new-sample.mdx
+```
+
+## Frontmatter Schema
+
+
+
+```mdx
+---
+title: "My Sample Application"
+description: "A production-ready example demonstrating RavenDB features."
+challenges_solutions_tags: [semantic-search, integration-patterns]
+feature_tags: [vector-search, include, document-refresh]
+tech_stack_tags: [csharp, aspire, azure-functions]
+image: "/img/samples/my-sample/cover.webp"
+img_alt: "My Sample Application Screenshot"
+category: "Ecommerce"
+license: "MIT License"
+license_url: "https://opensource.org/licenses/MIT"
+repository_url: "https://github.com/ravendb/my-sample-repo"
+demo_url: "https://demo.example.com"
+languages: ["C#"]
+gallery:
+ - src: "/img/samples/my-sample/screenshot-1.webp"
+ alt: "Main interface"
+ - src: "/img/samples/my-sample/screenshot-2.webp"
+ alt: "Admin dashboard"
+related_resources:
+ - type: guide
+ subtitle: "Related Guide Title"
+ article_key: "guide-slug"
+ - type: documentation
+ documentation_type: docs
+ subtitle: "Vector Search Overview"
+ article_key: "ai-integration/vector-search/overview"
+---
+```
+
+
+
+### Frontmatter Fields
+
+| Field | Type | Required | Description |
+|---|---|---|---|
+| `title` | `string` | ✅ | Sample name displayed in cards and page header |
+| `description` | `string` | ✅ | Short summary shown in sample cards |
+| `challenges_solutions_tags` | `string[]` | ✅ | Challenges & solutions tags from `samples/tags/challenges-solutions.yml` (kebab-case) |
+| `feature_tags` | `string[]` | ✅ | RavenDB feature tags from `samples/tags/feature.yml` (kebab-case) |
+| `tech_stack_tags` | `string[]` | ✅ | Technology tags from `samples/tags/tech-stack.yml` (kebab-case) |
+| `image` | `string` | ❌ | Cover image path (shown in sample cards) |
+| `img_alt` | `string` | ❌ | Alt text for the cover image |
+| `category` | `string` | ❌ | Business category (e.g., "Ecommerce", "Healthcare") - displayed in metadata sidebar |
+| `license` | `string` | ❌ | License type (e.g., "MIT License", "Apache 2.0") - displayed in metadata sidebar |
+| `license_url` | `string` | ❌ | License URL (e.g., `https://opensource.org/licenses/MIT`) - links the sidebar label and feeds JSON-LD |
+| `repository_url` | `string` | ❌ | GitHub repository URL - renders "Browse code" button; used in `SoftwareSourceCode` JSON-LD for SEO |
+| `demo_url` | `string` | ❌ | Live demo URL - renders "View demo" button in the sidebar |
+| `languages` | `string[]` | ❌ | Programming languages (e.g., `["C#"]`) - used in `SoftwareSourceCode` JSON-LD for SEO |
+| `gallery` | `array` | ❌ | Array of screenshot objects with `src` and `alt` properties |
+| `related_resources` | `array` | ❌ | Related guides and docs shown in the sidebar — see schema below |
+
+Each `related_resources` item accepts:
+
+| Field | Type | Required | Description |
+|---|---|---|---|
+| `type` | `"guide"` \| `"documentation"` | ✅ | Resource type |
+| `documentation_type` | `"docs"` \| `"cloud"` | ❌ | Documentation section (only for `type: documentation`) |
+| `subtitle` | `string` | ✅ | Display text |
+| `article_key` | `string` | ✅ | Article path without version prefix (e.g., `ai-integration/vector-search/overview`) |
+
+
+ All tag keys must exist in their respective YAML files (`samples/tags/challenges-solutions.yml`, `feature.yml`, `tech-stack.yml`). Using undefined tags will cause them to display with their raw key value instead of a formatted label.
+
+
+## Page Structure
+
+### Basic Layout
+
+
+
+```mdx
+---
+title: "My Sample"
+description: "Sample description"
+challenges_solutions_tags: [semantic-search]
+feature_tags: [vector-search]
+tech_stack_tags: [csharp]
+license: "MIT License"
+license_url: "https://opensource.org/licenses/MIT"
+repository_url: "https://github.com/ravendb/my-sample-repo"
+languages: ["C#"]
+related_resources:
+ - type: guide
+ subtitle: "Related Guide Title"
+ article_key: "guide-slug"
+ - type: documentation
+ documentation_type: docs
+ subtitle: "Vector Search Overview"
+ article_key: "ai-integration/vector-search/overview"
+---
+
+import { FeatureAccordion, SampleLayout } from '@site/src/components/Samples';
+
+
+
+## Overview
+
+Describe what the sample does and what problems it solves...
+
+## Features used
+
+
+ Detailed explanation of how vector search is used in this sample...
+
+ // Code example
+
+
+
+```
+
+
+
+
+ The `gallery` prop on `SampleLayout` provides optimal responsive behavior:
+
+ - **Mobile**: Gallery appears at the top, right after the page title and above the ActionsCard
+ - **Desktop**: Gallery appears in the main content area, before the Overview section
+
+ `SampleLayout` reads `gallery` from the `gallery` frontmatter field automatically. If the field is absent or empty, no gallery is rendered.
+
+
+
+ **Do NOT add a `#` heading in your markdown content.**
+
+ The `title` frontmatter is automatically rendered as the page heading. Adding a `#` heading breaks the layout.
+
+ ✅ Correct:
+ ```mdx
+ ---
+ title: "My Sample"
+ ---
+
+ ## Overview
+
+ Content starts here...
+ ```
+
+ ❌ Wrong:
+ ```mdx
+ ---
+ title: "My Sample"
+ ---
+
+ # My Sample
+
+ ## Overview
+ ```
+
+
diff --git a/templates/see-also.mdx b/templates/see-also.mdx
index 419a493843..ddce7cd89f 100644
--- a/templates/see-also.mdx
+++ b/templates/see-also.mdx
@@ -7,10 +7,6 @@ sidebar_label: See also
import Admonition from "@theme/Admonition";
import SeeAlso from "@site/src/components/SeeAlso";
-
-
-
-
# See also
The `SeeAlso` component is used to display a list of related articles or external resources at the end of a page. It is automatically rendered in the page footer when the `see_also` property is defined in the page's frontmatter.
diff --git a/templates/tags-samples.mdx b/templates/tags-samples.mdx
new file mode 100644
index 0000000000..5d9bfcf1fe
--- /dev/null
+++ b/templates/tags-samples.mdx
@@ -0,0 +1,176 @@
+---
+title: "Samples: Tags"
+hide_table_of_contents: false
+sidebar_label: Tags
+see_also:
+ - title: "Adding new samples"
+ link: "/templates/new-samples"
+ source: "docs"
+ path: "Templates > Samples"
+ - title: "Samples Introduction"
+ link: "/templates/introduction-samples"
+ source: "docs"
+ path: "Templates > Samples"
+---
+
+import Admonition from "@theme/Admonition";
+import Panel from "@site/src/components/Panel";
+
+Samples use a **three-category tag system** to enable powerful filtering and discovery. Unlike Guides which use a single flat tag list, Samples organize tags into separate category files.
+
+## Tag Categories
+
+### 1. Challenges & Solutions Tags (`samples/tags/challenges-solutions.yml`)
+
+These tags describe **what business problems** the sample solves.
+
+**Location:** `samples/tags/challenges-solutions.yml`
+
+**Some of the existing tags:**
+- `cloud-tax`
+- `gen-ai-data-enrichment`
+- `integration-patterns`
+- `semantic-search`
+
+**Example usage in frontmatter:**
+```yaml
+challenges_solutions_tags: [semantic-search, integration-patterns]
+```
+
+### 2. Feature Tags (`samples/tags/feature.yml`)
+
+These tags indicate **which RavenDB features** are demonstrated.
+
+**Location:** `samples/tags/feature.yml`
+
+**Some of the existing tags:**
+- `vector-search`
+- `document-refresh`
+- `include`
+- `azure-storage-queues-etl`
+- `ai-agents`
+- `full-text-search`
+
+**Example usage in frontmatter:**
+```yaml
+feature_tags: [vector-search, include, document-refresh]
+```
+
+### 3. Tech Stack Tags (`samples/tags/tech-stack.yml`)
+
+These tags specify **technologies and frameworks** used in the sample.
+
+**Location:** `samples/tags/tech-stack.yml`
+
+**Some of the existing tags:**
+- `csharp`
+- `nodejs`
+- `python`
+- `java`
+- `php`
+- `aspire`
+- `azure-storage-queues`
+- `azure-functions`
+
+**Example usage in frontmatter:**
+```yaml
+tech_stack_tags: [csharp, aspire, azure-functions]
+```
+
+## Adding New Tags
+
+### Step 1: Choose the correct category
+
+Determine which category your tag belongs to:
+- **Challenges & Solutions** - Business problem or use case
+- **Feature** - RavenDB feature or capability
+- **Tech Stack** - Programming language, framework, or service
+
+### Step 2: Edit the appropriate YAML file
+
+
+
+Edit `samples/tags/challenges-solutions.yml`:
+
+```yaml
+cloud-tax:
+ label: "Cloud Tax"
+gen-ai-data-enrichment:
+ label: "Gen AI Data Enrichment"
+# Add your new tag:
+real-time-analytics:
+ label: "Real-Time Analytics"
+```
+
+
+
+
+
+Edit `samples/tags/feature.yml`:
+
+```yaml
+vector-search:
+ label: "Vector Search"
+document-refresh:
+ label: "Document Refresh"
+# Add your new tag:
+time-series:
+ label: "Time Series"
+```
+
+
+
+
+
+Edit `samples/tags/tech-stack.yml`:
+
+```yaml
+csharp:
+ label: "C#"
+nodejs:
+ label: "Node.js"
+# Add your new tag:
+nextjs:
+ label: "Next.js"
+```
+
+
+
+### Step 3: Use the tag in a sample
+
+Reference the tag key in your sample's frontmatter:
+
+```mdx
+---
+title: "My Sample"
+challenges_solutions_tags: [real-time-analytics]
+feature_tags: [time-series]
+tech_stack_tags: [nextjs]
+---
+```
+
+
+ Each tag entry requires only a `label` field. The key (e.g., `cloud-tax`) is used in frontmatter, while the label (e.g., "Cloud Tax") is displayed in the UI.
+
+
+## Tag Guidelines
+
+
+ - **Be specific**: Use `azure-storage-queues-etl` instead of just `etl`
+ - **Use kebab-case**: `gen-ai-data-enrichment` not `GenAIDataEnrichment`
+ - **Keep labels concise**: "Vector Search" not "Vector Search Functionality"
+ - **Avoid duplicates**: Check existing tags before adding new ones
+ - **Stay consistent**: Follow naming patterns of existing tags
+
+
+
+ The following tech stack tags are treated specially as "language tags" and displayed with colored badges:
+ - `csharp`
+ - `java`
+ - `python`
+ - `php`
+ - `nodejs`
+
+ These should only be used for the primary programming language of the sample.
+
+
diff --git a/templates/tags.mdx b/templates/tags.mdx
index 6f40e217b9..7853b2c5a2 100644
--- a/templates/tags.mdx
+++ b/templates/tags.mdx
@@ -16,10 +16,6 @@ see_also:
import Admonition from "@theme/Admonition";
import Panel from "@site/src/components/Panel";
-
-
-
-
# Tags
## Add a new tag
diff --git a/templates/themed-images.mdx b/templates/themed-images.mdx
index 407d00bcbb..ae6b63c977 100644
--- a/templates/themed-images.mdx
+++ b/templates/themed-images.mdx
@@ -12,10 +12,6 @@ import ColGrid from "@site/src/components/ColGrid";
import lightImage from '@site/static/img/templates/light-image.png';
import darkImage from '@site/static/img/templates/dark-image.png';
-
-
-
-
# Themed Images overview
This guide shows how to use `ThemedImage` component to display different images for light and dark themes, ensuring optimal visual appearance in both modes.
@@ -30,7 +26,7 @@ import ThemedImage from '@theme/ThemedImage';
### Basic usage
-````mdx
+```mdx
import ThemedImage from '@theme/ThemedImage';
import lightImage from '@site/static/img/templates/light-image.png';
import darkImage from '@site/static/img/templates/dark-image.png';
@@ -42,7 +38,7 @@ import darkImage from '@site/static/img/templates/dark-image.png';
dark: darkImage,
}}
/>
-````
+```
#### Live example
@@ -98,96 +94,7 @@ import darkImage from '@site/static/img/templates/dark-image.png';
/>
```
-## Using ThemedImage in Card components
-Both `CardWithImage` and `CardWithImageHorizontal` support themed images by passing an object with `light` and `dark` properties to the `imgSrc` prop.
-
-### CardWithImage with themed images
-
-```mdx
-import CardWithImage from "@site/src/components/Common/CardWithImage";
-import lightImage from '@site/static/img/templates/light-image.png';
-import darkImage from '@site/static/img/templates/dark-image.png';
-
-
-```
-
-#### Live example
-
-
-
-
-
-### CardWithImageHorizontal with themed images
-
-```mdx
-import CardWithImageHorizontal from "@site/src/components/Common/CardWithImageHorizontal";
-import lightImage from '@site/static/img/templates/light-image.png';
-import darkImage from '@site/static/img/templates/dark-image.png';
-
-
-```
-
-#### Live example
-
-
-
-
-
-### Fallback to single image
-
-Both card components maintain backward compatibility. If you pass a string instead of an object, they'll use a regular `
` tag:
-
-```mdx
-
-```
-#### Live example
-
-
-
-
## Best practices
@@ -197,9 +104,6 @@ Both card components maintain backward compatibility. If you pass a string inste
- **Optimize images**: Use appropriate image formats and compression for web performance.
- **Test both themes**: Verify that images look good in both light and dark modes.
-
-When using themed images in card components, the component automatically detects the object format and renders the appropriate image component. For single images, use a string; for themed images, use an object with `light` and `dark` properties.
-
## Props
@@ -214,12 +118,3 @@ When using themed images in card components, the component automatically detects
| height | number \| string | — | Image height (optional). |
| style | React.CSSProperties | — | Inline styles for the image (optional). |
-### CardWithImage / CardWithImageHorizontal
-
-The `imgSrc` prop accepts either:
-
-- **String**: Single image URL (backward compatible)
-- **Object**: `{ light: string; dark: string }` for themed images
-
-When an object is provided, the component automatically uses `ThemedImage` internally.
-
diff --git a/versioned_docs/version-1.0/home.mdx b/versioned_docs/version-1.0/home.mdx
index 614ef33eea..0c34d76a6f 100644
--- a/versioned_docs/version-1.0/home.mdx
+++ b/versioned_docs/version-1.0/home.mdx
@@ -2,7 +2,7 @@
slug: /
pagination_next: null
pagination_prev: null
-wrapperClassName: docs-home-page
+wrapperClassName: docsHomePage
hide_table_of_contents: true
---
diff --git a/versioned_docs/version-2.0/home.mdx b/versioned_docs/version-2.0/home.mdx
index 614ef33eea..0c34d76a6f 100644
--- a/versioned_docs/version-2.0/home.mdx
+++ b/versioned_docs/version-2.0/home.mdx
@@ -2,7 +2,7 @@
slug: /
pagination_next: null
pagination_prev: null
-wrapperClassName: docs-home-page
+wrapperClassName: docsHomePage
hide_table_of_contents: true
---
diff --git a/versioned_docs/version-2.5/home.mdx b/versioned_docs/version-2.5/home.mdx
index 614ef33eea..0c34d76a6f 100644
--- a/versioned_docs/version-2.5/home.mdx
+++ b/versioned_docs/version-2.5/home.mdx
@@ -2,7 +2,7 @@
slug: /
pagination_next: null
pagination_prev: null
-wrapperClassName: docs-home-page
+wrapperClassName: docsHomePage
hide_table_of_contents: true
---
diff --git a/versioned_docs/version-3.0/home.mdx b/versioned_docs/version-3.0/home.mdx
index f694bf8226..a1935c0184 100644
--- a/versioned_docs/version-3.0/home.mdx
+++ b/versioned_docs/version-3.0/home.mdx
@@ -2,7 +2,7 @@
slug: /
pagination_next: null
pagination_prev: null
-wrapperClassName: docs-home-page
+wrapperClassName: docsHomePage
hide_table_of_contents: true
---
diff --git a/versioned_docs/version-3.5/home.mdx b/versioned_docs/version-3.5/home.mdx
index f694bf8226..a1935c0184 100644
--- a/versioned_docs/version-3.5/home.mdx
+++ b/versioned_docs/version-3.5/home.mdx
@@ -2,7 +2,7 @@
slug: /
pagination_next: null
pagination_prev: null
-wrapperClassName: docs-home-page
+wrapperClassName: docsHomePage
hide_table_of_contents: true
---
diff --git a/versioned_docs/version-4.0/home.mdx b/versioned_docs/version-4.0/home.mdx
index f694bf8226..a1935c0184 100644
--- a/versioned_docs/version-4.0/home.mdx
+++ b/versioned_docs/version-4.0/home.mdx
@@ -2,7 +2,7 @@
slug: /
pagination_next: null
pagination_prev: null
-wrapperClassName: docs-home-page
+wrapperClassName: docsHomePage
hide_table_of_contents: true
---
diff --git a/versioned_docs/version-4.1/home.mdx b/versioned_docs/version-4.1/home.mdx
index f694bf8226..a1935c0184 100644
--- a/versioned_docs/version-4.1/home.mdx
+++ b/versioned_docs/version-4.1/home.mdx
@@ -2,7 +2,7 @@
slug: /
pagination_next: null
pagination_prev: null
-wrapperClassName: docs-home-page
+wrapperClassName: docsHomePage
hide_table_of_contents: true
---
diff --git a/versioned_docs/version-4.2/home.mdx b/versioned_docs/version-4.2/home.mdx
index f694bf8226..a1935c0184 100644
--- a/versioned_docs/version-4.2/home.mdx
+++ b/versioned_docs/version-4.2/home.mdx
@@ -2,7 +2,7 @@
slug: /
pagination_next: null
pagination_prev: null
-wrapperClassName: docs-home-page
+wrapperClassName: docsHomePage
hide_table_of_contents: true
---
diff --git a/versioned_docs/version-5.0/home.mdx b/versioned_docs/version-5.0/home.mdx
index f694bf8226..a1935c0184 100644
--- a/versioned_docs/version-5.0/home.mdx
+++ b/versioned_docs/version-5.0/home.mdx
@@ -2,7 +2,7 @@
slug: /
pagination_next: null
pagination_prev: null
-wrapperClassName: docs-home-page
+wrapperClassName: docsHomePage
hide_table_of_contents: true
---
diff --git a/versioned_docs/version-5.1/home.mdx b/versioned_docs/version-5.1/home.mdx
index f694bf8226..a1935c0184 100644
--- a/versioned_docs/version-5.1/home.mdx
+++ b/versioned_docs/version-5.1/home.mdx
@@ -2,7 +2,7 @@
slug: /
pagination_next: null
pagination_prev: null
-wrapperClassName: docs-home-page
+wrapperClassName: docsHomePage
hide_table_of_contents: true
---
diff --git a/versioned_docs/version-5.2/home.mdx b/versioned_docs/version-5.2/home.mdx
index f694bf8226..a1935c0184 100644
--- a/versioned_docs/version-5.2/home.mdx
+++ b/versioned_docs/version-5.2/home.mdx
@@ -2,7 +2,7 @@
slug: /
pagination_next: null
pagination_prev: null
-wrapperClassName: docs-home-page
+wrapperClassName: docsHomePage
hide_table_of_contents: true
---
diff --git a/versioned_docs/version-5.3/home.mdx b/versioned_docs/version-5.3/home.mdx
index f694bf8226..a1935c0184 100644
--- a/versioned_docs/version-5.3/home.mdx
+++ b/versioned_docs/version-5.3/home.mdx
@@ -2,7 +2,7 @@
slug: /
pagination_next: null
pagination_prev: null
-wrapperClassName: docs-home-page
+wrapperClassName: docsHomePage
hide_table_of_contents: true
---
diff --git a/versioned_docs/version-5.4/home.mdx b/versioned_docs/version-5.4/home.mdx
index f694bf8226..a1935c0184 100644
--- a/versioned_docs/version-5.4/home.mdx
+++ b/versioned_docs/version-5.4/home.mdx
@@ -2,7 +2,7 @@
slug: /
pagination_next: null
pagination_prev: null
-wrapperClassName: docs-home-page
+wrapperClassName: docsHomePage
hide_table_of_contents: true
---
diff --git a/versioned_docs/version-6.0/home.mdx b/versioned_docs/version-6.0/home.mdx
index f694bf8226..a1935c0184 100644
--- a/versioned_docs/version-6.0/home.mdx
+++ b/versioned_docs/version-6.0/home.mdx
@@ -2,7 +2,7 @@
slug: /
pagination_next: null
pagination_prev: null
-wrapperClassName: docs-home-page
+wrapperClassName: docsHomePage
hide_table_of_contents: true
---
diff --git a/versioned_docs/version-6.2/home.mdx b/versioned_docs/version-6.2/home.mdx
index f694bf8226..a1935c0184 100644
--- a/versioned_docs/version-6.2/home.mdx
+++ b/versioned_docs/version-6.2/home.mdx
@@ -2,7 +2,7 @@
slug: /
pagination_next: null
pagination_prev: null
-wrapperClassName: docs-home-page
+wrapperClassName: docsHomePage
hide_table_of_contents: true
---
diff --git a/versioned_docs/version-7.0/home.mdx b/versioned_docs/version-7.0/home.mdx
index f694bf8226..a1935c0184 100644
--- a/versioned_docs/version-7.0/home.mdx
+++ b/versioned_docs/version-7.0/home.mdx
@@ -2,7 +2,7 @@
slug: /
pagination_next: null
pagination_prev: null
-wrapperClassName: docs-home-page
+wrapperClassName: docsHomePage
hide_table_of_contents: true
---
diff --git a/versioned_docs/version-7.1/home.mdx b/versioned_docs/version-7.1/home.mdx
index f694bf8226..a1935c0184 100644
--- a/versioned_docs/version-7.1/home.mdx
+++ b/versioned_docs/version-7.1/home.mdx
@@ -2,7 +2,7 @@
slug: /
pagination_next: null
pagination_prev: null
-wrapperClassName: docs-home-page
+wrapperClassName: docsHomePage
hide_table_of_contents: true
---