सामग्री पर जाएँ
Blume
Esc
↑↓नेविगेट↵खोलें⌘Jप्रीव्यू
इस पेज पर

खोज

क्लाइंट-साइड खोज जो बिना किसी API keys के तुरंत काम करती है, साथ ही वैकल्पिक होस्टेड और सिमेंटिक एडैप्टर जिन पर आप अपने docs के बढ़ने के साथ स्विच कर सकते हैं।

Blume बिना किसी होस्टेड इन्फ्रास्ट्रक्चर और बिना API keys के लोकल खोज प्रदान करता है। यह ब्राउज़र में चलती है, blume dev और blume build दोनों में काम करती है, और केवल आपकी वास्तविक सामग्री को इंडेक्स करती है — नेविगेशन क्रोम और बाहर रखे गए पेज छोड़ दिए जाते हैं। जब आपकी ज़रूरतें इससे आगे बढ़ जाएँ, तो आप खोज के दिखने या व्यवहार करने के तरीके को बदले बिना किसी होस्टेड या सिमेंटिक बैकएंड पर स्विच कर सकते हैं — केवल वह एडैप्टर बदलता है जिसे आप search को पास करते हैं।

हर बैकएंड blume/search से इम्पोर्ट किया गया एक एडैप्टर है: Orama (डिफ़ॉल्ट), FlexSearch, Pagefind, Algolia, Orama Cloud, Typesense, और Mixedbread। हर एडैप्टर अपने ऑप्शन, अपनी रनटाइम डिपेंडेंसी, और अपने लिए ज़रूरी सीक्रेट स्वयं संभालता है। Orama और Pagefind, Blume के साथ आते हैं; बाकी हर एडैप्टर का SDK एक वैकल्पिक peer डिपेंडेंसी है जिसे आप स्वयं इंस्टॉल करते हैं, इसलिए एक बैकएंड चुनने से बाकी कभी नहीं आते। यदि यह मौजूद नहीं है, तो blume build Vite के चलने से पहले ही रुक जाता है और पैकेज तथा उसे इंस्टॉल करने वाले कमांड का नाम बताता है, और blume doctor भी इसकी रिपोर्ट करता है।

import { defineConfig } from "blume";
import { algolia } from "blume/search";

export default defineConfig({
  search: algolia({
    appId: "YOUR_APP_ID",
    apiKey: "YOUR_SEARCH_ONLY_KEY",
    indexName: "docs",
  }),
});

एडैप्टर बैकएंड का एक सादा विवरण होता है — कोई लाइव क्लाइंट नहीं — इसलिए Blume इसे जनरेट की गई साइट में और eject किए गए प्रोजेक्ट में इनलाइन कर सकता है। एडैप्टर को सीधे पास करें, या जब आप इसके साथ लोकप्रिय लिंक, इंडेक्सिंग, या एनालिटिक्स ऑप्शन भी सेट करना चाहें, तो ऑब्जेक्ट फ़ॉर्म का उपयोग करें:

import { pagefind } from "blume/search";

search: {
  provider: pagefind(),
  popular: [{ href: "/guides/getting-started", icon: "rocket", label: "Getting started" }],
  indexing: { includeCodeBlocks: true },
},

खोज को हेडर में खोज आइकन से, ⌘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 को छोड़ दें या खाली रहने दें। ऑब्जेक्ट फ़ॉर्म में provider को छोड़ देने पर डिफ़ॉल्ट Orama एडैप्टर बना रहता है।

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 के विवरण — और इसके लिए वही सीरियलाइज़र उपयोग होते हैं जो एजेंट सरफ़ेस उपयोग करते हैं, इसलिए एक agents.markdownComponents एंट्री आपके अपने कंपोनेंट्स को भी कवर कर लेती है। इस ऑप्शन का Pagefind या Mixedbread पर कोई प्रभाव नहीं पड़ता। यह अपेक्षा रखें कि आपकी fenced सामग्री के साथ इंडेक्स बढ़ेगा — क्लाइंट इंडेक्स हर पाठक तक भेजा जाता है, होस्टेड एडैप्टर अधिक डेटा संग्रहीत करते हैं (Algolia सिंक किसी लंबे पेज को कई रिकॉर्ड में बाँट देता है), और किसी fence के भीतर मिला मिलान परिणाम के अंश में सपाट किया हुआ कोड दिखाता है।

