feat(docs): generate sitemap for docs site (#148)

* docs: add VidBee Docs suffix to all documentation page titles

Update the page title metadata generation to append "| VidBee Docs" to all documentation page titles for consistent branding across the site.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>

* docs: add canonical URLs to documentation pages

Add canonical URL metadata to all documentation pages to prevent search engine duplication issues and improve SEO rankings.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>

* feat(docs): add automatic sitemap

* fix(docs): align canonical base URL

* fix(docs): configure sitemap for static export

Add 'export const dynamic = "force-static"' to sitemap.ts to enable
static generation when using Next.js output: export mode. This fixes
the build error: "export const dynamic = 'force-static'/export const
revalidate not configured on route '/sitemap.xml'".

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* chore(docs): add favicon and icon assets

Add favicons and app icons in various sizes for better browser
and platform support.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
Nexmoe
2026-01-18 13:26:34 +08:00
committed by GitHub
parent cab86fe71c
commit b6c67b23f6
27 changed files with 154 additions and 13 deletions

101
docs/public/ICONS.md Normal file
View File

@@ -0,0 +1,101 @@
# VidBee Documentation Icons
This directory contains the VidBee logo in various sizes for use in the documentation site.
## Source
All icons are generated from the original VidBee application icon located at:
`/Users/air15/Documents/GitHub/VidBee/build/icon.png`
## Available Sizes
| Filename | Size | Use Case |
|----------|------|----------|
| `icon.png` | 512×512 | Default/Original icon |
| `icon-16.png` | 16×16 | Browser favicon (small) |
| `icon-32.png` | 32×32 | Browser favicon (standard) |
| `icon-48.png` | 48×48 | Browser favicon (large) |
| `icon-64.png` | 64×64 | Small UI elements |
| `icon-128.png` | 128×128 | Medium UI elements |
| `icon-192.png` | 192×192 | PWA icon (Android) |
| `icon-256.png` | 256×256 | Large UI elements |
| `icon-512.png` | 512×512 | PWA splash screen, high-res displays |
| `apple-touch-icon.png` | 180×180 | iOS/macOS home screen icon |
| `favicon.png` | 32×32 | Standard favicon |
## Usage in Next.js
### In `app/layout.tsx` or `app/favicon.ico`:
```tsx
import type { Metadata } from 'next'
export const metadata: Metadata = {
title: 'VidBee Documentation',
description: 'Official VidBee documentation',
icons: {
icon: [
{ url: '/icon-16.png', sizes: '16x16', type: 'image/png' },
{ url: '/icon-32.png', sizes: '32x32', type: 'image/png' },
{ url: '/icon-48.png', sizes: '48x48', type: 'image/png' },
],
apple: [
{ url: '/apple-touch-icon.png', sizes: '180x180', type: 'image/png' },
],
},
}
```
### For PWA (Progressive Web App):
Add to your `manifest.json` or `site.webmanifest`:
```json
{
"icons": [
{
"src": "/icon-192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "/icon-512.png",
"sizes": "512x512",
"type": "image/png"
}
]
}
```
## Regeneration
If you need to regenerate these icons from the source:
```bash
cd docs/public
SOURCE="/Users/air15/Documents/GitHub/VidBee/build/icon.png"
# Copy original
cp $SOURCE icon-original.png
# Generate sizes
sips -z 16 16 icon-original.png --out icon-16.png
sips -z 32 32 icon-original.png --out icon-32.png
sips -z 48 48 icon-original.png --out icon-48.png
sips -z 64 64 icon-original.png --out icon-64.png
sips -z 128 128 icon-original.png --out icon-128.png
sips -z 192 192 icon-original.png --out icon-192.png
sips -z 256 256 icon-original.png --out icon-256.png
sips -z 180 180 icon-original.png --out apple-touch-icon.png
# Create standard copies
cp icon-original.png icon-512.png
cp icon-original.png icon.png
cp icon-32.png favicon.png
```
## Notes
- All icons maintain the VidBee bee/honeycomb theme
- Icons use PNG format with transparency (RGBA)
- Generated using macOS `sips` tool for quality consistency

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

BIN
docs/public/favicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
docs/public/icon-128.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

BIN
docs/public/icon-16.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 924 B

BIN
docs/public/icon-192.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
docs/public/icon-256.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
docs/public/icon-32.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
docs/public/icon-48.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

BIN
docs/public/icon-512.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
docs/public/icon-64.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
docs/public/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -57,11 +57,17 @@ export async function generateMetadata(
const page = source.getPage(params.slug, params.lang);
if (!page) notFound();
const baseUrl = 'https://docs.vidbee.org';
const canonicalUrl = `${baseUrl}${page.url}`;
return {
title: page.data.title,
title: `${page.data.title} | VidBee Docs`,
description: page.data.description,
openGraph: {
images: getPageImage(page).url,
},
alternates: {
canonical: canonicalUrl,
},
};
}

34
docs/src/app/sitemap.ts Normal file
View File

@@ -0,0 +1,34 @@
import type { MetadataRoute } from 'next';
import { i18n } from '@/lib/i18n';
import { source } from '@/lib/source';
export const dynamic = 'force-static';
const baseUrl = 'https://docs.vidbee.org';
function buildPath(segments: string[]): string {
if (segments.length === 0) {
return '/';
}
return `/${segments.join('/')}/`;
}
export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
const params = source.generateParams();
return params.map(({ lang, slug }) => {
const segments: string[] = [];
if (lang && lang !== i18n.defaultLanguage) {
segments.push(lang);
}
if (slug && slug.length > 0) {
segments.push(...slug);
}
return {
url: `${baseUrl}${buildPath(segments)}`,
};
});
}

View File

@@ -660,4 +660,4 @@
"popularSection": "المنصات الرئيسية",
"viewAll": "عرض جميع المواقع المدعومة"
}
}
}

View File

@@ -660,4 +660,4 @@
"popularSection": "Hauptplattformen",
"viewAll": "Alle unterstützten Websites anzeigen"
}
}
}

View File

@@ -660,4 +660,4 @@
"popularSection": "Plataformas principales",
"viewAll": "Ver todos los sitios soportados"
}
}
}

View File

@@ -660,4 +660,4 @@
"popularSection": "Plateformes principales",
"viewAll": "Voir tous les sites supportés"
}
}
}

View File

@@ -660,4 +660,4 @@
"popularSection": "Platform utama",
"viewAll": "Lihat semua situs yang didukung"
}
}
}

View File

@@ -660,4 +660,4 @@
"popularSection": "Piattaforme principali",
"viewAll": "Visualizza tutti i siti supportati"
}
}
}

View File

@@ -660,4 +660,4 @@
"popularSection": "主要プラットフォーム",
"viewAll": "サポートされているすべてのサイトを表示"
}
}
}

View File

@@ -660,4 +660,4 @@
"popularSection": "주요 플랫폼",
"viewAll": "지원되는 모든 사이트 보기"
}
}
}

View File

@@ -660,4 +660,4 @@
"popularSection": "Plataformas principais",
"viewAll": "Ver todos os sites suportados"
}
}
}

View File

@@ -660,4 +660,4 @@
"popularSection": "Основные платформы",
"viewAll": "Просмотреть все поддерживаемые сайты"
}
}
}

View File

@@ -660,4 +660,4 @@
"popularSection": "主流平台",
"viewAll": "檢視全部支援的網站"
}
}
}

View File

@@ -660,4 +660,4 @@
"popularSection": "主流平台",
"viewAll": "查看全部支持的网站"
}
}
}