परिनियोजन
शून्य कॉन्फ़िगरेशन के साथ स्टैटिक डॉक्स को किसी भी होस्ट पर परिनियोजित करें, या जब आपको डायनामिक व्यवहार की आवश्यकता हो तो सर्वर रेंडरिंग पर स्विच करने के लिए blume/deploy से एक होस्ट एडाप्टर का नाम दें।
कहीं भी परिनियोजित करें (स्टैटिक)
blume build आपके डॉक्स को सादे HTML, CSS, और dist/ में एक स्थानीय खोज इंडेक्स में संकलित करता है। चलाने के लिए कोई सर्वर नहीं है — बस किसी भी स्टैटिक होस्ट को उस फ़ोल्डर की ओर इंगित करें।
| सेटिंग | मान |
|---|---|
| बिल्ड कमांड | blume build |
| आउटपुट डायरेक्टरी | dist |
| Node संस्करण | 22.19 या नया |
ये सेटिंग्स Vercel, Netlify, Cloudflare Pages, GitHub Pages, या किसी भी बकेट या CDN पर काम करती हैं। सुनिश्चित करें कि blume एक डिपेंडेंसी है ताकि होस्ट बिल्ड चला सके।
CloudFront के पीछे Amazon S3 को, जिसमें एक निजी बकेट ऑरिजिन एक्सेस कंट्रोल के माध्यम से पढ़ा जाता है, दो और चीज़ों की आवश्यकता होती है, क्योंकि S3 REST एंडपॉइंट हर कुंजी को ठीक-ठीक खोजता है और हर फ़ाइल को उसी प्रकार के साथ परोसता है जिसके साथ उसे अपलोड किया गया था:
- व्यूअर अनुरोधों पर एक CloudFront Function, जो हर पेज URL को उस
index.htmlसे मैप करे जिसे Blume उसके लिए लिखता है:/quickstartको/quickstart/index.htmlसे, और/(या/पर समाप्त होने वाले किसी भी पथ) को उसकेindex.htmlसे। जिस पथ के अंतिम सेगमेंट में एक बिंदु हो (/quickstart.md,/_astro/app.js), उसे अपरिवर्तित छोड़ दें, और फ़ंक्शन को/.well-known/*पर लागू न करें, जिसकेapi-catalogका कोई एक्सटेंशन नहीं है। इसके बिना, S3/quickstartका उत्तर403या404के साथ देता है। - ऐसे अपलोड जो वे प्रकार सेट करें जिन्हें फ़ाइल एक्सटेंशन से लगाया गया अनुमान गलत कर देता है या बिना charset के छोड़ देता है:
.mdऔर.mdxके लिएtext/markdown; charset=utf-8,.txtके लिएtext/plain; charset=utf-8, और.well-known/api-catalogके लिएapplication/linkset+json; profile="https://www.rfc-editor.org/info/rfc9727"।dist/_headersउन सभी नियमों को सूचीबद्ध करता है जिनकी आपके बिल्ड को आवश्यकता है।
S3 और CloudFront गाइड में फ़ंक्शन सहित एक CloudFormation टेम्पलेट और एक डिप्लॉय स्क्रिप्ट है जो इन प्रकारों के साथ अपलोड करती है।
Cloudflare Workers पर, जो एक स्टैटिक बिल्ड को स्टैटिक एसेट्स के रूप में परोसता है, अपने Wrangler कॉन्फ़िग में assets के अंतर्गत "html_handling": "drop-trailing-slash" सेट करें। Blume हर पेज को <route>/index.html के रूप में लिखता है और उससे बिना ट्रेलिंग स्लैश के लिंक करता है, और Cloudflare का डिफ़ॉल्ट (auto-trailing-slash) /quickstart का उत्तर /quickstart/ की ओर एक 307 के साथ देता है। एक cloudflare() सर्वर बिल्ड हर पेज को अपने Worker के माध्यम से रूट करता है, जो किसी भी सेटिंग के अंतर्गत /quickstart परोसता है, इसलिए वहाँ यह केवल तभी मायने रखता है जब बिल्ड Could not wire Accept: text/markdown negotiation की चेतावनी देता है और स्टैटिक परत स्वयं पेज परोसती है।
एक स्टैटिक बिल्ड में शामिल है:
- हर डॉक्स और कस्टम पेज स्टैटिक HTML के रूप में
- एक स्थानीय खोज इंडेक्स (डिफ़ॉल्ट रूप से Orama, Pagefind वैकल्पिक)
- जब साइट URL ज्ञात हो तो एक
sitemap.xml - एक
robots.txt, जो साइट URL ज्ञात होने पर साइटमैप की ओर इंगित करता है - AI टूल्स के लिए
llms.txtऔरllms-full.txt - रीडायरेक्ट पेज
- जब
seo.og.enabledचालू हो तो प्रीरेंडर की गई Open Graph छवियाँ
अपना साइट URL सेट करें
साइटमैप, कैनोनिकल टैग, RSS, और Open Graph छवियों को एक निरपेक्ष ऑरिजिन की आवश्यकता होती है। Vercel, Netlify, और Cloudflare Pages पर, Blume इसे बिल्ड समय पर प्लेटफ़ॉर्म के परिवेश से पहचान लेता है — किसी कॉन्फ़िग की आवश्यकता नहीं।
पहचाने गए मान को ओवरराइड करने के लिए, या उन होस्ट्स पर मान उपलब्ध कराने के लिए जो इसे उजागर नहीं करते (GitHub Pages, S3, एक कस्टम CDN), site को एक निरपेक्ष http:// या https:// URL पर सेट करें। एक स्टैटिक बिल्ड के लिए यह सादा deployment ऑब्जेक्ट है:
deployment: {
site: "https://docs.example.com",
}
Vercel और Netlify पर, स्वचालित पहचान प्रति-डिप्लॉय प्रीव्यू URL की तुलना में आपके स्थिर प्रोडक्शन डोमेन को प्राथमिकता देती है, ताकि कैनोनिकल ऑरिजिन डिप्लॉय-दर-डिप्लॉय एक जैसा बना रहे। Cloudflare Pages केवल वर्तमान डिप्लॉयमेंट का URL (CF_PAGES_URL) उजागर करता है, जो हर डिप्लॉय के साथ बदल जाता है, इसलिए वहाँ site सेट करें। Cloudflare Workers कोई भी URL उजागर नहीं करता, इसलिए Workers पर भी site सेट करें।
blume dev के दौरान, जब कोई सेट न हो तो साइट URL आपके स्थानीय डेव सर्वर (जैसे http://localhost:4321) पर वापस चला जाता है, ताकि साइट-आधारित सुविधाएँ — Open Graph छवियाँ, कैनोनिकल, साइटमैप — बिना किसी अतिरिक्त सेटअप के काम करें। बिल्ड कभी इस फ़ॉलबैक का उपयोग नहीं करते, इसलिए प्रोडक्शन आउटपुट कभी localhost की ओर इंगित नहीं होता।
मोनोरेपो
डॉक्स वर्कस्पेस को उसके अपने प्रोजेक्ट के रूप में परिनियोजित करें, जिसमें होस्ट की रूट डायरेक्टरी उसी पर सेट हो (Vercel की Root Directory, Netlify की Base directory) और ऊपर दी गई सेटिंग्स हों। Vercel पर, जब भी डॉक्स अपने वर्कस्पेस के बाहर की फ़ाइलें पढ़ते हैं, तो Include source files outside of the Root Directory in the Build Step को चालू रहने दें, जो डिफ़ॉल्ट है: कंपोनेंट उदाहरण या कोई वर्कस्पेस पैकेज जिसे वे इम्पोर्ट करते हैं, theme.css में एक @source पथ, या रिपॉज़िटरी में कहीं और मौजूद एक स्पेक। इसके बंद होने पर, बिल्ड उन फ़ाइलों तक नहीं पहुँच सकता। मोनोरेपो गाइड pnpm और Turborepo सेटअप को चरण-दर-चरण समझाती है।
स्थानीय रूप से पूर्वावलोकन करें
शिप करने से पहले, प्रोडक्शन बिल्ड का ठीक वैसे ही पूर्वावलोकन करें जैसे एक स्टैटिक होस्ट इसे परोसेगा:
blume build
blume preview
blume preview स्टैटिक बिल्ड और node() व cloudflare() सर्वर बिल्ड परोसता है। Vercel और Netlify एडाप्टर के पास कोई स्थानीय प्रीव्यू सर्वर नहीं है, इसलिए vercel() या netlify() सर्वर बिल्ड के बाद यह इसके बजाय एक त्रुटि के साथ रुक जाता है। साइट को blume dev के साथ आज़माएँ, या vercel deploy या netlify deploy के साथ एक प्रीव्यू परिनियोजित करें।
एक स्टैटिक बिल्ड पर, blume preview dist/ की फ़ाइलों से आगे भी वही उत्तर देता है जो होस्ट देता। यह रीडायरेक्ट, पैटर्न सहित, उनके कॉन्फ़िगर किए गए स्टेटस के साथ ठीक वैसे ही लागू करता है जैसे बिल्ड द्वारा लिखी गई होस्ट फ़ाइलें करती हैं। यह ट्रेलिंग स्लैश को भी उसी तरह संभालता है जैसे स्टैटिक होस्ट संभालते हैं:
- ट्रेलिंग स्लैश वाला किसी पेज का URL (
/guide/) क्वेरी स्ट्रिंग को बनाए रखते हुए पेज (/guide) पर रीडायरेक्ट होता है। public/में आपके द्वारा शिप किया गया HTML का एक फ़ोल्डर (public/demo/index.html)/demo/पर परोसा जाता है, और/demoवहाँ रीडायरेक्ट होता है, ताकि उसके भीतर के सापेक्ष लिंक हल हो सकें।
blume dev भी ट्रेलिंग स्लैश को इसी तरह संभालता है।
सबपाथ परिनियोजन
डॉक्स को example.com/docs जैसे पथ के अंतर्गत परोस रहे हैं? base सेट करें — GitHub Pages प्रोजेक्ट साइटों के लिए यह सामान्य है। पूरी साइट, रूट सहित, बेस के अंतर्गत चली जाती है, और आंतरिक लिंक व एसेट्स को इसे शामिल करने के लिए पुनर्लिखित किया जाता है, साथ ही रॉ HTML में मौजूद रूट-सापेक्ष href या src (<a href="/guide">, <img src="/logo.png">) को भी।
deployment: {
base: "/docs",
}
base (और site) हर होस्ट एडाप्टर के विकल्प भी हैं: vercel({ base: "/docs" })। @astrojs/vercel बेस को अनदेखा करता है, इसलिए एक vercel() सर्वर बिल्ड स्वयं स्टैटिक फ़ाइलों को .vercel/output/static/docs/ में, और .vercel/output/config.json के रूट व रीडायरेक्ट को /docs के अंतर्गत ले जाता है।
हर पेज बेस के अंतर्गत अपना स्वयं का पथ बनाए रखता है, उस कंटेंट फ़ोल्डर में भी जिसका नाम बेस के नाम जैसा ही हो: base: "/docs" के साथ, docs/setup.md को /docs/docs/setup पर परोसा जाता है, और उसका कैनोनिकल URL, साइडबार लिंक, और llms.txt एंट्री वहीं की ओर इंगित करते हैं। आपके द्वारा लिखा गया जो रूट-सापेक्ष लिंक पहले से ही बेस से शुरू होता है, उसे बेस सहित माना जाता है और जैसा लिखा गया है वैसा ही छोड़ दिया जाता है, इसलिए उस पेज को लिंक करने के लिए एक सापेक्ष लिंक (./docs/setup) या उसके पूरे पथ (/docs/docs/setup) का उपयोग करें।
प्रति डिप्लॉय एक अलग बेस
blume.config.ts एक मॉड्यूल है, इसलिए base एक परिवेश चर से आ सकता है। इससे CI कॉन्फ़िग को संपादित किए बिना हर पुल अनुरोध का प्रीव्यू उसके अपने पथ के अंतर्गत बिल्ड कर सकता है:
deployment: {
base: process.env.DOCS_BASE,
}
DOCS_BASE=/pr-1234 blume build
DOCS_BASE सेट न होने पर, साइट रूट पर बिल्ड होती है, इसलिए प्रोडक्शन को किसी अतिरिक्त चीज़ की आवश्यकता नहीं होती।
डॉक्स को किसी पथ के अंतर्गत माउंट करें
basePath हर जनरेट किए गए रूट को एक सेगमेंट (/docs/getting-started) के अंतर्गत माउंट करता है जबकि साइडबार को अछूता छोड़ देता है — शीर्ष स्तर आपके सेक्शन हैं, कोई रैपर समूह नहीं। इसका उपयोग तब करें जब डॉक्स /docs/* पर रहें लेकिन साइट रूट आपका ही बना रहे (जैसे Docusaurus का routeBasePath या Fumadocs का baseUrl)।
basePath: "/docs",
लिंक ऐसे लिखें मानो वे रूट पर माउंट हों (/getting-started); Blume उन्हें, साथ ही रीडायरेक्ट, साइटमैप, कैनोनिकल URL, Open Graph छवियाँ, llms.txt, और खोज इंडेक्स को पुनर्लिखित करता है। सार्वजनिक एसेट्स (छवियाँ, public/ के अंतर्गत फ़ाइलें) साइट रूट पर ही रहती हैं, या यदि आपने base सेट किया है तो उसके अंतर्गत।
यह ऊपर दी गई दो अवधारणाओं से अलग है:
- प्रति-स्रोत
prefixएक स्रोत को नेमस्पेस देता है और एक साइडबार समूह जोड़ता है। deployment.baseवह होस्ट सबडायरेक्टरी है जहाँ से पूरा ऐप परोसा जाता है। दोनों साथ मिलकर काम करते हैं — दोनों सेट होने पर, एक पेज{deployment.base}/{basePath}/pageपर पहुँचता है।
सर्वर रेंडरिंग
स्टैटिक आउटपुट अधिकांश डॉक्स के लिए पर्याप्त है। जब आपको अनुरोध-समय की सुविधाओं की आवश्यकता हो तो सर्वर आउटपुट पर स्विच करें — विशेष रूप से असिस्टेंट एंडपॉइंट और MCP सर्वर के लिए। आप ऐसा होस्ट का नाम देकर करते हैं: deployment blume/deploy से इम्पोर्ट किया गया एक एडाप्टर लेता है।
import { defineConfig } from "blume";
import { vercel } from "blume/deploy";
export default defineConfig({
deployment: vercel(),
});
हर एडाप्टर समान नामित विकल्प लेता है — site, base, और output — और बाकी सब कुछ जस का तस अंतर्निहित @astrojs/* एडाप्टर को आगे भेज देता है, ताकि जिस विकल्प का Blume नाम नहीं लेता, वह भी उस तक पहुँच जाए:
deployment: vercel({
site: "https://docs.example.com",
// Passed straight to @astrojs/vercel.
isr: { expiration: 60 },
}),
| एडाप्टर | पैकेज | किसके लिए उपयोग करें |
|---|---|---|
vercel() |
@astrojs/vercel |
Vercel — सबसे परिष्कृत रास्ता |
netlify() |
@astrojs/netlify |
Netlify Functions |
node() |
@astrojs/node |
स्वयं-होस्ट किए गए Node सर्वर, कंटेनर |
cloudflare() |
@astrojs/cloudflare |
Cloudflare Workers |
vercel() और node() Blume के साथ आते हैं — इनमें से किसी एक को चुनना ही काफ़ी है। netlify() और cloudflare() के पैकेज आपके प्रोजेक्ट में इंस्टॉल करने होंगे (जैसे bun add -d @astrojs/netlify)। पैकेज गायब होने पर, blume build आपके पैकेज मैनेजर के लिए इंस्टॉल कमांड के साथ रुक जाता है, blume dev चेतावनी देता है, और blume doctor इसकी रिपोर्ट करता है। pnpm के साथ, उन पैकेजों द्वारा लाई गई बिल्ड स्क्रिप्ट्स को भी pnpm-workspace.yaml में allowBuilds के अंतर्गत स्वीकृत करें, उस esbuild एंट्री के बगल में जिसे blume init लिखता है: Netlify के लिए sharp, जिसका एडाप्टर उसकी अपनी प्रति लाता है, और Cloudflare के लिए workerd। pnpm 11 और उसके बाद के संस्करण इन्हें स्वीकृत किए जाने तक ERR_PNPM_IGNORED_BUILDS के साथ इंस्टॉल को रोक देते हैं; pnpm 10 एक चेतावनी के साथ स्क्रिप्ट्स को छोड़ देता है। allowBuilds के लिए pnpm 10.26 या नया संस्करण आवश्यक है।
एडाप्टर का नाम देने से बिल्ड सर्वर आउटपुट पर स्विच हो जाता है। उस होस्ट पर स्टैटिक बिल्ड बनाए रखने के लिए — उसकी साइट पहचान और उसके द्वारा पढ़ी जाने वाली प्लेटफ़ॉर्म फ़ाइलों के साथ — output: "static" पास करें:
deployment: netlify({ output: "static" }),
एक सर्वर बिल्ड में वह सब कुछ शामिल होता है जो एक स्टैटिक बिल्ड में होता है, साथ ही आपके द्वारा जोड़े गए कोई भी Astro एंडपॉइंट या मिडलवेयर। node() एडाप्टर एक स्वतंत्र सर्वर बनाता है जिसे आप node dist/server/entry.mjs के साथ सीधे चला सकते हैं। यह localhost:4321 पर सुनता है, जब तक कि आप इसे शुरू करते समय HOST और PORT परिवेश चर सेट न करें (HOST=0.0.0.0 PORT=8080 node dist/server/entry.mjs); node() को पास किए गए host और port का कोई प्रभाव नहीं होता, क्योंकि @astrojs/node उन्हें Astro की अपनी सर्वर सेटिंग्स से बदल देता है। रिवर्स प्रॉक्सी के पीछे, allowedDomains सेट करें ताकि दर सीमा हर पाठक की गणना अलग-अलग करे। सर्वर अपने पैकेजों को आपके प्रोजेक्ट के node_modules में लिंक के माध्यम से हल करता है, इसलिए प्रोजेक्ट को उसकी इंस्टॉल की गई डिपेंडेंसी के साथ परिनियोजित करें, केवल dist/ को नहीं। जब साइट डिस्कवरी फ़ाइलें प्रकाशित करती है, किसी कंटेंट स्रोत द्वारा डाउनलोड की गई छवियाँ परोसती है, या रीडायरेक्ट कॉन्फ़िगर करती है, तो Blume Astro की एंट्री के आगे एक छोटा रैपर रख देता है (एंट्री को उसके बगल में astro-entry.mjs में ले जाया जाता है)। यह .well-known डिस्कवरी फ़ाइलों को उनके मीडिया प्रकारों और CORS हेडर के साथ, और डाउनलोड किए गए SVG को सैंडबॉक्स करके भेजता है, जो स्वतंत्र सर्वर का स्टैटिक हैंडलर स्वयं नहीं कर सकता, और हर रीडायरेक्ट का उत्तर उसके कॉन्फ़िगर किए गए स्टेटस के साथ देता है।
एक vercel() सर्वर बिल्ड, एडाप्टर द्वारा ट्रेस किए गए फ़ंक्शन बंडल में ऐसे पैकेजों की जाँच करता है जिन्हें बंडल इम्पोर्ट तो करता है लेकिन जो कॉपी नहीं किए गए, क्योंकि वे Vercel पर फ़ंक्शन को क्रैश कर देंगे। आपके अपने किसी इम्पोर्ट का गायब होना एक चेतावनी है। Blume की किसी डिपेंडेंसी का गायब होना बिल्ड को रोक देता है, और बिल्ड .vercel/output/config.json को हटा देता है, ताकि vercel deploy --prebuilt उन रूट्स के बिना आउटपुट शिप न कर सके जिन्हें Blume उसमें जोड़ता है।
एक cloudflare() सर्वर बिल्ड केवल Cloudflare Workers पर चलता है, क्योंकि @astrojs/cloudflare ने संस्करण 13 में Cloudflare Pages का समर्थन हटा दिया; एक स्टैटिक बिल्ड इस पैकेज को लोड नहीं करता, इसलिए उसका dist/ अब भी Pages पर परिनियोजित होता है। सर्वर बिल्ड blume build के बाद प्रोजेक्ट रूट से npx wrangler deploy के साथ परिनियोजित होता है: Blume रीडायरेक्ट किया गया Wrangler कॉन्फ़िग .wrangler/deploy/ में लिखता है (और .wrangler/ को .gitignore में जोड़ता है), और Worker का नाम आपके प्रोजेक्ट के नाम पर रखता है — package.json का name, अन्यथा साइट का होस्टनेम, अन्यथा फ़ोल्डर — जब तक कि प्रोजेक्ट रूट पर आपकी अपनी wrangler.jsonc name सेट न करे।
Vercel और Cloudflare पर, एक सर्वर बिल्ड Accept: text/markdown कंटेंट नेगोशिएशन को भी चालू कर देता है, ताकि उस हेडर के साथ किसी भी कंटेंट पेज का अनुरोध करने वाले एजेंट को उसी URL पर उसका रॉ-Markdown मिरर मिले। Vercel पर, Blume डिप्लॉय के रूटिंग कॉन्फ़िग में हेडर-सशर्त रीराइट्स जोड़ देता है; Cloudflare पर, यह Astro वाले Worker के आगे एक छोटा Worker उत्पन्न करता है और assets.run_worker_first को फ़िंगरप्रिंट किए गए बिल्ड एसेट्स और रॉ .md, .txt, .json, और .well-known फ़ाइलों को छोड़कर हर पथ की ओर इंगित करता है, क्योंकि अन्यथा प्लेटफ़ॉर्म कोई भी सर्वर कोड चलने से पहले ही प्रीरेंडर किए गए पेज — और जिस URL के पीछे कोई पेज न हो उसके लिए अपना 404.html — परोस देता; वे छूट प्राप्त फ़ाइलें अपना शून्य-Worker तेज़ रास्ता बनाए रखती हैं। जब प्रीरेंडर किए गए प्रति-पेज JSON दस्तावेज़ों (/api/docs/pages/{route}.json) में से किसी का अनुरोध उस Worker तक पहुँचता है, तो वह Worker उसका उत्तर भी एसेट बाइंडिंग से देता है, क्योंकि अन्यथा Astro उसे /api/ कैच-ऑल की ओर रूट कर देता।
निजी डॉक्स
Blume का अपना कोई साइन-इन नहीं है। एक स्टैटिक बिल्ड केवल सादी फ़ाइलें होता है, और जो कोई भी होस्ट तक पहुँच सकता है, वह dist/ में से कुछ भी फ़ेच कर सकता है। किसी साइट को निजी रखने के लिए, अपने होस्ट की एक्सेस सुरक्षा चालू करें, जो किसी फ़ाइल के परोसे जाने से पहले हर अनुरोध की जाँच करती है:
- Vercel: All Deployments स्कोप के साथ Deployment Protection, ताकि केवल प्रीव्यू ही नहीं, बल्कि प्रोडक्शन भी कवर हो। Vercel Authentication आपकी Vercel टीम के सदस्यों को प्रवेश देता है; सशुल्क प्लान पर, Password Protection साझा पासवर्ड वाले किसी भी व्यक्ति को प्रवेश देता है।
- Netlify: सभी डिप्लॉय पर पासवर्ड सुरक्षा, साझा पासवर्ड के साथ, या Enterprise प्लान पर टीम लॉगिन के साथ।
- Cloudflare: साइट परोसने वाले Worker पर Cloudflare Access (Workers & Pages, फिर आपका Worker, फिर Access), जो उन सभी डोमेन को कवर करता है जिन पर वह उत्तर देता है। ईमेल पते, ईमेल डोमेन, या Cloudflare खाते की सदस्यता के आधार पर चुनें कि कौन साइन इन कर सकता है।
- GitHub Pages: GitHub Enterprise Cloud पर किसी संगठन से साइट को निजी रूप से प्रकाशित करें, और केवल वही लोग इसे देख सकेंगे जिनके पास रिपॉज़िटरी का पढ़ने का एक्सेस है।
- आपका अपना सर्वर:
dist/के आगे प्रमाणीकरण रखें, जैसे nginx काauth_basicया एक पहचान-सजग प्रॉक्सी।
होस्ट सुरक्षा सर्वर बिल्ड के लिए भी उसी तरह काम करती है। यह पूरी साइट को कवर करती है: कुछ पेजों को सार्वजनिक रखने के लिए, उन्हें एक अलग साइट के रूप में प्रकाशित करें।
Blume द्वारा dist/ में लिखी गई हर चीज़ सुरक्षा के पीछे रहती है, जिसमें पेज, खोज इंडेक्स, .md प्रतियाँ, llms.txt, और Open Graph छवियाँ शामिल हैं। कुछ सुविधाएँ इसके बाहर तक पहुँचती हैं:
- एक होस्ट किया गया खोज प्रदाता (Algolia, Orama Cloud, Typesense, या Mixedbread) उस सेवा पर आपके कंटेंट की अपनी प्रति रखता है। अंतर्निहित Orama, FlexSearch, और Pagefind इंडेक्स
dist/में मौजूद फ़ाइलें हैं, इसलिए वे निजी रहते हैं। - सुरक्षा के बाहर की सेवाएँ आपके पेज नहीं पढ़ सकतीं। Open in chat ChatGPT या Claude को एक ऐसा लिंक देता है जिसे वह खोल नहीं सकता, Slack या X में लिंक प्रीव्यू आपके Open Graph कार्ड नहीं दिखा सकते, और एजेंट
llms.txtया MCP सर्वर को नहीं पढ़ सकते। चैट क्रियाओं को छिपाने के लिएai.openInChat: falseसेट करें।
रीडायरेक्ट
blume.config.ts में पुराने URL को नए URL से मैप करें:
redirects: [{ from: "/old", to: "/new", status: 301 }],
status 301, 302, 307, या 308 स्वीकार करता है (डिफ़ॉल्ट 301)। सर्वर बिल्ड रीडायरेक्ट को अनुरोध-समय पर कॉन्फ़िगर किए गए स्टेटस के साथ संभालते हैं, और blume dev व blume preview भी ऐसा ही करते हैं। स्टैटिक बिल्ड रीडायरेक्ट पेज और वे प्लेटफ़ॉर्म फ़ाइलें दोनों उत्पन्न करते हैं जिन्हें आपका होस्ट पढ़ता है, ताकि वह एक वास्तविक HTTP रीडायरेक्ट जारी करे: netlify() और cloudflare() के लिए _redirects, vercel() के लिए vercel.json, और — जब किसी होस्ट का नाम न दिया गया हो — ये दोनों, साथ ही blume-redirects.json, बाकी सब कुछ के लिए एक संरचित मैनिफ़ेस्ट (nginx/Apache नियम, एक एज वर्कर)। public/ में आपके द्वारा शिप की गई _redirects या vercel.json फ़ाइल अछूती छोड़ दी जाती है।
जो रीडायरेक्ट एक पेज को दूसरे पेज पर ले जाता है, वह पेज के रॉ Markdown को भी साथ ले जाता है: blume dev और हर बिल्ड में, /old.md और /old.mdx उसी स्टेटस के साथ /new.md और /new.mdx पर रीडायरेक्ट होते हैं। किसी .html URL से होने वाला रीडायरेक्ट, जैसे आपके द्वारा माइग्रेट की गई किसी साइट का /old.html, ऐसा नहीं करता, क्योंकि उस URL की कभी कोई Markdown प्रति नहीं थी। न ही वह रीडायरेक्ट ऐसा करता है जिसका Markdown URL पहले से ही एक प्रति परोसता है: /index.md होम पेज की प्रति है, इसलिए /index से / पर होने वाला रीडायरेक्ट उसे अछूता छोड़ देता है।
किसी पेज के अपने index.html URL से होने वाले रीडायरेक्ट, जैसे /guide/index.html से /guide पर, के लिए एक स्टैटिक बिल्ड में कोई रीडायरेक्ट पेज नहीं बनता, क्योंकि पेज स्वयं उसी फ़ाइल में लिखा जाता है। जो होस्ट रीडायरेक्ट फ़ाइलें पढ़ते हैं, वे इसका उत्तर रीडायरेक्ट के साथ देते हैं। कोई भी अन्य होस्ट उस URL पर पेज परोसता है।
Blume स्वयं एक प्रकार का रीडायरेक्ट जोड़ता है: तारीख़ के नाम वाला कोई पेज, जिसे किसी पिछले संस्करण ने एक छोटे URL के अंतर्गत प्रकाशित किया था, जैसे /changelog/05-2022 पर changelog/12-05-2022.mdx, उस URL से अपने स्वयं के URL पर रीडायरेक्ट होता है (संख्यात्मक उपसर्गों के साथ क्रम देखें)। जहाँ पुराने URL पर कोई दूसरा पेज मौजूद हो या आपके द्वारा कॉन्फ़िगर किया गया कोई रीडायरेक्ट पहले से वहीं से शुरू होता हो, वहाँ यह कोई रीडायरेक्ट नहीं जोड़ता।
दो होस्ट्स को फ़ाइल से अधिक की आवश्यकता होती है:
- Netlify रीडायरेक्ट नियम के बजाय पहले से मौजूद फ़ाइल को परोसता है, जब तक कि नियम फ़ोर्स न किया गया हो, और एक स्टैटिक बिल्ड में हर
fromपर एक रीडायरेक्ट पेज होता है।netlify()के लिए_redirectsअपने नियमों को फ़ोर्स करता है (/old /new 301!)। Cloudflare उस फ़्लैग को अस्वीकार करता है, इसलिए किसी नामित होस्ट के बिना बने बिल्ड द्वारा लिखी गई फ़ाइल में यह फ़्लैग नहीं होता, और Netlify पर वह बिल्ड इसके बजाय रीडायरेक्ट पेज के साथ उत्तर देता है; HTTP रीडायरेक्ट पाने के लिएnetlify({ output: "static" })के साथ होस्ट का नाम दें। - Vercel
vercel.jsonको प्रोजेक्ट की रूट डायरेक्टरी से पढ़ता है, आउटपुट डायरेक्टरी से कभी नहीं, इसलिएdist/में मौजूद प्रति केवल तभी लागू होती है जब आप उसी फ़ोल्डर को Vercel CLI (vercel deploy dist) के साथ परिनियोजित करते हैं। एक Git-कनेक्टेड प्रोजेक्ट इसे कभी नहीं पढ़ता: वह रीडायरेक्ट पेज परोसता है और कंटेंट प्रकार में से कोई भी हेडर नहीं भेजता।dist/vercel.jsonसेredirectsऔरheadersको अपने प्रोजेक्ट की रूट डायरेक्टरी कीvercel.jsonमें कॉपी करें, या सर्वर बिल्ड के लिएvercel()का उपयोग करें, जिसका रूटिंग कॉन्फ़िग रीडायरेक्ट और डिस्कवरी हेडर साथ ले जाता है।
पैटर्न रीडायरेक्ट
एक from एक साथ कई पथों को कवर कर सकता है, और इसे उसी तरह लिखा जाता है जैसे Mintlify और vercel.json लिखते हैं:
redirects: [
{ from: "/beta/:slug*", to: "/v2/:slug*" },
{ from: "/blog/:slug", to: "/articles/:slug" },
{ from: "/articles/concepts-*", to: "/concepts" },
{ from: "/old/article-*", to: "/new/article-*" },
],
:nameएक पूरे सेगमेंट से मेल खाता है:/blog/:slug/blog/helloको कवर करता है,/blog/a/bको नहीं।- अंतिम सेगमेंट के रूप में
:name*पथ के शेष भाग से मेल खाता है, चाहे उसमें कितने भी सेगमेंट हों:/beta/:slug*/beta/guides/setupको/v2/guides/setupपर, और स्वयं/betaको/v2पर भेजता है। अंतिम सेगमेंट के रूप में*भी यही करता है। हर होस्ट को वह सादा पथ उसके अपने एक अलग नियम के रूप में मिलता है (_redirectsमें/beta /v2), ताकि सभी होस्ट उसे एक ही जगह भेजें।blume auditजाँचता है कि वह कहाँ पहुँचता है, और यदि/betaऐसे/v2पर जाता है जिसे बिल्ड परोसता नहीं, तो उसे एक टूटे हुए रीडायरेक्ट के रूप में रिपोर्ट करता है। - किसी सेगमेंट के अंत में
*वहाँ से आगे पथ के शेष भाग से मेल खाता है:/articles/concepts-*/articles/concepts-overviewको कवर करता है।
to किसी कैप्चर को उसके नाम से, एक पूरे सेगमेंट के रूप में (/:slug*, /:slug), पढ़ता है, या from में मौजूद * जिस भाग से मेल खाया, उसे एक * के रूप में पढ़ता है (_redirects की वर्तनी वाला :splat भी इसे पढ़ता है)। जो to कोई कैप्चर नहीं पढ़ता, वह पैटर्न द्वारा कवर किए गए हर पथ को एक ही पेज पर भेज देता है। उसी पथ को कवर करने वाले पैटर्न की तुलना में एक सटीक रीडायरेक्ट को प्राथमिकता मिलती है, और पैटर्न को उसी क्रम में आज़माया जाता है जिसमें आप उन्हें सूचीबद्ध करते हैं।
हर होस्ट को पैटर्न उसके अपने सिंटैक्स में मिलते हैं: _redirects में स्प्लैट, vercel.json में path-to-regexp स्रोत, और vercel() या netlify() सर्वर बिल्ड का रूटिंग कॉन्फ़िग। node() और cloudflare() सर्वर उनका मिलान स्वयं करते हैं, और blume dev व blume preview भी ऐसा ही करते हैं। एक स्टैटिक बिल्ड किसी पैटर्न के लिए कोई रीडायरेक्ट पेज नहीं लिखता, क्योंकि उसके लिए पैटर्न द्वारा कवर किए गए हर पथ के लिए एक पेज की आवश्यकता होगी, इसलिए जो होस्ट इनमें से कोई भी फ़ाइल नहीं पढ़ता (जैसे GitHub Pages), वह केवल सटीक रीडायरेक्ट लागू करता है; blume-redirects.json पैटर्न को वैसे ही सूचीबद्ध करता है जैसे आपने उन्हें लिखा था।
blume validate जाँचता है कि हर रीडायरेक्ट कहाँ ले जाता है। एक सटीक to एक पेज, public/ की कोई फ़ाइल या Blume द्वारा जनरेट की गई कोई फ़ाइल, या किसी अन्य रीडायरेक्ट का from होना चाहिए; किसी पैटर्न के लिए, to के पहले कैप्चर से पहले वाले शाब्दिक भाग (/v2/:slug* में /v2/) के अंतर्गत कुछ न कुछ परोसा जाना चाहिए। जो रीडायरेक्ट कहीं नहीं ले जाता, उसके to पर BLUME_BROKEN_REDIRECT की चेतावनी दी जाती है। blume audit बिल्ड की गई साइट में हर रीडायरेक्ट का अनुसरण करता है।
कोई पैटर्न किसी पेज से भी मेल नहीं खा सकता: दोनों में से कौन उत्तर देगा, इस पर होस्ट्स एकमत नहीं हैं, इसलिए बिल्ड BLUME_REDIRECT_MATCHES_PAGE के साथ, उस पेज का नाम बताते हुए, रुक जाता है। पैटर्न को केवल उन्हीं पथों तक सीमित करें जो स्थानांतरित हुए हैं। किसी पेज के अपने URL से एक सटीक रीडायरेक्ट हर होस्ट पर एक ही तरह से उत्तर देता है, और वह URL को अपने अधिकार में ले लेता है ताकि पेज कभी प्रकाशित न हो, इसलिए वहाँ यही कोड एक चेतावनी है: यदि पेज स्थानांतरित हुआ है तो उसे हटा दें, अन्यथा रीडायरेक्ट को हटा दें। किसी पेज की Markdown प्रति से होने वाला रीडायरेक्ट भी, जैसे /guide.md या होम पेज का /index.md, एक चेतावनी है, क्योंकि वह उस प्रति को एजेंटों से छीन लेता है: रीडायरेक्ट को हटा दें।
कंटेंट प्रकार
जहाँ होस्ट इसे पढ़ता है, वहाँ एक बिल्ड एक _headers फ़ाइल भी उत्पन्न करता है जो रॉ AI-तैयार एंडपॉइंट्स — /<route>.md, /<route>.mdx, और .txt फ़ाइलों (llms.txt, llms-full.txt) — पर charset=utf-8 निर्धारित करती है। वे प्रतिक्रियाएँ वैध UTF-8 होती हैं, लेकिन कई स्टैटिक होस्ट उन्हें बिना किसी charset के text/markdown / text/plain के रूप में परोसते हैं, और तब ब्राउज़र Windows-1252 पर वापस चले जाते हैं — इसलिए गैर-ASCII डॉक्स (जापानी, उच्चारण-चिह्न वाली लैटिन, …) रॉ URL सीधे खोलने पर मोजिबाके के रूप में दिखते हैं। HTML पेज इससे अप्रभावित रहते हैं क्योंकि उनमें <meta charset> होता है। Netlify स्टैटिक डिप्लॉय पर _headers पढ़ता है और Cloudflare (Pages, और Workers स्टैटिक एसेट्स) स्टैटिक और सर्वर दोनों बिल्ड पर, इसलिए उन एडाप्टर और बिना नाम वाले स्टैटिक होस्ट को यह फ़ाइल मिलती है; Vercel (जिसके हेडर रूटिंग कॉन्फ़िग के साथ जाते हैं) और Node (जिसका सर्वर इस फ़ाइल को अनदेखा करता है) को नहीं मिलती। एक Netlify सर्वर बिल्ड इसके बजाय यही नियम अपने Frameworks API कॉन्फ़िग (.netlify/v1/config.json) के headers में लिखता है। एक स्टैटिक Vercel बिल्ड इसके बजाय यही नियम dist/vercel.json में लिखता है, जिसे एक Git-कनेक्टेड प्रोजेक्ट नहीं पढ़ता (रीडायरेक्ट देखें)। public/ में आपके द्वारा शिप की गई _headers फ़ाइल अछूती छोड़ दी जाती है।
Powered-by हेडर
Blume एक X-Powered-By: Blume प्रतिक्रिया हेडर में अपना नाम देता है, ताकि HTTP इंस्पेक्टर और टेक्नोलॉजी डिटेक्टर बता सकें कि साइट किससे बनी है। इसे हटाने के लिए poweredBy को false पर सेट करें:
poweredBy: false,
blume dev इसे हर प्रतिक्रिया पर भेजता है। एक सर्वर बिल्ड इसे वहाँ से भेजता है जहाँ से होस्ट अपने हेडर लेता है: node() सर्वर और cloudflare() Worker इसे स्वयं सेट करते हैं, एक vercel() बिल्ड इसे अपने रूटिंग कॉन्फ़िग में ले जाता है, और एक netlify() बिल्ड अपने Frameworks API कॉन्फ़िग के हेडर नियमों में, जिसमें Blume का मिडलवेयर इसे मांग पर रेंडर किए गए पेजों में जोड़ता है। एक स्टैटिक बिल्ड इसे कंटेंट प्रकारों के बगल में _headers और dist/vercel.json में सूचीबद्ध करता है, इसलिए यह उन्हीं होस्ट्स तक पहुँचता है जहाँ तक ये फ़ाइलें पहुँचती हैं: Git-कनेक्टेड Vercel प्रोजेक्ट तक नहीं, और ऐसे होस्ट तक भी नहीं जो कोई कस्टम हेडर नहीं भेजता, जैसे GitHub Pages।
एक इजेक्ट किए गए ऐप में, यह स्विच astro.config.mjs में blumeIntegration() का poweredBy विकल्प है। उसका बिल्ड सर्वर-रेंडर किए गए पेजों पर और _headers से हेडर भेजता है; सर्वर-एंट्री रैपर और रूटिंग कॉन्फ़िग, जो इसे अन्य जगहों पर ले जाते हैं, blume build के चरण हैं।
परिवेश चर
जब किसी सुविधा को एक सीक्रेट की आवश्यकता होती है, तो Blume blume dev/build पर चेतावनी देता है यदि वह गायब है — ताकि समस्या पहले अनुरोध के बजाय पहले ही सामने आ जाए:
| सुविधा | चर |
|---|---|
| असिस्टेंट (AI Gateway) | AI_GATEWAY_API_KEY (या Vercel OIDC) |
| असिस्टेंट (अन्य एडाप्टर) | एडाप्टर का डिफ़ॉल्ट कुंजी एन्व चर (OPENAI_API_KEY, ANTHROPIC_API_KEY, GEMINI_API_KEY, XAI_API_KEY, OPENROUTER_API_KEY, LLMGATEWAY_API_KEY, INKEEP_API_KEY), या आपके द्वारा उसे पास किया गया apiKeyEnv |
| असिस्टेंट बॉट सुरक्षा | TURNSTILE_SECRET_KEY (turnstile()), HCAPTCHA_SECRET_KEY (hcaptcha()) |
दर सीमित करना (upstash()) |
UPSTASH_REDIS_REST_URL और UPSTASH_REDIS_REST_TOKEN |
दर सीमित करना (unkey()) |
UNKEY_ROOT_KEY, या आपके द्वारा उसे पास किया गया rootKeyEnv |
| Mixedbread खोज | MIXEDBREAD_API_KEY |
| नैरेशन (जनरेट की गई आवाज़ें) | gateway() के लिए AI_GATEWAY_API_KEY (या Vercel OIDC), openai() के लिए OPENAI_API_KEY (baseUrl के साथ कोई नहीं, जब तक कि आप किसी का नाम न दें), या आपके द्वारा दोनों में से किसी को भी पास किया गया apiKeyEnv |
| कंटेंट स्रोत | NOTION_TOKEN (notion()), SANITY_TOKEN (sanity()), CONTENTFUL_ACCESS_TOKEN (contentful(), साथ ही --preview के लिए CONTENTFUL_PREVIEW_TOKEN, जिसके बिना यह विफल हो जाता है), PAYLOAD_API_KEY (payload()), STRAPI_API_TOKEN (strapi()), GITHUB_TOKEN (githubReleases(), और github के साथ mdxRemote()) |
स्थानीय डेव के लिए इन्हें .env.local में और प्रोडक्शन के लिए अपने होस्ट के परिवेश में सेट करें। एक कंटेंट स्रोत blume dev और blume build के दौरान फ़ेच करते समय अपना टोकन पढ़ता है, और नैरेशन blume build के दौरान अपनी कुंजी पढ़ता है, इसलिए इन्हें वहाँ सेट करें जहाँ आपकी साइट बिल्ड होती है। खोज-इंडेक्स सिंक के लिए बिल्ड-समय के सीक्रेट्स (ALGOLIA_ADMIN_API_KEY, ORAMA_PRIVATE_API_KEY, TYPESENSE_ADMIN_API_KEY) की जाँच स्वयं सिंक चरण करता है: जब इनमें से कोई सेट न हो, तो बिल्ड चेतावनी देता है और सिंक को छोड़ देता है, और जब यह सेट हो, तो एक विफल सिंक बिल्ड को विफल कर देता है। GitHub info कार्ड भी, जब GITHUB_TOKEN सेट हो, GitHub की API दर सीमा बढ़ाने के लिए उसे भेजता है।
बिल्ड कैश
Blume दो कैश रखता है जिनका एक बिल्ड पुन: उपयोग कर सकता है। Astro और Vite के कैश .blume/.cache/ के अंतर्गत रहते हैं (इनमें कंटेंट स्टोर और इमेज ट्रांसफ़ॉर्म शामिल हैं)। रेंडर किए गए OG कार्ड node_modules/.cache/blume/og में रहते हैं, ताकि एक रीबिल्ड केवल उन्हीं कार्डों को रेंडर करे जिनका शीर्षक, विवरण, या ब्रांडिंग बदली है। कोई प्लेटफ़ॉर्म डिप्लॉय के बीच उस डायरेक्टरी को बनाए रखता है या नहीं, यह अलग-अलग होता है:
- Vercel अपने बिल्ड कैश से
node_modules/**को पुनर्स्थापित करता है, इसलिए कार्ड आगे बने रहते हैं (कैश 1 GB का होता है, एक महीने तक रखा जाता है, और प्रति ब्रांच कुंजीबद्ध होता है — एक नई ब्रांच प्रोडक्शन कैश से शुरू होती है)। - Netlify
node_modulesको पुनर्स्थापित करता है, इसलिए कार्ड आगे बने रहते हैं। - Cloudflare Workers Builds केवल पैकेज-मैनेजर कैश और, पहचाने गए Astro प्रोजेक्ट के लिए,
node_modules/.astroको बनाए रखता है —node_modules/.cacheको कभी नहीं — इसलिए वहाँ हर डिप्लॉय हर कार्ड को रेंडर करता है। - GitHub Actions और आपके द्वारा प्रबंधित अन्य रनर कुछ भी नहीं रखते, जब तक कि आप स्वयं उस डायरेक्टरी को कैश न करें:
- uses: actions/cache@v6
with:
path: node_modules/.cache/blume/og
key: blume-og-${{ runner.os }}-${{ hashFiles('**/bun.lock', '**/package-lock.json', '**/pnpm-lock.yaml') }}
restore-keys: blume-og-${{ runner.os }}-
कार्ड कंटेंट के आधार पर कुंजीबद्ध होते हैं, इसलिए एक अपरिशुद्ध कुंजी भी ठीक है: पुनर्स्थापित कैश केवल रेंडर बचाता है, कभी गलत कार्ड नहीं परोसता।
एक इंस्टॉल कमांड हर प्लेटफ़ॉर्म पर कैश को हटा देता है: npm ci इंस्टॉल करने से पहले node_modules को हटा देता है। पुन: उपयोग का लाभ पाने के लिए इंस्टॉल कमांड के रूप में npm install, bun install, या pnpm install का उपयोग करें।
बिल्ड सारांश
हर बिल्ड एक सारांश प्रिंट करता है — आउटपुट मोड, एडाप्टर, हल किया गया साइट URL, खोज प्रदाता, रीडायरेक्ट संख्या, साइटमैप और llms.txt की स्थिति, और कोई भी सक्षम सर्वर सुविधाएँ — ताकि परिनियोजित करने से पहले आप पुष्टि कर सकें कि क्या शिप हुआ (स्वतः पहचानी गई हर चीज़ सहित)।