किसी वर्शन वाली साइट पर, परिणाम डिफ़ॉल्ट रूप से उसी वर्शन तक सीमित रहते हैं जिसे देखा जा रहा है, और डायलॉग के फ़ुटर में एक “All versions” टॉगल होता है (जो हर पाठक के लिए याद रखा जाता है)। दूसरे वर्शन के मिलान अपनी पंक्ति पर अपना वर्शन बताते हैं। Orama, FlexSearch, Algolia, और Typesense इस स्कोपिंग का पालन करते हैं — होस्टेड रिकॉर्ड एक version facet रखते हैं, जिसमें मौजूदा docs "current" के रूप में अपलोड होते हैं। Pagefind, Orama Cloud, और Mixedbread वर्शन के अनुसार स्कोप नहीं करते: उनके परिणाम हर वर्शन में फैले होते हैं, और डायलॉग में यह टॉगल नहीं दिखाया जाता।

i18n वाली साइट पर, परिणाम डिफ़ॉल्ट रूप से उस पेज की भाषा तक सीमित रहते हैं जिसे देखा जा रहा है, और उसके बगल में एक “All languages” टॉगल होता है (यह भी हर पाठक के लिए याद रखा जाता है)। Orama और FlexSearch ब्राउज़र में अपने इंडेक्स को फ़िल्टर करते हैं, और Algolia, Orama Cloud, और Typesense हर रिकॉर्ड में मौजूद locale पर फ़िल्टर करते हैं। Pagefind हर भाषा के लिए एक अलग इंडेक्स रखता है: यह पेज की अपनी भाषा के इंडेक्स में खोजता है, और “All languages” चुनने पर बाकी इंडेक्सों को भी मिला लेता है, जिनमें यह फिर पेज की भाषा के word stemming के साथ खोजता है। Mixedbread भाषा के अनुसार स्कोप नहीं करता: उसके परिणाम हर भाषा में फैले होते हैं, और डायलॉग में यह टॉगल नहीं दिखाया जाता।

टैग

किसी होस्टेड एडैप्टर के लिए किसी पेज को लेबल करने हेतु उसके frontmatter में search.tags जोड़ें। पेज का पहला टैग Algolia, Orama Cloud, और Typesense में उसके रिकॉर्ड पर एक tag फ़ील्ड के रूप में अपलोड किया जाता है, जहाँ आप प्रोवाइडर के डैशबोर्ड में या अपने स्वयं के सर्च UI में उस पर फ़िल्टर कर सकते हैं। Typesense tag को एक facet के रूप में घोषित करता है; Algolia पर, इसे इंडेक्स के attributesForFaceting में स्वयं जोड़ें, और सिंक इसे वहाँ बनाए रखता है।

search:
  tags: [api, reference]

खोज डायलॉग टैग नहीं पढ़ता। इसके फ़िल्टर परिणामों को उस साइडबार सेक्शन के अनुसार समूहित करते हैं जिसमें हर पेज स्थित है, और ये Orama और FlexSearch के साथ दिखाई देते हैं, जिनके इंडेक्स हर पेज का सेक्शन रखते हैं।

रैंकिंग

