diff --git a/website/astro.config.mjs b/website/astro.config.mjs
index 85f123de..f617e900 100644
--- a/website/astro.config.mjs
+++ b/website/astro.config.mjs
@@ -73,7 +73,9 @@ export default defineConfig({
],
components: {
Banner: './src/components/Banner.astro',
+ Head: './src/components/Head.astro',
Header: './src/components/Header.astro',
+ Search: './src/components/Search.astro',
Sidebar: './src/components/Sidebar.astro',
SiteTitle: './src/components/SiteTitle.astro',
},
diff --git a/website/package.json b/website/package.json
index e3636c1a..4e03eea0 100644
--- a/website/package.json
+++ b/website/package.json
@@ -5,7 +5,8 @@
"scripts": {
"prepare-docs": "node scripts/prepare-docs.mjs",
"dev": "node scripts/prepare-docs.mjs && astro dev",
- "build": "node scripts/prepare-docs.mjs && astro build",
+ "test": "bun test src/docs-path.test.ts",
+ "build": "bun run test && node scripts/prepare-docs.mjs && astro build",
"preview": "astro preview"
},
"dependencies": {
diff --git a/website/src/components/Head.astro b/website/src/components/Head.astro
new file mode 100644
index 00000000..b1214cb1
--- /dev/null
+++ b/website/src/components/Head.astro
@@ -0,0 +1,9 @@
+---
+import { docsChannel } from '../docs-path';
+
+const { head } = Astro.locals.starlightRoute;
+const channel = docsChannel(Astro.url.pathname);
+---
+
+{head.map(({ tag: Tag, attrs, content }) => )}
+
diff --git a/website/src/components/Search.astro b/website/src/components/Search.astro
new file mode 100644
index 00000000..2a31ea24
--- /dev/null
+++ b/website/src/components/Search.astro
@@ -0,0 +1,52 @@
+---
+import StarlightSearch from '@astrojs/starlight/components/Search.astro';
+import { docsChannel } from '../docs-path';
+
+const channel = docsChannel(Astro.url.pathname);
+---
+
+
+
+
+
+
+
+
diff --git a/website/src/content.config.ts b/website/src/content.config.ts
index e84e3781..f4993be8 100644
--- a/website/src/content.config.ts
+++ b/website/src/content.config.ts
@@ -2,20 +2,7 @@ import { defineCollection, z } from 'astro:content';
import { glob } from 'astro/loaders';
import { docsLoader } from '@astrojs/starlight/loaders';
import { docsSchema } from '@astrojs/starlight/schema';
-
-const docsLocales = ['ja', 'zh-cn'];
-
-function docsPath({ entry }: { entry: string }) {
- const slug = entry.replace(/\.(md|mdx|markdown|mdown|mkdn|mkd|mdwn)$/i, '');
- const normalized = slug.replace(/\/index$/, '');
- for (const locale of docsLocales) {
- if (normalized === locale) return `${locale}/docs`;
- if (normalized.startsWith(`${locale}/`)) {
- return `${locale}/docs/${normalized.slice(locale.length + 1)}`;
- }
- }
- return normalized === 'index' ? 'docs' : `docs/${normalized}`;
-}
+import { docsPath } from './docs-path';
export const collections = {
docs: defineCollection({ loader: docsLoader({ generateId: docsPath }), schema: docsSchema() }),
diff --git a/website/src/docs-path.test.ts b/website/src/docs-path.test.ts
new file mode 100644
index 00000000..26f9a701
--- /dev/null
+++ b/website/src/docs-path.test.ts
@@ -0,0 +1,32 @@
+import { describe, expect, test } from 'bun:test';
+import { docsChannel, docsPath } from './docs-path';
+
+describe('docsChannel', () => {
+ test.each([
+ ['/docs/', 'stable'],
+ ['/ja/docs/install/', 'stable'],
+ ['/zh-cn/docs/', 'stable'],
+ ['/docs/preview/', 'preview'],
+ ['/ja/docs/preview/install/', 'preview'],
+ ['/zh-cn/docs/preview/', 'preview'],
+ ])('maps %s to %s', (pathname, expected) => {
+ expect(docsChannel(pathname)).toBe(expected);
+ });
+});
+
+describe('docsPath', () => {
+ test.each([
+ ['index.mdx', 'docs'],
+ ['install.mdx', 'docs/install'],
+ ['ja/index.mdx', 'ja/docs'],
+ ['ja/install.mdx', 'ja/docs/install'],
+ ['zh-cn/install.mdx', 'zh-cn/docs/install'],
+ ['preview/index.mdx', 'docs/preview'],
+ ['preview/install.mdx', 'docs/preview/install'],
+ ['preview/ja/index.mdx', 'ja/docs/preview'],
+ ['preview/ja/install.mdx', 'ja/docs/preview/install'],
+ ['preview/zh-cn/install.mdx', 'zh-cn/docs/preview/install'],
+ ])('maps %s to %s', (entry, expected) => {
+ expect(docsPath({ entry })).toBe(expected);
+ });
+});
diff --git a/website/src/docs-path.ts b/website/src/docs-path.ts
new file mode 100644
index 00000000..be022a4b
--- /dev/null
+++ b/website/src/docs-path.ts
@@ -0,0 +1,20 @@
+const docsLocales = new Set(['ja', 'zh-cn']);
+
+export function docsChannel(pathname: string) {
+ return /^\/(?:ja\/|zh-cn\/)?docs\/preview(?:\/|$)/.test(pathname) ? 'preview' : 'stable';
+}
+
+export function docsPath({ entry }: { entry: string }) {
+ const slug = entry.replace(/\.(md|mdx|markdown|mdown|mkdn|mkd|mdwn)$/i, '');
+ const normalized = slug.replace(/\/index$/, '');
+ const segments = normalized.split('/');
+ const localeIndex = segments[0] === 'preview' ? 1 : 0;
+ const locale = segments[localeIndex];
+
+ if (locale && docsLocales.has(locale)) {
+ segments.splice(localeIndex, 1);
+ return `${locale}/docs${segments.length > 0 ? `/${segments.join('/')}` : ''}`;
+ }
+
+ return normalized === 'index' ? 'docs' : `docs/${normalized}`;
+}