From ca7ae086e8d6e80f6efc969d541b390328a6d143 Mon Sep 17 00:00:00 2001 From: Ogulcan Celik Date: Tue, 14 Jul 2026 02:41:24 +0300 Subject: [PATCH] fix(website): scope docs search by locale and channel --- website/astro.config.mjs | 2 ++ website/package.json | 3 +- website/src/components/Head.astro | 9 +++++ website/src/components/Search.astro | 52 +++++++++++++++++++++++++++++ website/src/content.config.ts | 15 +-------- website/src/docs-path.test.ts | 32 ++++++++++++++++++ website/src/docs-path.ts | 20 +++++++++++ 7 files changed, 118 insertions(+), 15 deletions(-) create mode 100644 website/src/components/Head.astro create mode 100644 website/src/components/Search.astro create mode 100644 website/src/docs-path.test.ts create mode 100644 website/src/docs-path.ts 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}`; +}