दो frontmatter फ़ील्ड तय करते हैं कि कोई पेज किस रैंक पर आता है। search.keywords उन अतिरिक्त शब्दों की सूची देता है जिनसे पेज खोज में मिल जाता है, भले ही उसका टेक्स्ट उनका उपयोग न करता हो। यह ऐसे पेज के लिए उपयुक्त है जिसे पाठक किसी पुराने नाम, संक्षिप्त रूप, या किसी प्रतिस्पर्धी के शब्द से खोजते हैं। search.boost पेज की प्रासंगिकता को गुणा करता है: 1 से ऊपर का मान उसे ऊपर ले जाता है, और 1 से नीचे का मान उसे नीचे ले जाता है।

search:
  keywords: [install, setup, getting started]
  boost: 3

boost को केवल उन कुछ पेजों तक सीमित रखें जिनकी पाठकों को सबसे अधिक ज़रूरत होती है, जैसे कोई quickstart या overview, और 2 से 5 के बीच के मान उपयोग करें। ऐसे पेज के लिए, जिसे उतने ही अच्छे से मेल खाने वाले अन्य पेजों से नीचे रैंक होना चाहिए, जैसे कोई पुरानी गाइड, 1 से कम मान का उपयोग करें, जैसे 0.5। boost को 10 से कम रखें: उससे आगे boost इस बात को दबा देता है कि कोई पेज कितनी अच्छी तरह मेल खाता है, और पेज उन खोजों में भी सबसे ऊपर आ जाता है जिनसे वह मुश्किल से मेल खाता है।

boost किसी पेज की रैंक को कितना बदलता है, यह एडैप्टर पर निर्भर करता है:

  • Orama (डिफ़ॉल्ट) और FlexSearch क्रमबद्ध करने से पहले हर मिलान को उसके पेज के boost से गुणा करते हैं, इसलिए 3 का boost ठीक तीन गुना गिना जाता है। MCP सर्वर और असिस्टेंट की खोज भी इसी तरह रैंक करती है।
  • Pagefind boost किए गए पेज के टेक्स्ट को अधिक महत्व देता है। यह दोहराए गए मिलानों का प्रभाव कम कर देता है, इसलिए बढ़त गुणक से छोटी होती है: 5 का boost पेज को ऊँची रैंक देता है, लेकिन लगभग दोगुनी के आसपास ही। Pagefind 10 से अधिक के boost को 10 ही गिनता है।
  • Algolia लगभग समान रूप से मेल खाने वाले परिणामों के बीच boost के अनुसार क्रमबद्ध करता है, इसलिए boost किसी कमज़ोर मिलान को मज़बूत मिलान से ऊपर उठाए बिना करीबी मुकाबलों का निर्णय करता है। सिंक इंडेक्स की custom ranking में, आपके द्वारा सेट की गई किसी भी रैंकिंग के बाद, desc(boost) जोड़ता है।
  • Typesense पहले प्रासंगिकता के अनुसार, फिर समान प्रासंगिकता स्कोर वाले परिणामों के बीच boost के अनुसार क्रमबद्ध करता है, इसलिए boost किसी कमज़ोर मिलान को मज़बूत मिलान से ऊपर उठाए बिना बराबरी के मामलों का निर्णय करता है।
  • Orama Cloud परिणामों का एक बड़ा समूह प्राप्त करता है और उन्हें प्रासंगिकता और boost के गुणनफल के अनुसार फिर से क्रमबद्ध करता है।
  • Mixedbread आपके अपने स्टोर में खोजता है, जिसमें Blume अपलोड नहीं करता, इसलिए boost और keywords उस तक नहीं पहुँचते।

Mixedbread को छोड़कर हर एडैप्टर पर keywords खोजे जाते हैं।

खोज एनालिटिक्स

