---
title: कस्टमाइज़ेशन
description: >-
  कंपोनेंट्स को ओवरराइड करें, इंटरैक्टिव आइलैंड्स जोड़ें, कस्टम पेज माउंट करें, रजिस्ट्री कंपोनेंट्स इंस्टॉल करें, या जब आपको पूरा नियंत्रण चाहिए तो पूरी तरह इजेक्ट कर दें।
---

## कंपोनेंट ओवरराइड्स [#component-overrides]

अपने प्रोजेक्ट रूट में एक `components.ts` (या `components.tsx`) जोड़ें और `defineComponents` एक्सपोर्ट करें। `mdx` मैप या तो किसी बिल्ट-इन कंपोनेंट को **बदल देता है** या एक नया कंपोनेंट **जोड़ता है** — जो बिना किसी इम्पोर्ट के हर `.mdx` पेज में उपलब्ध रहता है।

```ts components.ts lineNumbers
import { defineComponents } from "blume";
import Callout from "./components/Callout.astro";
import Pricing from "./components/Pricing.astro";

export default defineComponents({
  mdx: {
    Callout, // replace the built-in Callout
    Pricing, // add a new <Pricing /> component
  },
});
```

कीज़ वही नाम होते हैं जो आप MDX में लिखते हैं (`<Callout>`, `<Pricing>`)। जब आप React कंपोनेंट्स इम्पोर्ट करें तो `.tsx` फ़ाइलनाम का उपयोग करें।

### रेफ़रेंस रूप [#reference-form]

हर ओवरराइड — चाहे `mdx`, `layout`, या `islands` में हो — तीन रूप स्वीकार करता है:

```ts components.ts
import { defineComponents } from "blume";
import Callout from "./components/Callout.astro";

export default defineComponents({
  mdx: {
    Callout, // 1. an imported component
    Note: "./components/Note.astro", // 2. a path string (resolved from the project root)
    Chart: { component: "./components/Chart.tsx", client: "load" }, // 3. a descriptor
  },
});
```

**डिस्क्रिप्टर** रूप एक हाइड्रेशन मोड जोड़ता है ताकि कोई इंटरैक्टिव React/Vue/Svelte कंपोनेंट अपना JavaScript भेजे और क्लाइंट पर जीवंत हो जाए। `client` मोड के बिना कोई फ़्रेमवर्क कंपोनेंट स्टैटिक HTML के रूप में रेंडर होता है — Blume ऐसा कंपोनेंट मिलने पर बिल्ड चेतावनी प्रिंट करता है, क्योंकि यह आमतौर पर एक गलती होती है।

| `client` | हाइड्रेट होता है |
| --- | --- |
| `"load"` | पेज लोड होते ही तुरंत |
| `"idle"` | जब मेन थ्रेड निष्क्रिय हो |
| `"visible"` | जब स्क्रॉल करके दृश्य में आए |
| `"media"` | जब कोई `media` क्वेरी मैच करे (`media: "(min-width: 40rem)"` जोड़ें) |
| `"only"` | केवल क्लाइंट पर, कभी सर्वर-रेंडर नहीं |

