---
title: आइलैंड्स
description: >-
  किसी इंटरैक्टिव कंपोनेंट को islands/ में रखें और उसे किसी भी MDX पेज में इस्तेमाल करें — स्वचालित रूप से हाइड्रेट, हर पेज पर इंपोर्ट किए बिना।
---

Blume आपके डॉक्स को डिफ़ॉल्ट रूप से **शून्य JavaScript** के साथ स्टैटिक HTML के रूप में रेंडर करता है। जब आपको कुछ इंटरैक्टिव चाहिए — एक लाइव डेमो, एक चार्ट, एक प्लेग्राउंड — तो आप एक **आइलैंड** जोड़ते हैं: एक फ्रेमवर्क कंपोनेंट जो JS केवल अपने लिए भेजता है, और केवल उन पेजों पर जो उसका उपयोग करते हैं।

## `islands/` परिपाटी [#the-islands-convention]

अपने प्रोजेक्ट के रूट में एक `islands/` फ़ोल्डर में कोई कंपोनेंट रखें। इसका फ़ाइल नाम एक ऐसा कंपोनेंट बन जाता है जिसे आप **किसी भी** `.mdx` पेज में, बिना इंपोर्ट किए, इस्तेमाल कर सकते हैं:

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

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

```mdx page.mdx
Here's a live counter: <Counter />
```

फ़ाइल नाम ही कंपोनेंट का नाम है, इसलिए यह **एक PascalCase आइडेंटिफ़ायर होना चाहिए** — केवल अक्षर, अंक और अंडरस्कोर (`Counter.tsx` → `<Counter />`)। लोअरकेस फ़ाइल नाम, डैश/डॉट/स्पेस वाले नाम (जैसे `Time-Picker.tsx`), और ऐसे दो आइलैंड्स जो एक ही नाम पर पहुँचते हैं, बिल्ड चेतावनी के साथ छोड़ दिए जाते हैं।

:::note
आइलैंड्स **इंटरैक्टिव** UI के लिए हैं। ऐसे स्टैटिक कंपोनेंट के लिए जिसे आप कई पेजों में दोबारा इस्तेमाल करते हैं (एक स्टाइल किया हुआ कॉलआउट, एक प्राइसिंग टेबल), इसके बजाय [MDX ओवरराइड](/docs/configuration/customization) का उपयोग करें — यह कोई JavaScript नहीं भेजता।
:::

## `components.ts` में आइलैंड्स रजिस्टर करना [#registering-islands-in-componentsts]

यदि आप आइलैंड्स को अपने बाकी कंपोनेंट्स के साथ रखना चाहें — या उन्हें फ़ाइल से अलग नाम देना चाहें — तो उन्हें `defineComponents` के साथ रजिस्टर करें। `islands` समूह बिल्कुल `islands/` फ़ोल्डर जैसा ही है: प्रत्येक एंट्री हर MDX पेज में उपलब्ध होती है और हाइड्रेट होती है (डिफ़ॉल्ट `client: "visible"` के साथ)।

```ts components.ts
import { defineComponents } from "blume";
import Counter from "./widgets/Counter.tsx";

export default defineComponents({
  islands: {
    Counter, // <Counter /> in any MDX page, hydrated
  },
});
```

कंपोनेंट को इंपोर्ट के ज़रिए या पाथ स्ट्रिंग के ज़रिए रेफ़र करें, और डिस्क्रिप्टर फ़ॉर्म के साथ प्रति आइलैंड एक हाइड्रेशन मोड सेट करें:

```ts components.ts
export default defineComponents({
  islands: {
    Chart: { component: "./widgets/Chart.tsx", client: "only" },
  },
});
```

## हाइड्रेशन [#hydration]

डिफ़ॉल्ट रूप से एक आइलैंड `client:visible` का उपयोग करता है: यह तब हाइड्रेट होता है जब पाठक इसे स्क्रॉल करके दृश्य में लाता है, इसलिए आइलैंड्स से भरा पेज भी तुरंत लोड होता है। आइलैंड फ़ाइल में `export const client` के साथ किसी दूसरी रणनीति को चुनें:

```tsx islands/Chart.tsx lineNumbers
// Skip server rendering entirely — for components that touch the DOM/window.
export const client = "only";

export default function Chart() {
  /* ... */
}
```

| `client` मान | हाइड्रेट होता है | इसके लिए उपयोग करें |
| --- | --- | --- |
| `"visible"` _(डिफ़ॉल्ट)_ | जब स्क्रॉल करके दृश्य में आए | अधिकांश आइलैंड्स |
| `"load"` | पेज लोड होते ही तुरंत | ऊपरी हिस्से का, तुरंत चाहिए वाला UI |
| `"idle"` | जब मुख्य थ्रेड निष्क्रिय हो | गैर-अत्यावश्यक इंटरैक्टिविटी |
| `"only"` | केवल क्लाइंट, कभी सर्वर-रेंडर नहीं | ऐसी लाइब्रेरीज़ जिन्हें `window`/`document` चाहिए (चार्ट, एडिटर) |