एनालिटिक्स एडैप्टर कॉन्फ़िगर होने पर, खोज यह रिपोर्ट करती है कि पाठक क्या ढूँढते हैं। कोई क्वेरी स्थिर हो जाने पर — एक सेकंड तक टाइप न किए जाने के बाद, या जब पाठक कोई परिणाम चुनता है या डायलॉग बंद करता है — एक search इवेंट के रूप में दर्ज की जाती है, जिसमें query, results की संख्या, और वह path होता है जहाँ से खोज की गई थी। जिस क्वेरी का कोई परिणाम नहीं होता, वह results: 0 के साथ दिखाई देती है, इसलिए इस पर फ़िल्टर करने से वे विषय सूचीबद्ध हो जाते हैं जिन्हें आपके docs अभी तक कवर नहीं करते। कोई परिणाम चुनने पर click-through के लिए एक search_select इवेंट भेजा जाता है, जिसमें query, परिणाम की 1 से शुरू होने वाली position, उसका url, और वह path होता है जहाँ से उसे चुना गया था।

क्वेरीज़ ठीक वैसे ही भेजी जाती हैं जैसे वे टाइप की गई थीं, अधिकतम 100 अक्षरों तक। आपका एनालिटिक्स उन्हें उसी तरह देखता है जैसे वह किसी भी पेज के खोज शब्दों को देखता है, इसलिए उन्हें पाठक का इनपुट मानें: कोई पाठक बॉक्स में ईमेल पता या कोई key पेस्ट कर सकता है, और Google Analytics तथा Plausible व्यक्तिगत डेटा भेजने की अनुमति नहीं देते। क्वेरी टेक्स्ट को अपने प्रोवाइडरों से दूर रखने के लिए, इसे बंद करें:

search: {
  analytics: { queries: false },
},

तब search और search_select इवेंट query के स्थान पर queryChars, यानी क्वेरी की लंबाई, रखते हैं। टेक्स्ट केवल blume:track DOM इवेंट पर, detail.props में query के रूप में जाता है, इसलिए आपके द्वारा लिखा गया कोई listener इसे वहाँ भेज सकता है जहाँ आप तय करें कि इसे होना चाहिए, ठीक उसी तरह जैसे असिस्टेंट प्रश्नों को संभालता है। कुकी सहमति चालू होने पर, केवल उन्हीं पाठकों की गिनती होती है जिन्होंने एनालिटिक्स की अनुमति दी है।

एडैप्टर

क्लाइंट-साइड एडैप्टर बिना keys के चलते हैं और किसी ऑप्शन की ज़रूरत नहीं रखते — उनके क्लाइंट i18n से कॉन्फ़िगर होते हैं (या, Pagefind के लिए, बिल्ड किए गए HTML से), इसलिए कोई अज्ञात key अनदेखी किए जाने के बजाय config वैलिडेशन द्वारा अस्वीकार कर दी जाती है। होस्टेड एडैप्टर सार्वजनिक क्रेडेंशियल लेते हैं (ब्राउज़र तक भेजना सुरक्षित) और बिल्ड के समय अपनी गुप्त एडमिन key एक environment variable से पढ़ते हैं — सीक्रेट कभी config या क्लाइंट बंडल में नहीं पहुँचता। किसी होस्टेड एडैप्टर को आप जो भी ऑप्शन पास करते हैं, वह ज्यों-का-त्यों रखा जाता है और ब्राउज़र में उसके सर्च क्लाइंट को (या, Mixedbread के लिए, सर्च एंडपॉइंट को) सौंप दिया जाता है, इसलिए जिस ऑप्शन का Blume नाम नहीं लेता, वह भी SDK तक पहुँचता है — Algolia का liteClient, Typesense Client, या OramaClient। ये ऑप्शन JSON वैल्यू होने चाहिए — डिस्क्रिप्टर जनरेट किए गए प्रोजेक्ट में एक literal के रूप में इनलाइन किया जाता है, इसलिए कोई फ़ंक्शन, undefined, या bigint रास्ते में गायब होने के बजाय एक पाथ के साथ config वैलिडेशन में विफल हो जाता है।

