Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app/ai/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export const metadata = getMetadata({
title: "DocumentDB for AI - Vector Search, RAG, and Embeddings",
description:
"Build AI applications with DocumentDB: a Mongo API-compatible document model, native vector search, PostgreSQL reliability, and self-hosted deployment.",
path: "/ai/",
extraKeywords: [
"AI database",
"vector search",
Expand Down
9 changes: 6 additions & 3 deletions app/docs/[section]/[[...slug]]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import Link from "next/link";
import { notFound, redirect } from 'next/navigation';
import { capitalCase } from 'change-case';
import { getAllArticlePaths, getArticleByPath } from "../../../services/articleService";
import { getMetadata } from "../../../services/metadataService";
import ComingSoon from "../../../components/ComingSoon";
import CommandSnippet from "../../../components/CommandSnippet";
import Markdown from "../../../components/Markdown";
Expand Down Expand Up @@ -48,10 +49,12 @@ export async function generateMetadata({ params }: PageProps) {
const selectedNavItem = navigation.find((item) => item.link.includes(file));
const pageTitle = frontmatter.title || selectedNavItem?.title || section;

return {
return getMetadata({
title: `${pageTitle} - DocumentDB Documentation`,
description: frontmatter.description || undefined,
};
description: frontmatter.description || '',
path: slug.length > 0 ? `/docs/${section}/${slug.join('/')}/` : `/docs/${section}/`,
type: 'article',
});
}

export default async function ArticlePage({ params }: PageProps) {
Expand Down
10 changes: 10 additions & 0 deletions app/docs/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
import Link from "next/link";
import { getArticleContent } from "../services/articleService";
import { getMetadata } from "../services/metadataService";

export function generateMetadata() {
const articleContent = getArticleContent();
return getMetadata({
title: `${articleContent.landing.title} - DocumentDB`,
description: articleContent.landing.description,
path: '/docs/',
});
}

export default function Docs() {
const articleContent = getArticleContent();
Expand Down
2 changes: 2 additions & 0 deletions app/docs/reference/[type]/[category]/[name]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ export async function generateMetadata({ params }: { params: Promise<{ type: str
return getMetadata({
title: `${data.frontmatter.title || name} - DocumentDB MQL Reference`,
description: data.frontmatter.description || '',
path: `/docs/reference/${type}/${category}/${name}/`,
type: 'article',
extraKeywords: ['reference', type, category, name]
});
}
Expand Down
3 changes: 2 additions & 1 deletion app/docs/reference/[type]/[category]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ export async function generateMetadata({ params }: { params: Promise<{ type: str
const title = `${capitalCase(category)} ${capitalCase(pluralize(type))}`;
const description = getCategoryDescription(type, category);
return getMetadata({
title: `${title} - DocumentDB MQL Reference`,
title: `${title} - DocumentDB MQL Reference`,
description: await sanitizeMarkdown(description),
path: `/docs/reference/${type}/${category}/`,
extraKeywords: ['reference', type, category]
});
}
Expand Down
3 changes: 2 additions & 1 deletion app/docs/reference/[type]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ export async function generateMetadata({ params }: { params: Promise<{ type: str
const title = capitalCase(pluralize(type));
const description = getTypeDescription(type);
return getMetadata({
title: `${title} - DocumentDB MQL Reference`,
title: `${title} - DocumentDB MQL Reference`,
description: await sanitizeMarkdown(description),
path: `/docs/reference/${type}/`,
extraKeywords: ['reference', type]
});
}
Expand Down
1 change: 1 addition & 0 deletions app/docs/reference/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export async function generateMetadata() {
return getMetadata({
title: 'DocumentDB MQL Reference',
description: await sanitizeMarkdown(description),
path: '/docs/reference/',
extraKeywords: ['reference']
});
}
Expand Down
1 change: 1 addition & 0 deletions app/kubernetes-operator/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ export const metadata = getMetadata({
title: "DocumentDB Kubernetes Operator",
description:
"Run DocumentDB on Kubernetes with a PostgreSQL foundation, replication, HA, backups, TLS, and hybrid or multi-cloud topologies.",
path: "/kubernetes-operator/",
extraKeywords: [
"Kubernetes",
"operator",
Expand Down
18 changes: 18 additions & 0 deletions app/packages/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { getMetadata } from "../services/metadataService";

// The packages page is a client component, so its metadata lives here.
export const metadata = getMetadata({
title: "Download DocumentDB - Docker, APT, and RPM Packages",
description:
"Run DocumentDB locally with Docker or install the PostgreSQL extension from GPG-signed APT and RPM packages for Ubuntu, Debian, and RHEL-compatible systems.",
path: "/packages/",
extraKeywords: ["download", "install", "Docker", "APT", "RPM", "Debian", "Ubuntu", "RHEL"],
});

export default function PackagesLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return children;
}
7 changes: 7 additions & 0 deletions app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,15 @@ import Image from "next/image";
import Link from "next/link";
import CommandSnippet from "./components/CommandSnippet";
import { documentdbKubernetesOperatorDocsUrl } from "./services/externalLinks";
import { getMetadata } from "./services/metadataService";
import { withBasePath } from "./services/sitePath";

export const metadata = getMetadata({
title: 'DocumentDB - Open Source Document Database',
description: 'A powerful, scalable open-source document database solution built on PostgreSQL for modern applications.',
path: '/',
});

type CapabilityIconName =
| "foundation"
| "index"
Expand Down
18 changes: 18 additions & 0 deletions app/samples/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { getMetadata } from "../services/metadataService";

// The samples page is a client component, so its metadata lives here.
export const metadata = getMetadata({
title: "DocumentDB Samples Gallery",
description:
"Ready-to-run DocumentDB code samples: vector search, RAG, semantic search, and full-stack applications in Python, Node.js, and TypeScript.",
path: "/samples/",
extraKeywords: ["samples", "examples", "vector search", "RAG", "Python", "Node.js", "TypeScript"],
});

export default function SamplesLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return children;
}
23 changes: 19 additions & 4 deletions app/services/metadataService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,32 @@ export const sanitizeMarkdown = async (markdown: string | undefined): Promise<st
return output.trim();
};

export const getMetadata = ({ title, description, extraKeywords = [] }: { title: string, description: string, extraKeywords?: string[] }): Metadata => ({
export const siteUrl = 'https://documentdb.io';

export const getMetadata = ({ title, description, path, type = 'website', extraKeywords = [] }: {
title: string,
description: string,
/**
* Site-relative path of the page (e.g. '/docs/reference/'), used as the
* canonical URL. Pages without a known path get no canonical tag.
*/
path?: string,
/** Open Graph object type; use 'article' for docs/reference content pages. */
type?: 'website' | 'article',
extraKeywords?: string[],
}): Metadata => ({
metadataBase: new URL(siteUrl),
keywords: [...getBaseKeywords(), ...extraKeywords],
title,
description,
...(path ? { alternates: { canonical: path } } : {}),
openGraph: {
type: 'article',
type,
title,
description,
images: [
{
url: 'https://documentdb.io/images/social-card.png',
url: `${siteUrl}/images/social-card.png`,
}
]
},
Expand All @@ -36,7 +51,7 @@ export const getMetadata = ({ title, description, extraKeywords = [] }: { title:
description,
images: [
{
url: 'https://documentdb.io/images/social-card.png',
url: `${siteUrl}/images/social-card.png`,
}
]
},
Expand Down