जिन इंटरैक्टिव कंपोनेंट्स का उपयोग आप कई पेजों में करते हैं, उनके लिए [`islands` समूह](/docs/content/islands#registering-islands-in-componentsts) `client: "visible"` के साथ डिस्क्रिप्टर रूप का संक्षिप्त रूप है।

### किसी ओवरराइड को टाइप करना [#typing-an-override]

जब आप किसी बिल्ट-इन को बदलें, तो उसका प्रॉप टाइप `blume/components` से इम्पोर्ट करें ताकि आपका कंपोनेंट अनुबंध से मेल खाए — ये टाइप्स कंपोनेंट्स से ही व्युत्पन्न होते हैं, इसलिए वे कभी अलग नहीं होते:

```tsx components/Callout.tsx
import type { CalloutProps } from "blume/components";

export default function Callout(props: CalloutProps) {
  // …your own callout, same props as the built-in
}
```

कंटेंट कंपोनेंट्स के लिए प्रॉप टाइप्स एक्सपोर्ट किए जाते हैं (`CalloutProps`, `CardProps`, `TabsProps`, `StepsProps`, `BadgeProps`, और अन्य)।

## लेआउट स्लॉट्स [#layout-slots]

`layout` मैप Blume के क्रोम के किसी हिस्से को आपके अपने कंपोनेंट से बदल देता है। हर ओवरराइड को वही प्रॉप्स मिलते हैं जो उस बिल्ट-इन को मिलते हैं जिसे वह बदल रहा है, इसलिए आप डिफ़ॉल्ट को रैप कर सकते हैं या शुरू से बना सकते हैं।

```ts components.ts
import { defineComponents } from "blume";
import Footer from "./components/Footer.astro";
import Logo from "./components/Logo.astro";

export default defineComponents({
  layout: {
    Logo, // brand mark + title in the header
    Footer, // site-wide footer (no built-in — renders only when set)
  },
});
```

जुड़े हुए स्लॉट्स:

| स्लॉट | किसे बदलता है | प्रॉप्स |
| --- | --- | --- |
| `Layout` | पूरा पेज शेल (`RootLayout`) | वह सब कुछ जो बिल्ट-इन लेआउट को मिलता है, साथ ही `layout` मैप |
| `Header` | ऊपरी नेविगेशन बार | `site`, `logo`, `navigation`, `route`, `searchEnabled`, … |
| `Logo` | हेडर में ब्रांड लिंक (मार्क + शीर्षक) | `site`, `logo` |
| `Search` | हेडर का सर्च ट्रिगर + मोडल | `navigation`, `strings`, `locale`, `askEnabled` |
| `Sidebar` | प्राथमिक नेविगेशन ट्री | `items`, `currentRoute` |
| `MobileNav` | मोबाइल ड्रॉअर के अंदर का नेव (डिफ़ॉल्ट रूप से `Sidebar`) | `items`, `currentRoute` |
| `Breadcrumbs` | ब्रेडक्रम्ब पथ | `crumbs` |
| `TableOfContents` | इस पेज पर वाली रूपरेखा | `headings`, `title`, `variant` |
| `Pagination` | पिछला/अगला फुटर लिंक | `prev`, `next`, `strings` |
| `PageHeader` | लेख के ऊपर एक इंजेक्शन बिंदु (कोई बिल्ट-इन नहीं) | `page`, `headings`, `route` |
| `PageFooter` | लेख के नीचे एक इंजेक्शन बिंदु (कोई बिल्ट-इन नहीं) | `page`, `headings`, `route` |
| `Footer` | कंटेंट ग्रिड के बाद साइट-व्यापी फुटर (कोई बिल्ट-इन नहीं) | `site`, `navigation`, `ui` |

`PageHeader`, `PageFooter`, और `Footer` का कोई बिल्ट-इन कंपोनेंट नहीं है — जब तक आप उन्हें सेट नहीं करते वे कुछ भी रेंडर नहीं करते, जिससे वे किसी प्रोमो बैनर, "अंतिम बार अपडेट किया गया" नोट, या मार्केटिंग फुटर के लिए सुविधाजनक इंजेक्शन बिंदु बन जाते हैं।

लेआउट स्लॉट्स MDX ओवरराइड्स जैसे ही [तीन रेफ़रेंस रूप](#reference-form) स्वीकार करते हैं, इसलिए जब आप इंटरैक्टिव हेडर या फुटर चाहें तो कोई स्लॉट एक पाथ स्ट्रिंग या हाइड्रेटेड डिस्क्रिप्टर (`{ component, client }`) हो सकता है।

## इंटरैक्टिव आइलैंड्स [#interactive-islands]

इंटरैक्टिव UI (React, Vue, या Svelte) के लिए, किसी कंपोनेंट को `islands/` फ़ोल्डर में रखें और उसे किसी भी MDX पेज में उपयोग करें — Blume उसे आपके लिए हाइड्रेट करता है, किसी रैपर या रजिस्ट्रेशन की ज़रूरत नहीं:

```tsx islands/Counter.tsx lineNumbers
import { useState } from "react";

export default function Counter() {
  const [n, setN] = useState(0);
  return <button onClick={() => setN(n + 1)}>Clicked {n}</button>;
}
```

```mdx page.mdx
Use it anywhere: <Counter />
```

हाइड्रेशन रणनीतियों और फ़्रेमवर्क सेटअप के लिए [Islands](/docs/content/islands) देखें।

## कस्टम पेज [#custom-pages]

अपने डॉक्स के साथ पूरी तरह कस्टम रूट माउंट करने के लिए अपने `pages/` फ़ोल्डर के अंतर्गत `.astro` फ़ाइलें जोड़ें — एक लैंडिंग पेज, एक प्राइसिंग पेज, या हाथ से बनाया गया इंडेक्स। वे अपना स्थान बनाए रखते हैं, इसलिए रिलेटिव इम्पोर्ट्स और `getStaticPaths` सामान्य रूप से काम करते हैं, और वे `blume:data` मॉड्यूल से आपका कॉन्फ़िग, नेविगेशन, और रूट्स पढ़ सकते हैं।

पूरी गाइड के लिए [Custom Pages](/docs/advanced/custom-pages) देखें।

## रजिस्ट्री [#registry]

`blume add` किसी Blume-रखरखावित कंपोनेंट को आपके प्रोजेक्ट में **सोर्स** के रूप में कॉपी करता है — वह आपका होता है और आप उसे स्वतंत्र रूप से संपादित कर सकते हैं। जो उपलब्ध है उसकी सूची देखने के लिए इसे बिना किसी आर्ग्युमेंट के चलाएँ:

```bash
blume add
```

कोई लेआउट स्लॉट (हेडर, साइडबार, ब्रेडक्रम्ब्स, टेबल ऑफ़ कंटेंट्स, पेजिनेशन, या फ़ीडबैक) या कोई भी कंटेंट कंपोनेंट (कॉलआउट, कार्ड, टैब्स, स्टेप्स, अकॉर्डियन, और अन्य) इंस्टॉल करें:

```bash
blume add callout
blume add pagination
```

कॉपी बाक़ी फ़्रेमवर्क को `blume/*` से इम्पोर्ट करती है, इसलिए जब तक आप उसे बदलते नहीं, वह ठीक बिल्ट-इन की तरह ही रेंडर होती है। `blume add` उसे रजिस्टर करने के लिए `defineComponents` स्निपेट प्रिंट करता है — कंटेंट कंपोनेंट्स `mdx` के अंतर्गत, लेआउट हिस्से `layout` के अंतर्गत।

## Astro इंटीग्रेशन [#astro-integrations]

`blume.config.ts` में शीर्ष-स्तरीय `integrations` ऐरे से कोई भी Astro इंटीग्रेशन जोड़ें। पहले इंटीग्रेशन को अपनी साइट में इंस्टॉल करें; Blume उसे जनरेट किए गए रनटाइम की डिपेंडेंसीज़ में नहीं जोड़ता और न ही उसकी Astro संगतता प्रबंधित करता है।

```bash
npm install @astrojs/sitemap
```

```ts blume.config.ts lineNumbers
import sitemap from "@astrojs/sitemap";
import { defineConfig } from "blume";

export default defineConfig({
  integrations: [
    sitemap({
      filter: (page) => !page.includes("/drafts/"),
    }),
  ],
});
```

Blume अपने बिल्ट-इन इंटीग्रेशन को उनके मौजूदा क्रम में रखता है, फिर आपकी प्रविष्टियाँ घोषणा क्रम में जोड़ता है। यह उन्हें न तो क्रमबद्ध करता है और न ही डुप्लिकेट हटाता है, इसलिए समान `name` वाले दो इंटीग्रेशन दोनों चलते हैं। Blume यह सत्यापित करता है कि `integrations` एक ऐरे है, जबकि Astro हर प्रविष्टि को सत्यापित करता है और अमान्य इंटीग्रेशन की रिपोर्ट देता है।

चूँकि Blume आपके इंटीग्रेशन को इंस्टेंस कॉपी करने के बजाय जनरेट किए गए Astro कॉन्फ़िग से `blume.config.ts` को फिर से इम्पोर्ट करके लोड करता है, इसलिए कॉन्फ़िग मॉड्यूल प्रति रन दो बार मूल्यांकित होता है — एक बार जब Blume आपका कॉन्फ़िग पढ़ता है और एक बार जब Astro उसे लोड करता है। इंटीग्रेशन फ़ैक्ट्रियों को साइड-इफ़ेक्ट मुक्त रखें (इंटीग्रेशन लौटाएँ; निर्माण के समय फ़ाइलें न लिखें या कनेक्शन न खोलें) ताकि दूसरा मूल्यांकन हानिरहित रहे।

वही इंटीग्रेशन `blume dev` और `blume build` दोनों में चलते हैं। `blume dev` के दौरान `blume.config.ts` संपादित करने से छिपा हुआ Astro कॉन्फ़िग फिर से जनरेट होता है और कॉन्फ़िग रीस्टार्ट ट्रिगर होता है; यदि आपको संपादित इंटीग्रेशन प्रभावी होता न दिखे, तो `blume dev` को रीस्टार्ट करें। Blume यह नहीं बता सकता कि कौन-से कॉन्फ़िग संपादन इंटीग्रेशन को प्रभावित करते हैं, इसलिए एक बार `integrations` ग़ैर-खाली हो जाने पर, `blume.config.ts` का हर संपादन — यहाँ तक कि किसी असंबंधित फ़ील्ड का भी — हॉट-अप्लाई करने के बजाय डेव सर्वर को रीस्टार्ट करता है। Blume केवल `blume.config.ts` की सामग्री ट्रैक करता है, इसलिए उसके द्वारा इम्पोर्ट की गई किसी अलग फ़ाइल को संपादित करना अपने आप वह पुनर्जनन ट्रिगर नहीं करेगा — ऐसे संपादनों के बाद `blume dev` रीस्टार्ट करें। यदि आप इजेक्ट करते हैं, तो आपके स्वामित्व वाला `astro.config.mjs` `blume.config.ts` से एक रिलेटिव ब्रिज बनाए रखता है, इसलिए कॉन्फ़िगर किए गए इंटीग्रेशन चलते रहते हैं; बाद में आप पूर्ण स्वामित्व लेने के हिस्से के रूप में उन्हें सीधे Astro कॉन्फ़िग में ले जा सकते हैं।

## इजेक्ट [#eject]

जब आपको पूरा नियंत्रण चाहिए, तो जनरेट किए गए रनटाइम को एक स्वतंत्र Astro प्रोजेक्ट में इजेक्ट करें:

```bash
blume eject --yes
```

इजेक्ट एक तरफ़ा कदम है: छिपा हुआ `.blume/` रनटाइम एक सामान्य Astro ऐप बन जाता है जिसका स्वामित्व आपके पास होता है और जिसे आप सीधे संशोधित कर सकते हैं। `blume` पैकेज इम्पोर्ट योग्य बना रहता है, इसलिए आप इसके कंपोनेंट्स, थीम, और Markdown प्रोसेसर बनाए रखते हैं।

### इजेक्ट क्या बनाए रखता है [#what-eject-keeps]

इजेक्ट किए गए ऐप की `build` स्क्रिप्ट सादा `astro build` चलाती है, और `blume build` जो आर्टिफ़ैक्ट्स ऊपर से जोड़ता है — सर्च इंडेक्स (और किसी होस्टेड प्रोवाइडर का इंडेक्स सिंक), `llms.txt` और `llms-full.txt`, `sitemap.xml`, `robots.txt`, `agent-readability.json`, `.well-known` डिस्कवरी फ़ाइलें, Agent Skills, और प्लेटफ़ॉर्म `_redirects`/`_headers` फ़ाइलें — वे अब भी उत्पन्न होते हैं: इजेक्ट किए गए `astro.config.mjs` में मौजूद Blume इंटीग्रेशन उन्हें Astro के `astro:build:done` हुक से लिखता है, और प्रोजेक्ट (आपका `blume.config.ts` और कंटेंट) को उसी तरह स्कैन करता है जैसे CLI करता था। इजेक्ट किया गया बिल्ड जो नहीं करता, वह है CLI का एडेप्टर पोस्ट-प्रोसेसिंग: Vercel और Cloudflare के `Accept: text/markdown` रूटिंग स्प्लाइस, Vercel फ़ंक्शन-बंडल ऑडिट, और `--analyze`/`--budget-*` गेट।