Algolia, Orama Cloud, और Typesense हर blume build के अंत में आपके पेजों को अपने इंडेक्स में अपलोड करते हैं। जब एडमिन key सेट नहीं होती, तो बिल्ड चेतावनी देकर अपलोड छोड़ देता है, इसलिए बिना सीक्रेट वाला बिल्ड, जैसे कोई लोकल बिल्ड, फिर भी काम करता है। जब key सेट हो और अपलोड विफल हो जाए (गलत key, पहुँच से बाहर होस्ट, अस्वीकार किया गया रिकॉर्ड), तो बिल्ड ऐसे इंडेक्स के विरुद्ध डिप्लॉय करने के बजाय, जिसे उसने अपडेट नहीं किया, BLUME_SEARCH_SYNC_FAILED के साथ विफल हो जाता है।

Orama (डिफ़ॉल्ट)

Blume का डिफ़ॉल्ट इंजन। यह /blume-search.json पर सर्व किया जाने वाला एक JSON इंडेक्स बनाता है और ब्राउज़र में उससे क्वेरी करता है — तुरंत, क्लाइंट-साइड, और blume dev में संपादन करते ही लाइव। कोई keys नहीं, कोई सेवा नहीं। search को पूरी तरह छोड़ देने पर यही चुना जाता है; इसे केवल तभी लिखें जब आप इसे स्पष्ट रूप से दर्शाना चाहते हों:

import { orama } from "blume/search";

search: orama(),

गैर-लैटिन लिपियाँ

मानक टोकनाइज़र केवल लैटिन अक्षर और अंक ही रखता है, इसलिए किसी भी अन्य लिपि का टेक्स्ट — जापानी, चीनी, कोरियाई और थाई, लेकिन उतना ही रूसी, यूनानी, हिब्रू और हिन्दी भी — अन्यथा कोई भी मिलान नहीं देता। Blume इसे आपके लिए संभालता है: जो पेज किसी गैर-लैटिन लिपि पर हल होने वाली locale में हैं, उन्हें एक शब्द-विभाजक टोकनाइज़र से इंडेक्स किया जाता है (जो ब्राउज़र- और Node-नेटिव Intl.Segmenter पर बना है)। बस अपनी साइट की भाषाएँ घोषित करना ही काफी है:

i18n: {
  defaultLocale: "ja",
  locales: [{ code: "ja", label: "日本語" }],
}

वही टोकनाइज़र खोज डायलॉग, MCP सर्वर के search_docs टूल, और असिस्टेंट ग्राउंडिंग के काम आते हैं। निर्णय लिपि से होता है, भाषा के नाम से नहीं — az-Cyrl विभाजित होती है जबकि sr-Latn नहीं। गैर-लैटिन डिफ़ॉल्ट के साथ, हर पेज डिफ़ॉल्ट locale का टोकनाइज़र साझा करता है: लैटिन शब्द विभाजन के बाद भी अक्षुण्ण रहते हैं, इसलिए अंग्रेज़ी के पेज डिफ़ॉल्ट भाषा के साथ-साथ खोजे जा सकते हैं। लैटिन डिफ़ॉल्ट के साथ, लैटिन-लिपि वाले पेज मानक टोकनाइज़र बनाए रखते हैं और गैर-लैटिन लिपि में हर अनुवाद को उसकी अपनी locale का टोकनाइज़र मिलता है, इसलिए किसी अंग्रेज़ी साइट के जापानी और हिन्दी पेज उनकी अपनी भाषा से और हर भाषा में की गई खोज से खोजे जा सकते हैं। मानक टोकनाइज़र उच्चारण-चिह्न हटा देता है और जिन अक्षरों में हटाने लायक कोई उच्चारण-चिह्न नहीं होता, उन्हें सादे अक्षरों में लिख देता है (ø को o, ł को l, ß को ss), इसलिए cafe से café मिल जाता है और lodz से Łódź, और खोज डायलॉग तथा असिस्टेंट के अंश भी पेज में उच्चारण-चिह्न वाला शब्द ढूँढ लेते हैं। जहाँ उच्चारण-चिह्न शब्दों में अंतर करते हैं (स्वीडिश ändra और andra, वियतनामी टोन), वहाँ कोई क्वेरी उन शब्दों से भी मेल खाती है जो उससे केवल उन्हीं उच्चारण-चिह्नों में भिन्न होते हैं।