## फ्रेमवर्क [#frameworks]

**React बिना किसी सेटअप के काम करता है** — जैसे ही आपके प्रोजेक्ट में कोई `.tsx`/`.jsx` आइलैंड होता है, Blume इसे अपने आप चालू कर देता है।

जब भी React सक्षम होता है, [React Compiler](https://react.dev/learn/react-compiler) डिफ़ॉल्ट रूप से चालू रहता है, इसलिए आपके आइलैंड्स स्वतः-मेमोआइज़्ड होते हैं — हाथ से लिखे `useMemo`/`useCallback` की ज़रूरत नहीं। यह Blume के साथ ही आता है; इंस्टॉल करने को कुछ नहीं है। `blume.config.ts` में इससे बाहर निकलें:

```ts blume.config.ts
export default defineConfig({
  react: { compiler: false },
});
```

**Vue और Svelte** भी समर्थित हैं; संबंधित Astro इंटीग्रेशन इंस्टॉल करें और जब Blume को कोई `.vue` या `.svelte` आइलैंड दिखता है, तो वह रेंडरर को जोड़ देता है:

```bash
# Vue
npm install @astrojs/vue vue

# Svelte
npm install @astrojs/svelte svelte
```

```vue islands/Toggle.vue lineNumbers
<script setup>
import { ref } from "vue";
const on = ref(false);
</script>

<template>
  <button @click="on = !on">{{ on ? "On" : "Off" }}</button>
</template>
```

MDX में आपके द्वारा पास किए गए प्रॉप्स (`<Counter start={5} />`) कंपोनेंट को फ़ॉरवर्ड कर दिए जाते हैं, और चिल्ड्रन (`<Counter>label</Counter>`) डिफ़ॉल्ट स्लॉट के रूप में पहुँचते हैं।

:::tip
आइलैंड्स क्लाइंट पर हाइड्रेट होते हैं, इसलिए जो कुछ भी आप प्रॉप के रूप में पास करते हैं वह सीरियलाइज़ेबल होना चाहिए — स्ट्रिंग्स, संख्याएँ, सादे ऑब्जेक्ट्स; फ़ंक्शन नहीं।
:::

## हुक्स [#hooks]

आइलैंड्स अपने आप हाइड्रेट होते हैं, इसलिए प्रोजेक्ट डेटा को पिरोने के लिए कोई React कॉन्टेक्स्ट नहीं होता। इसके बजाय, `blume/hooks` एक छोटा स्नैपशॉट पढ़ता है जिसे लेआउट पेज में सीरियलाइज़ करता है — कोई प्रॉप ड्रिलिंग नहीं:

```tsx islands/PageInfo.tsx lineNumbers
import { useBlume, usePage } from "blume/hooks";

export default function PageInfo() {
  const blume = useBlume();
  const page = usePage();
  if (!(blume && page)) {
    return null;
  }
  return (
    <p>
      You're reading <strong>{page.title}</strong> on {blume.config.title}.
    </p>
  );
}
```

| हुक | क्या लौटाता है |
| --- | --- |
| `useBlume()` | साइट के लिए `{ config, navigation }`, या माउंट से पहले `null` |
| `usePage()` | मौजूदा पेज के लिए `{ route, title }`, या माउंट से पहले `null` |
| `useSearch()` | `{ search, results, loading }` — कॉन्फ़िगर किए गए सर्च प्रोवाइडर से क्वेरी करें |
| `useAskAI()` | `{ ask, messages, loading, reset }` — Ask AI एंडपॉइंट से स्ट्रीम करें |

`useBlume()` और `usePage()` तब तक `null` लौटाते हैं जब तक आइलैंड माउंट नहीं हो जाता (ताकि सर्वर और क्लाइंट एक ही पहला फ़्रेम रेंडर करें) — इसके लिए गार्ड लगाएँ। स्नैपशॉट केवल उन पेजों पर उत्सर्जित होता है जो React भेजते हैं, इसलिए पूरी तरह स्टैटिक साइट को कोई कीमत नहीं चुकानी पड़ती।

`PageLayout` से बने [कस्टम पेजों](/docs/advanced/custom-pages) पर, `clientData` पास करें ताकि वहाँ के आइलैंड्स उसे पढ़ सकें:

```astro
<PageLayout
  clientData={{ config: data.config, navigation: data.navigation, page: { route: "/", title: "Home" } }}
  {/* …other props… */}
/>
```
