Skip to content

Commit bf43978

Browse files
committed
Enhance SEO image generation
1 parent 3a2123c commit bf43978

File tree

15 files changed

+2057
-155
lines changed

15 files changed

+2057
-155
lines changed

.github/workflows/continuous-deployment.yml

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -50,28 +50,11 @@ jobs:
5050
# Configure DocumentDB version (can be overridden by repository variables)
5151
echo "DOCUMENTDB_VERSION=${{ vars.DOCUMENTDB_VERSION || 'latest' }}" >> $GITHUB_ENV
5252
echo "MULTI_VERSION=${{ vars.MULTI_VERSION || 'true' }}" >> $GITHUB_ENV
53-
- name: Detect package manager
54-
id: detect-package-manager
55-
run: |
56-
if [ -f "${{ github.workspace }}/yarn.lock" ]; then
57-
echo "manager=yarn" >> $GITHUB_OUTPUT
58-
echo "command=install" >> $GITHUB_OUTPUT
59-
echo "runner=yarn" >> $GITHUB_OUTPUT
60-
exit 0
61-
elif [ -f "${{ github.workspace }}/package.json" ]; then
62-
echo "manager=npm" >> $GITHUB_OUTPUT
63-
echo "command=ci" >> $GITHUB_OUTPUT
64-
echo "runner=npx --no-install" >> $GITHUB_OUTPUT
65-
exit 0
66-
else
67-
echo "Unable to determine package manager"
68-
exit 1
69-
fi
7053
- name: Setup Node.js
7154
uses: actions/setup-node@v5
7255
with:
7356
node-version: 24
74-
cache: ${{ steps.detect-package-manager.outputs.manager }}
57+
cache: npm
7558
- name: Restore cache
7659
uses: actions/cache@v4
7760
with:
@@ -83,11 +66,11 @@ jobs:
8366
restore-keys: |
8467
${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json', '**/yarn.lock') }}-
8568
- name: Install dependencies
86-
run: ${{ steps.detect-package-manager.outputs.manager }} ${{ steps.detect-package-manager.outputs.command }}
69+
run: npm ci
8770
- name: Build with Next.js
8871
env:
8972
NEXT_BASE_PATH: ${{ github.event.repository.name }}
90-
run: ${{ steps.detect-package-manager.outputs.runner }} next build
73+
run: npm run build
9174
- name: Download DocumentDB packages from latest release
9275
run: .github/scripts/download_packages.sh
9376
- name: Upload artifact

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,7 @@ yarn-error.log*
3434

3535
# typescript
3636
*.tsbuildinfo
37-
next-env.d.ts
37+
next-env.d.ts
38+
39+
# Built resources
40+
/public/open-graph/**/*

app/docs/[section]/[[...slug]]/page.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import Link from "next/link";
22
import { notFound } from 'next/navigation';
33
import { getAllArticlePaths, getArticleByPath } from "../../../services/articleService";
4+
import { getMetadata } from "../../../services/metadataService";
45
import ComingSoon from "../../../components/ComingSoon";
56
import Markdown from "../../../components/Markdown";
67

@@ -34,10 +35,11 @@ export async function generateMetadata({ params }: PageProps) {
3435
const selectedNavItem = navigation.find((item) => item.link.includes(file));
3536
const pageTitle = frontmatter.title || selectedNavItem?.title || section;
3637

37-
return {
38+
return getMetadata({
3839
title: `${pageTitle} - DocumentDB Documentation`,
39-
description: frontmatter.description || undefined,
40-
};
40+
description: frontmatter.description || `${pageTitle} - DocumentDB Documentation`,
41+
pagePath: `docs/${section}${slug.length ? '/' + slug.join('/') : ''}`
42+
});
4143
}
4244

4345
export default async function ArticlePage({ params }: PageProps) {

app/docs/reference/[type]/[category]/[name]/page.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ export async function generateMetadata({ params }: { params: Promise<{ type: str
1212
return getMetadata({
1313
title: `${data?.name || 'Reference'} - DocumentDB MQL Reference`,
1414
description: data?.description || data?.summary || '',
15-
extraKeywords: ['reference', type, category, name]
15+
extraKeywords: ['reference', type, category, name],
16+
pagePath: `docs/reference/${type}/${category}/${name}`
1617
});
1718
}
1819

app/docs/reference/[type]/[category]/page.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ export async function generateMetadata({ params }: { params: Promise<{ type: str
1818
return getMetadata({
1919
title: `${title} - DocumentDB MQL Reference`,
2020
description: description || '',
21-
extraKeywords: ['reference', type, category]
21+
extraKeywords: ['reference', type, category],
22+
pagePath: `docs/reference/${type}/${category}`
2223
});
2324
}
2425

app/docs/reference/[type]/page.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@ import { getMetadata } from "../../../services/metadataService";
77
import pluralize from 'pluralize';
88
import { capitalCase } from 'change-case';
99

10-
const allowed_types = ['operator', 'command'];
10+
const allowed_types = ['operators', 'commands'];
1111

1212
export const generateStaticParams = async (): Promise<{ type: string }[]> => [
13-
{ type: 'operator' },
14-
{ type: 'command' }
13+
{ type: 'operators' },
14+
{ type: 'commands' }
1515
];
1616

1717
export async function generateMetadata({ params }: { params: Promise<{ type: string }> }) {
@@ -21,7 +21,8 @@ export async function generateMetadata({ params }: { params: Promise<{ type: str
2121
return getMetadata({
2222
title: `${title} - DocumentDB MQL Reference`,
2323
description: description || '',
24-
extraKeywords: ['reference', type]
24+
extraKeywords: ['reference', type],
25+
pagePath: `docs/reference/${type}`
2526
});
2627
}
2728

app/docs/reference/layout.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ export default function ReferenceLayout({
1818
const groupedReferences = getReferencesGroupedByTypeAndCategory();
1919

2020
return (
21-
<div className="min-h-screen bg-neutral-900 relative overflow-hidden">
21+
<div className="min-h-screen bg-neutral-900 relative overflow-hidden max-h-screen">
2222
{/* Background elements */}
2323
<div className="absolute inset-0 bg-gradient-to-br from-neutral-900 via-neutral-800 to-black"></div>
2424
<div className="absolute inset-0 opacity-5">
@@ -28,9 +28,9 @@ export default function ReferenceLayout({
2828
style={{ animationDelay: "1.5s" }}
2929
></div>
3030
</div>
31-
<div className="relative flex min-h-screen">
32-
<div className="w-80 bg-neutral-800/50 backdrop-blur-sm border-r border-neutral-700/50 flex flex-col">
33-
<div className="p-6 border-b border-neutral-700/50">
31+
<div className="relative flex h-screen">
32+
<div className="w-80 bg-neutral-800/50 backdrop-blur-sm border-r border-neutral-700/50 flex flex-col h-full">
33+
<div className="p-6 border-b border-neutral-700/50 flex-shrink-0">
3434
<Link href="/docs" className="text-blue-400 hover:text-blue-300 text-sm mb-4 flex items-center transition-colors">
3535
<svg
3636
className="w-4 h-4 mr-2"
@@ -51,7 +51,7 @@ export default function ReferenceLayout({
5151
</div>
5252
<Index groupedReferences={groupedReferences} />
5353
</div>
54-
<article className="flex-1 p-8">
54+
<article className="flex-1 p-8 overflow-y-auto h-full">
5555
<div className="max-w-4xl">
5656
{children}
5757
</div>

app/services/contentService.ts

Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
import { getAllArticlePaths, getArticleByPath } from './articleService';
2+
import { getAllPosts } from './blogService';
3+
import { getReferencesGroupedByTypeAndCategory, getAllReferenceParams, getReferenceByPath } from './referenceService';
4+
import path from 'path';
5+
import { Entity } from '../types/Entity';
6+
7+
export function getAllContent(): Entity[] {
8+
const pages: Entity[] = [];
9+
10+
// 1. Home page
11+
pages.push({
12+
url: '/',
13+
slug: 'home.png',
14+
title: 'DocumentDB',
15+
description: 'A powerful, scalable open-source document database solution',
16+
type: 'home',
17+
});
18+
19+
// 2. Docs landing
20+
pages.push({
21+
url: '/docs',
22+
slug: 'docs.png',
23+
title: 'Documentation',
24+
description: 'Complete DocumentDB documentation and guides',
25+
section: 'docs',
26+
type: 'landing',
27+
});
28+
29+
// 3. All article/documentation pages
30+
const articlePaths = getAllArticlePaths();
31+
for (const articlePath of articlePaths) {
32+
const article = getArticleByPath(articlePath.section, articlePath.slug);
33+
if (article) {
34+
const selectedNavItem = article.navigation.find((item: any) =>
35+
item.link.includes(articlePath.slug[articlePath.slug.length - 1] || 'index')
36+
);
37+
const title = article.frontmatter.title || selectedNavItem?.title || articlePath.section;
38+
39+
let url = `/docs/${articlePath.section}`;
40+
if (articlePath.slug.length > 0) {
41+
url += `/${articlePath.slug.join('/')}`;
42+
}
43+
44+
const mdFilePath = path.join(
45+
process.cwd(),
46+
'articles',
47+
articlePath.section,
48+
...articlePath.slug,
49+
'index.md'
50+
);
51+
52+
// Convert URL to slug filename
53+
const slug = url === '/'
54+
? 'home.png'
55+
: url.slice(1).replace(/\//g, '-') + '.png';
56+
57+
pages.push({
58+
url,
59+
slug,
60+
title,
61+
description: article.frontmatter.description || `${title} - DocumentDB Documentation`,
62+
section: articlePath.section,
63+
type: 'docs',
64+
filePath: mdFilePath,
65+
});
66+
}
67+
}
68+
69+
// 4. Blogs landing
70+
pages.push({
71+
url: '/blogs',
72+
slug: 'blogs.png',
73+
title: 'Blog',
74+
description: 'Latest insights and updates from DocumentDB',
75+
section: 'blog',
76+
type: 'landing',
77+
});
78+
79+
// 5. Individual blog posts (external URIs)
80+
const posts = getAllPosts();
81+
for (const post of posts) {
82+
// Generate slug from title (for external blog posts without slugs)
83+
const slug = post.title
84+
.toLowerCase()
85+
.replace(/[^a-z0-9]+/g, '-')
86+
.replace(/^-+|-+$/g, '');
87+
88+
const url = `/blogs/${slug}`;
89+
const filename = url.slice(1).replace(/\//g, '-') + '.png';
90+
91+
pages.push({
92+
url,
93+
slug: filename,
94+
title: post.title,
95+
description: post.description,
96+
section: 'blog',
97+
type: 'blog',
98+
isExternal: true, // Mark as external since these redirect to external URIs
99+
});
100+
}
101+
102+
// 6. Reference landing page
103+
pages.push({
104+
url: '/docs/reference',
105+
slug: 'docs-reference.png',
106+
title: 'API Reference',
107+
description: 'Complete DocumentDB API reference documentation',
108+
section: 'reference',
109+
type: 'landing',
110+
});
111+
112+
// 7. Reference type pages (e.g., /docs/reference/commands)
113+
const referenceContent = getReferencesGroupedByTypeAndCategory();
114+
for (const [type] of Object.entries(referenceContent)) {
115+
const url = `/docs/reference/${type}`;
116+
const slug = url.slice(1).replace(/\//g, '-') + '.png';
117+
118+
pages.push({
119+
url,
120+
slug,
121+
title: `${type.charAt(0).toUpperCase() + type.slice(1)} Reference`,
122+
description: `DocumentDB ${type} reference documentation`,
123+
section: 'reference',
124+
type: 'landing',
125+
});
126+
}
127+
128+
// 8. Reference category pages (e.g., /docs/reference/operators/aggregation)
129+
for (const [type, categories] of Object.entries(referenceContent)) {
130+
for (const [category] of Object.entries(categories)) {
131+
const url = `/docs/reference/${type}/${category}`;
132+
const slug = url.slice(1).replace(/\//g, '-') + '.png';
133+
134+
pages.push({
135+
url,
136+
slug,
137+
title: `${category} - ${type.charAt(0).toUpperCase() + type.slice(1)}`,
138+
description: `${category} ${type} reference documentation`,
139+
section: 'reference',
140+
type: 'landing',
141+
});
142+
}
143+
}
144+
145+
// 9. Individual reference items
146+
const referenceParams = getAllReferenceParams();
147+
for (const param of referenceParams) {
148+
const reference = getReferenceByPath(param.type, param.category, param.name);
149+
if (reference) {
150+
const url = `/docs/reference/${param.type}/${param.category}/${param.name}`;
151+
const slug = url.slice(1).replace(/\//g, '-') + '.png';
152+
153+
const mdFilePath = path.join(
154+
process.cwd(),
155+
'reference',
156+
param.type,
157+
param.category,
158+
`${param.name}.yml`
159+
);
160+
161+
pages.push({
162+
url,
163+
slug,
164+
title: reference.name || param.name,
165+
description: reference.description || `${param.name} - DocumentDB Reference`,
166+
section: 'reference',
167+
type: 'reference',
168+
filePath: mdFilePath,
169+
});
170+
}
171+
}
172+
173+
// 10. Packages page
174+
pages.push({
175+
url: '/packages',
176+
slug: 'packages.png',
177+
title: 'Packages',
178+
description: 'Download and install DocumentDB packages',
179+
type: 'packages',
180+
});
181+
182+
return pages;
183+
}

0 commit comments

Comments
 (0)