जापानी और चीनी एक कदम और आगे जाती हैं। केवल विभाजन से एक संयुक्त शब्द उसके हिस्सों के रूप में इंडेक्स होता है — 資金決済法 को 資金, 決済 और 法 के रूप में — जिससे हर हिस्से का कहीं-न-कहीं उल्लेख करने वाला पेज उस पेज से आगे निकल सकता है जो वास्तव में उस शब्द के बारे में है। इसलिए Han, Hiragana और Katakana को ओवरलैप होने वाले अक्षर-युग्मों के रूप में इंडेक्स किया जाता है, और उन इंडेक्सों पर क्वेरीज़ ऐसे पेजों को प्राथमिकता देती हैं जो किसी शब्द के युग्मों को एक साथ रखते हैं, और जब कोई पेज उन सभी को नहीं रखता तो किसी-भी-युग्म मिलान तक ढील दे देती हैं, ताकि पूरा वाक्य टाइप करने पर भी उसके सबसे नज़दीकी पेज लौटें। कोरियाई और थाई अपने विभाजित शब्द बनाए रखती हैं।

FlexSearch

एक दूसरा बिना key वाला, क्लाइंट-साइड विकल्प (flexsearch इंस्टॉल करें)। यह वही /blume-search.json इंडेक्स दोबारा उपयोग करता है जो Orama प्रदान करता है और ब्राउज़र में एक FlexSearch डॉक्युमेंट इंडेक्स बनाता है। blume dev और blume build में काम करता है।

FlexSearch में इसके समकक्ष कोई सेगमेंटेशन हुक नहीं है, इसलिए गैर-लैटिन लिपि वाली साइटों के लिए Orama (डिफ़ॉल्ट) या Pagefind को प्राथमिकता दें, जिसका pagefind_extended बाइनरी भाषाओं के एक व्यापक समूह को इंडेक्स करता है और चीनी, जापानी, और कोरियाई को नेटिव रूप से विभाजित करता है।

import { flexsearch } from "blume/search";

search: flexsearch(),

Pagefind

बहुत बड़े docs के लिए, Pagefind चुनें। यह आपके बिल्ड किए गए HTML को इंडेक्स करता है और इंडेक्स को माँग पर शार्ड्स में लोड करता है, जिससे साइट चाहे कितनी भी बड़ी हो जाए, प्रारंभिक payload छोटा बना रहता है।

import { pagefind } from "blume/search";

search: pagefind(),

Pagefind केवल blume build के दौरान चलता है, इसलिए इस एडैप्टर के साथ blume dev में खोज उपलब्ध नहीं होती। यह हर docs पेज के आर्टिकल को इंडेक्स करता है — उसके आस-पास के हेडर, साइडबार, या फ़ुटर को नहीं — इसलिए PageLayout पर बने कस्टम पेज, 404 पेज, और जनरेट किया गया changelog इंडेक्स इसके परिणामों में नहीं आते।

Algolia

