From 9366ac60f26ce1197c8843abf8cfacfd65ef524c Mon Sep 17 00:00:00 2001 From: javayhu Date: Sat, 29 Mar 2025 16:12:59 +0800 Subject: [PATCH] fix: fix search Chinese not work in docs - Added a guideline to use `pnpm` as the default package manager in TypeScript best practices. - Refactored the search API route to improve readability by simplifying the mapping of pages to search indexes. - Wrapped the GET handler with locale detection from the referer header and ensured the locale parameter is passed to the search API for better internationalization support. --- .cursor/rules/typescript-best-practices.mdc | 3 +- src/app/api/search/route.ts | 86 ++++++++++++++++----- 2 files changed, 69 insertions(+), 20 deletions(-) diff --git a/.cursor/rules/typescript-best-practices.mdc b/.cursor/rules/typescript-best-practices.mdc index 1cf8e7f..f6ba2af 100644 --- a/.cursor/rules/typescript-best-practices.mdc +++ b/.cursor/rules/typescript-best-practices.mdc @@ -10,4 +10,5 @@ alwaysApply: false - Use generics for reusable components and functions. - Use strict null checks to prevent null and undefined errors - Implement proper type inference using generics for reusable components. -- Utilize type guards and assertions for runtime type checking. \ No newline at end of file +- Utilize type guards and assertions for runtime type checking. +- Use `pnpm` as default package manager if run Command in Terminal. \ No newline at end of file diff --git a/src/app/api/search/route.ts b/src/app/api/search/route.ts index 21d502f..bcc52ee 100644 --- a/src/app/api/search/route.ts +++ b/src/app/api/search/route.ts @@ -11,29 +11,24 @@ import { docsI18nConfig } from '@/lib/docs/i18n'; * * 2. For special languages like Chinese, configure custom tokenizers: * https://fumadocs.vercel.app/docs/headless/search/orama#special-languages + * https://docs.orama.com/open-source/supported-languages/using-chinese-with-orama */ -export const { GET } = createI18nSearchAPI('advanced', { +const searchAPI = createI18nSearchAPI('advanced', { // Pass the i18n config for proper language detection i18n: docsI18nConfig, - + // Get all pages from all languages and map them to search indexes indexes: source.getLanguages().flatMap(({ language, pages }) => - pages.map((page) => { - console.log('--------------------------------'); - console.log('search index', language, page.data.title, page.url); - console.log('--------------------------------'); - return { - title: page.data.title, - description: page.data.description, - structuredData: page.data.structuredData, - id: page.url, - url: page.url, - // Set the locale explicitly for each page - locale: language, - }; - }), + pages.map((page) => ({ + title: page.data.title, + description: page.data.description, + structuredData: page.data.structuredData, + id: page.url, + url: page.url, + locale: language, + })), ), - + // Configure special language tokenizers and search options localeMap: { // Chinese configuration with Mandarin tokenizer @@ -48,13 +43,66 @@ export const { GET } = createI18nSearchAPI('advanced', { tolerance: 0, }, }, - + // Use the default English tokenizer for English content en: 'english', }, - + // Global search configuration search: { limit: 20, }, }); + +/** + * 1. Wrap the GET handler for debugging docs search + * 2. Detect locale from referer header, and add the locale parameter to the search API + * 3. Fumadocs core searchAPI get `locale` from searchParams, and pass it to the search API + * https://github.com/fuma-nama/fumadocs/blob/dev/packages/core/src/search/orama/create-endpoint.ts#L19 + */ +export const GET = async (request: Request) => { + const url = new URL(request.url); + const query = url.searchParams.get('query') || ''; + let locale = url.searchParams.get('locale') || docsI18nConfig.defaultLanguage; + + // detect locale from referer header + const referer = request.headers.get('referer'); + if (referer) { + try { + const refererUrl = new URL(referer); + console.log('search, referer pathname:', refererUrl.pathname); + const refererPathParts = refererUrl.pathname.split('/').filter(Boolean); + console.log('search, referer path parts:', refererPathParts); + if (refererPathParts.length > 0 && docsI18nConfig.languages.includes(refererPathParts[0])) { + locale = refererPathParts[0]; + console.log(`search, detected locale from referer: ${locale}`); + } + } catch (e) { + console.error('search, error parsing referer:', e); + } + } + + console.log(`search, request: query="${query}", detected locale="${locale}"`); + + // ensure locale parameter is passed to search API + const searchUrl = new URL(url); + searchUrl.searchParams.set('locale', locale); + + const modifiedRequest = new Request(searchUrl, { + headers: request.headers, + method: request.method, + body: request.body, + cache: request.cache, + credentials: request.credentials, + integrity: request.integrity, + keepalive: request.keepalive, + mode: request.mode, + redirect: request.redirect, + referrer: request.referrer, + referrerPolicy: request.referrerPolicy, + signal: request.signal, + }); + + const response = await searchAPI.GET(modifiedRequest); + return response; +};