खोज
क्लाइंट-साइड खोज जो बिना किसी API keys के तुरंत काम करती है, साथ ही वैकल्पिक होस्टेड और सिमेंटिक बैकएंड जिन पर आप अपने docs के बढ़ने के साथ स्विच कर सकते हैं।
Blume बिना किसी होस्टेड इन्फ्रास्ट्रक्चर और बिना API keys के लोकल खोज प्रदान करता है। यह ब्राउज़र में चलती है, blume dev और blume build दोनों में काम करती है, और केवल आपकी वास्तविक सामग्री को इंडेक्स करती है — नेविगेशन क्रोम और बाहर रखे गए पेज छोड़ दिए जाते हैं। जब आपकी ज़रूरतें इससे आगे बढ़ जाएँ, तो आप खोज के दिखने या व्यवहार करने के तरीके को बदले बिना किसी होस्टेड या सिमेंटिक बैकएंड पर स्विच कर सकते हैं — केवल आपके द्वारा कॉन्फ़िगर किया गया search.provider बदलता है।
Blume Fumadocs के प्रोवाइडर सेट की बराबरी करता है: Orama, FlexSearch, Algolia, Orama Cloud, Typesense, और Mixedbread (साथ ही Pagefind)। केवल कॉन्फ़िगर किए गए प्रोवाइडर का SDK ही आपके प्रोजेक्ट में इंस्टॉल होता है, इसलिए एक बैकएंड चुनने से बाकी कभी नहीं आते।
खोज का उपयोग
खोज को ⌘K (या Ctrl K) से खोलें, या जब आप किसी फ़ील्ड में टाइप नहीं कर रहे हों तो / दबाएँ। Esc इसे बंद करता है, और ⌘J (या Ctrl J) परिणाम प्रीव्यू पेन को टॉगल करता है।
क्वेरीज़ पेज के शीर्षकों, विवरणों, और मुख्य टेक्स्ट से मेल खाती हैं, जिसमें शीर्षक के मिलान सबसे ऊँची रैंक पाते हैं और विवरण मुख्य टेक्स्ट से ऊपर रहते हैं।
लोकप्रिय पेज
पाठक के कोई क्वेरी टाइप करने से पहले, खोज डायलॉग एक Popular सूची दिखाता है। डिफ़ॉल्ट रूप से यह पहले छह साइडबार पेज होते हैं — जो मल्टी-टैब साइटों पर अक्सर गलत सेक्शन सामने ले आते हैं। इसके बजाय अपने मनचाहे लिंक पिन करें:
search: {
popular: [
{ href: "/guides/getting-started", icon: "rocket", label: "Getting started" },
{ href: "/guides/install", icon: "download", label: "Install" },
{ href: "/concepts/overview", label: "Overview" },
],
},
प्रत्येक एंट्री एक href (आंतरिक रूट या बाहरी URL) और एक label लेती है, साथ ही एक वैकल्पिक icon — कोई बिल्ट-इन आइकन नाम, इमेज पाथ/URL, या इनलाइन SVG (nav आइकनों जैसे ही इनपुट), जो डिफ़ॉल्ट रूप से एक फ़ाइल ग्लिफ़ होता है। साइडबार फ़ॉलबैक बनाए रखने के लिए popular को छोड़ दें या खाली रहने दें।
href ऐसे लिखें जैसे साइट रूट पर माउंट हो — basePath आपके लिए अपने आप लागू किया जाता है, ठीक navigation.featured की तरह। बाहरी URL बिना बदलाव के आगे बढ़ जाते हैं।
क्या इंडेक्स होता है
Orama, FlexSearch, Algolia, Orama Cloud, और Typesense के लिए — और MCP सर्वर के search_docs टूल के लिए — Blume हर पेज का शीर्षक, विवरण, और सादे टेक्स्ट में बदला गया मुख्य भाग इंडेक्स करता है: कोड ब्लॉक, इमेज, और मार्कअप हटा दिए जाते हैं, ताकि परिणाम प्रासंगिक बने रहें। ये इंडेक्स आपकी सोर्स फ़ाइलों से बनते हैं, इसलिए ये dev और प्रोडक्शन में एक जैसे होते हैं। Pagefind इसके बजाय बिल्ड किए गए HTML को इंडेक्स करता है, और Mixedbread आपके कच्चे Markdown को सिंक करता है, इसलिए ये दोनों हमेशा कोड में भी खोजते हैं।
यदि आपके docs ऑप्शनों, मेथडों, या एरर नामों जैसे खोजे जाने योग्य शब्दों के लिए कोड उदाहरणों पर निर्भर करते हैं, तो fenced कोड को सोर्स से बने इंडेक्सों में शामिल करें:
search: {
indexing: {
includeCodeBlocks: true,
},
},
हर fence का मुख्य भाग और शीर्षक (ऊपर blume.config.ts) खोजे जाने योग्य बन जाते हैं; भाषा और fence मार्कर नहीं। .mdx पेजों पर इंडेक्स कंपोनेंट्स को उस टेक्स्ट के रूप में पढ़ता है जो वे दिखाते हैं — किसी Card का शीर्षक, किसी Tab का लेबल, किसी TypeTable के विवरण — और इसके लिए वही सीरियलाइज़र उपयोग होते हैं जो एजेंट सरफ़ेस उपयोग करते हैं, इसलिए एक ai.markdownComponents एंट्री आपके अपने कंपोनेंट्स को भी कवर कर लेती है। इस ऑप्शन का Pagefind या Mixedbread पर कोई प्रभाव नहीं पड़ता। यह अपेक्षा रखें कि आपकी fenced सामग्री के साथ इंडेक्स बढ़ेगा — क्लाइंट इंडेक्स हर पाठक तक भेजा जाता है, होस्टेड प्रोवाइडर रिकॉर्ड के आकार की सीमा तय करते हैं (जब किसी एक पेज का रिकॉर्ड उसके प्लान की सीमा से आगे निकल जाता है तो Algolia सिंक बैच को अस्वीकार कर देता है, और पिछला इंडेक्स ही लाइव बना रहता है), और किसी fence के भीतर मिला मिलान परिणाम के अंश में सपाट किया हुआ कोड दिखाता है।
किसी वर्शन वाली साइट पर, परिणाम डिफ़ॉल्ट रूप से उसी वर्शन तक सीमित रहते हैं जिसे देखा जा रहा है, और डायलॉग के फ़ुटर में एक “All versions” टॉगल होता है (जो हर पाठक के लिए याद रखा जाता है)। दूसरे वर्शन के मिलान अपनी पंक्ति पर अपना वर्शन बताते हैं। Orama, FlexSearch, Algolia, और Typesense इस स्कोपिंग का पालन करते हैं — होस्टेड रिकॉर्ड एक version facet रखते हैं, जिसमें मौजूदा docs "current" के रूप में अपलोड होते हैं — जबकि Pagefind बिना स्कोप के रहता है, जो उसके locale व्यवहार के अनुरूप है।
टैग
किसी पेज को खोज डायलॉग में एक फ़िल्टर के अंतर्गत समूहित करने के लिए उसके frontmatter में search.tags जोड़ें — पाठक एक क्लिक से परिणामों को किसी टैग तक सीमित कर सकते हैं। होस्टेड प्रोवाइडरों पर टैग एक facet भी बन जाते हैं।
search:
tags: [api, reference]
प्रोवाइडर
क्लाइंट-साइड प्रोवाइडर बिना keys के चलते हैं और किसी अतिरिक्त config की ज़रूरत नहीं रखते। होस्टेड प्रोवाइडर blume.config.ts में सार्वजनिक क्रेडेंशियल लेते हैं (ब्राउज़र तक भेजना सुरक्षित) और बिल्ड के समय अपनी गुप्त एडमिन key एक environment variable से पढ़ते हैं — सीक्रेट कभी config या क्लाइंट बंडल में नहीं पहुँचता।
Orama (डिफ़ॉल्ट)
Blume का डिफ़ॉल्ट इंजन। यह /blume-search.json पर सर्व किया जाने वाला एक JSON इंडेक्स बनाता है और ब्राउज़र में उससे क्वेरी करता है — तुरंत, क्लाइंट-साइड, और blume dev में संपादन करते ही लाइव। कोई keys नहीं, कोई सेवा नहीं।
search: {
provider: "orama", // default
}
गैर-लैटिन लिपियाँ
Orama का मानक टोकनाइज़र केवल बुनियादी लैटिन अक्षर, अंक, और गिने-चुने उच्चारण-चिह्न वाले स्वर ही रखता है, इसलिए किसी भी अन्य लिपि का टेक्स्ट — जापानी, चीनी, कोरियाई, और थाई, लेकिन उतना ही रूसी, यूनानी, हिब्रू, और हिन्दी भी — अन्यथा कोई भी मिलान नहीं देता। Blume इसे आपके लिए संभालता है: जब i18n.defaultLocale किसी गैर-लैटिन लिपि पर हल होता है, तो इंडेक्स एक शब्द-विभाजक टोकनाइज़र पर स्विच हो जाता है (जो ब्राउज़र- और Node-नेटिव Intl.Segmenter पर बना है)। बस अपनी साइट की भाषा घोषित करना ही काफी है:
i18n: {
defaultLocale: "ja",
locales: [{ code: "ja", label: "日本語" }],
}
वही टोकनाइज़र खोज डायलॉग, MCP सर्वर के search_docs टूल, और Ask AI ग्राउंडिंग के काम आता है। निर्णय लिपि से होता है, भाषा के नाम से नहीं — az-Cyrl विभाजित होती है जबकि sr-Latn नहीं — और पूरे इंडेक्स के लिए निर्णय डिफ़ॉल्ट locale ही करता है: मिश्रित-भाषा वाली साइट पर हर पेज डिफ़ॉल्ट locale का टोकनाइज़र साझा करता है। गैर-लैटिन डिफ़ॉल्ट के साथ यह सुरक्षित है, क्योंकि लैटिन शब्द विभाजन के बाद भी अक्षुण्ण रहते हैं, इसलिए अंग्रेज़ी के पेज डिफ़ॉल्ट भाषा के साथ-साथ खोजे जा सकते हैं। इसका उलटा सही नहीं है: लैटिन-डिफ़ॉल्ट वाली साइट पर गैर-लैटिन अनुवाद खोजे नहीं जा सकते। जो लैटिन-लिपि वाली भाषाएँ उच्चारण-चिह्नों पर बहुत निर्भर करती हैं (वियतनामी, या लैटिन लिपि में सर्बियाई), वे भी मानक टोकनाइज़र पर कमज़ोर प्रदर्शन करती हैं, जो केवल कुछ ही उच्चारण-चिह्न वाले स्वरों को समेटता है और बाकी पर शब्दों को तोड़ देता है।
जापानी और चीनी एक कदम और आगे जाती हैं। केवल विभाजन से एक संयुक्त शब्द उसके हिस्सों के रूप में इंडेक्स होता है — 資金決済法 को 資金, 決済 और 法 के रूप में — जिससे हर हिस्से का कहीं-न-कहीं उल्लेख करने वाला पेज उस पेज से आगे निकल सकता है जो वास्तव में उस शब्द के बारे में है। इसलिए Han, Hiragana और Katakana को ओवरलैप होने वाले अक्षर-युग्मों के रूप में इंडेक्स किया जाता है, और उन इंडेक्सों पर क्वेरीज़ ऐसे पेजों को प्राथमिकता देती हैं जो किसी शब्द के युग्मों को एक साथ रखते हैं, और जब कोई पेज उन सभी को नहीं रखता तो किसी-भी-युग्म मिलान तक ढील दे देती हैं, ताकि पूरा वाक्य टाइप करने पर भी उसके सबसे नज़दीकी पेज लौटें। कोरियाई और थाई अपने विभाजित शब्द बनाए रखती हैं।
FlexSearch
एक दूसरा बिना key वाला, क्लाइंट-साइड विकल्प। यह वही /blume-search.json इंडेक्स दोबारा उपयोग करता है जो Orama प्रदान करता है और ब्राउज़र में एक FlexSearch डॉक्युमेंट इंडेक्स बनाता है। blume dev और blume build में काम करता है।
FlexSearch में इसके समकक्ष कोई सेगमेंटेशन हुक नहीं है, इसलिए गैर-लैटिन लिपि वाली साइटों के लिए Orama (डिफ़ॉल्ट) या Pagefind को प्राथमिकता दें, जिसका pagefind_extended बाइनरी भाषाओं के एक व्यापक समूह को इंडेक्स करता है और चीनी, जापानी, और कोरियाई को नेटिव रूप से विभाजित करता है।
search: {
provider: "flexsearch",
}
Pagefind
बहुत बड़े docs के लिए, Pagefind चुनें। यह आपके बिल्ड किए गए HTML को इंडेक्स करता है और इंडेक्स को माँग पर शार्ड्स में लोड करता है, जिससे साइट चाहे कितनी भी बड़ी हो जाए, प्रारंभिक payload छोटा बना रहता है।
search: {
provider: "pagefind",
}
Pagefind केवल blume build के दौरान चलता है, इसलिए इस प्रोवाइडर के साथ blume dev में खोज उपलब्ध नहीं होती।
Algolia
ब्राउज़र आपकी search-only key से सीधे Algolia से क्वेरी करता है। हर blume build इंडेक्स को ALGOLIA_ADMIN_API_KEY से मिली एडमिन key का उपयोग करके बदल देता है (यदि यह सेट नहीं है तो बिल्ड चेतावनी देकर अपलोड छोड़ देता है)। हर सिंक पर पूरा इंडेक्स बदल दिया जाता है, इसलिए हटाए गए या नाम बदले गए पेज बासी परिणामों के रूप में नहीं टिके रहते।
search: {
provider: "algolia",
algolia: {
appId: "YOUR_APP_ID",
indexName: "docs",
searchApiKey: "YOUR_SEARCH_ONLY_KEY", // public
},
}
Orama Cloud
होस्टेड Orama। ब्राउज़र सार्वजनिक API key के साथ आपके इंडेक्स एंडपॉइंट से क्वेरी करता है; blume build, ORAMA_PRIVATE_API_KEY का उपयोग करके रिकॉर्ड इंडेक्स में भेजता है। सिंक सक्षम करने के लिए indexId सेट करें।
search: {
provider: "orama-cloud",
oramaCloud: {
endpoint: "https://cloud.orama.run/v1/indexes/your-index",
apiKey: "YOUR_PUBLIC_API_KEY",
indexId: "your-index-id", // for the build-time sync
},
}
Typesense
सेल्फ-होस्टेड या क्लाउड Typesense। ब्राउज़र search-only key से कलेक्शन से क्वेरी करता है; blume build, TYPESENSE_ADMIN_API_KEY का उपयोग करके कलेक्शन फिर से बनाता है और डॉक्युमेंट इम्पोर्ट करता है। हर सिंक पर कलेक्शन हटाकर दोबारा बनाया जाता है ताकि हटाए गए या नाम बदले गए पेज बासी परिणामों के रूप में न टिकें — यदि आप कलेक्शन की सेटिंग्स हाथ से समायोजित करते हैं, तो बिल्ड के बाद उन्हें फिर से लागू करें।
search: {
provider: "typesense",
typesense: {
host: "xyz.a1.typesense.net",
collection: "docs",
searchApiKey: "YOUR_SEARCH_ONLY_KEY", // public
// port + protocol default to 443 / https
},
}
Mixedbread
Mixedbread के माध्यम से सिमेंटिक खोज। क्वेरीज़ एक जनरेट किए गए /api/search एंडपॉइंट से होकर जाती हैं जो आपकी key रखता है, इसलिए इस प्रोवाइडर को सर्वर आउटपुट की आवश्यकता है (deployment.output: "server")। एंडपॉइंट MIXEDBREAD_API_KEY पढ़ता है। अपने बिल्ड में Mixedbread CLI से अपनी सामग्री को स्टोर में सिंक करें, जैसे mxbai vs sync <STORE_ID> ./content --ci।
search: {
provider: "mixedbread",
mixedbread: {
storeId: "YOUR_STORE_ID",
},
}
खोज को अक्षम करना
search: {
provider: "none",
}
पेजों को बाहर रखना
केवल इंडेक्स-योग्य पेज ही खोजे जाते हैं। जब कोई पेज अपने frontmatter में search.exclude सेट करता है, तो उसे इंडेक्स से बाहर रखा जाता है:
search:
exclude: true
छिपे हुए पेज भी डिफ़ॉल्ट रूप से बाहर रखे जाते हैं। उन्हें फिर भी इंडेक्स करने के लिए, इसे सक्षम करें:
search: {
indexing: { includeHiddenPages: true },
}