algoliasearch इंस्टॉल करें। ब्राउज़र आपकी search-only key से सीधे Algolia से क्वेरी करता है। हर blume build इंडेक्स को ALGOLIA_ADMIN_API_KEY से मिली एडमिन key का उपयोग करके बदल देता है (यदि यह सेट नहीं है तो बिल्ड चेतावनी देकर अपलोड छोड़ देता है)। हर सिंक पर पूरा इंडेक्स बदल दिया जाता है, इसलिए हटाए गए या नाम बदले गए पेज बासी परिणामों के रूप में नहीं टिके रहते। यदि indexName नाम का कोई इंडेक्स अभी तक मौजूद नहीं है, तो सिंक उसे बना देता है, इसलिए गलत टाइप किया गया नाम बिल्ड को विफल करने के बजाय एक दूसरा इंडेक्स बना देता है। सिंक, Algolia द्वारा कतार में डाले गए हर इंडेक्सिंग टास्क के लिए लगभग सात मिनट तक प्रतीक्षा करता है, और जो टास्क तब तक पूरा नहीं होता, वह बिल्ड को BLUME_SEARCH_SYNC_FAILED के साथ विफल कर देता है। सिंक इंडेक्स के attributesForFaceting में filterOnly(locale) और filterOnly(version) भी जोड़ता है, और आपके द्वारा स्वयं घोषित किए गए facets को बनाए रखता है, क्योंकि डायलॉग परिणामों को भाषा और docs वर्शन के अनुसार सीमित करता है, और Algolia में किसी ऐसे attribute पर लगाया गया फ़िल्टर, जो faceting के लिए घोषित नहीं है, किसी भी चीज़ से मेल नहीं खाता।

Algolia अपने Build और Grow प्लान पर किसी रिकॉर्ड को 10 KB तक सीमित करता है, इसलिए सिंक किसी लंबे पेज को कई रिकॉर्ड में बाँट देता है, जिनमें से हर एक पेज का शीर्षक, विवरण, और URL उसके टेक्स्ट के एक हिस्से के साथ रखता है। फिर यह इंडेक्स के attributeForDistinct को url पर सेट करता है, जब तक कि आपने अपना स्वयं का सेट न किया हो, ताकि बाँटा गया पेज परिणामों में केवल एक बार, अपने सबसे अच्छे मेल खाने वाले रिकॉर्ड पर, दिखाई दे।

import { algolia } from "blume/search";

search: algolia({
  appId: "YOUR_APP_ID",
  apiKey: "YOUR_SEARCH_ONLY_KEY", // public
  indexName: "docs",
}),

Orama Cloud

होस्टेड Orama (@oramacloud/client इंस्टॉल करें)। ब्राउज़र सार्वजनिक API key के साथ आपके इंडेक्स एंडपॉइंट से क्वेरी करता है; blume build, ORAMA_PRIVATE_API_KEY का उपयोग करके रिकॉर्ड इंडेक्स में भेजता है। सिंक सक्षम करने के लिए indexId सेट करें; इसके बिना, key सेट होने पर भी बिल्ड चेतावनी देकर सिंक छोड़ देता है।

import { oramaCloud } from "blume/search";

search: 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। typesense इंस्टॉल करें। ब्राउज़र search-only key से कलेक्शन से क्वेरी करता है। हर blume build, TYPESENSE_ADMIN_API_KEY का उपयोग करके आपके पेजों को एक नए कलेक्शन में इम्पोर्ट करता है, फिर collection के नाम वाले एक alias को उसकी ओर इंगित करता है और उस कलेक्शन को हटा देता है जिसे उसने बदला है। नया कलेक्शन पूरा होने तक खोजें पिछले कलेक्शन से ही पढ़ती रहती हैं, और हटाए गए या नाम बदले गए पेज बासी परिणामों के रूप में नहीं टिकते। यदि सिंक विफल होता है, तो बिल्ड विफल हो जाता है और alias अंतिम पूर्ण सिंक को ही सर्व करता रहता है। एडमिन key को कलेक्शन और alias प्रबंधित करने की अनुमति चाहिए। पहले सिंक पर, जिस कलेक्शन का नाम पहले से collection वाला है (किसी पुराने Blume वर्शन से), उसे alias से बदल दिया जाता है, और उस नाम तक सीमित search keys काम करती रहती हैं। किसी कलेक्शन पर आप हाथ से जो सेटिंग्स समायोजित करते हैं, वे अगले कलेक्शन में नहीं जातीं, इसलिए बिल्ड के बाद उन्हें फिर से लागू करें।

import { typesense } from "blume/search";

search: typesense({
  host: "xyz.a1.typesense.net",
  collection: "docs",
  apiKey: "YOUR_SEARCH_ONLY_KEY", // public
  // port + protocol default to 443 / https
}),

Typesense का डिफ़ॉल्ट टोकनाइज़र टेक्स्ट को स्पेस पर विभाजित करता है, इसलिए चीनी, जापानी, या थाई में कोई क्वेरी केवल टेक्स्ट के किसी क्रम की शुरुआत से ही मेल खाती है। locale को अपने पेजों की भाषा के दो-अक्षर वाले कोड पर सेट करें (locale: "ja", "zh", "th"), और सिंक खोजे जाने वाले फ़ील्ड को उस भाषा के लिए टोकनाइज़ करता है; उन फ़ील्ड में लैटिन-लिपि वाले शब्द फिर भी मेल खाते हैं। एक ही कलेक्शन में हर भाषा रहती है, इसलिए यह सेटिंग उन सभी पर लागू होती है।

Mixedbread

Mixedbread के माध्यम से सिमेंटिक खोज (@mixedbread/sdk इंस्टॉल करें)। क्वेरीज़ एक जनरेट किए गए /api/search एंडपॉइंट से होकर जाती हैं जो आपकी key रखता है, इसलिए इस एडैप्टर को सर्वर आउटपुट की आवश्यकता है: एक होस्ट एडैप्टर, जैसे blume/deploy से deployment: vercel() (देखें सर्वर रेंडरिंग)। एंडपॉइंट MIXEDBREAD_API_KEY पढ़ता है। Blume स्टोर में अपलोड नहीं करता: अपने बिल्ड के हिस्से के रूप में Mixedbread CLI से अपना सामग्री फ़ोल्डर सिंक करें, जैसे mxbai store sync <STORE_ID> ./docs --yes (CLI अपनी key MXBAI_API_KEY से पढ़ता है)।

हर परिणाम उस पेज से लिंक होता है जिसे उसकी फ़ाइल रेंडर करती है, और यह पेज उस पाथ से पहचाना जाता है जिसे CLI फ़ाइल के लिए दर्ज करता है, इसलिए सिंक को अपने प्रोजेक्ट रूट से या उसके ऊपर के किसी फ़ोल्डर से चलाएँ, जैसे किसी monorepo रूट से। कोई पेज केवल एक बार, अपने सबसे अच्छे मेल खाने वाले अंश पर, दिखाई देता है, और उन फ़ाइलों के अंश जो पेज नहीं हैं, या खोज से बाहर रखे गए पेजों के अंश, छोड़ दिए जाते हैं।

import { mixedbread } from "blume/search";

search: mixedbread({
  storeId: "YOUR_STORE_ID",
}),

खोज डायलॉग क्वेरी भेजने से पहले पाठक के टाइप करना रोकने की प्रतीक्षा करता है, और ऐसी क्वेरी को छोड़ देता है जिससे आगे पाठक टाइप कर चुका है। भेजी गई हर क्वेरी एंडपॉइंट की रेट लिमिट में गिनी जाती है।

search: false,

जब आप फिर भी चाहते हों कि indexing MCP सर्वर के इंडेक्स पर लागू हो, तो इसके बजाय ऑब्जेक्ट फ़ॉर्म में provider: false सेट करें।

पेजों को बाहर रखना

केवल इंडेक्स-योग्य पेज ही खोजे जाते हैं। जब कोई पेज अपने frontmatter में search.exclude सेट करता है, तो उसे इंडेक्स से बाहर रखा जाता है:

search:
  exclude: true

छिपे हुए पेज भी डिफ़ॉल्ट रूप से बाहर रखे जाते हैं। उन्हें फिर भी इंडेक्स करने के लिए, इसे सक्षम करें:

search: {
  indexing: { includeHiddenPages: true },
}

अंतिम अपडेट

क्या यह पेज सहायक था?