ASTRO
#astro#islands#react#client-load#hydration

Astro: островок React с client:load

Подключение React-компонента как островка с директивой client:load — гидратация при загрузке страницы.

Как использовать

  1. Установите интеграцию @astrojs/react и импортируйте React-компонент в .astro странице.
  2. Добавьте директиву client:load к компоненту: <Counter client:load />.
  3. Компонент будет отрендерен в HTML при сборке и гидратирован в браузере после загрузки страницы.

В Astro страница по умолчанию отдаёт статический HTML; интерактивность (клики, состояние) нужна только в отдельных блоках — островках. React-компонент подключают как островок и указывают, когда запускать гидратацию в браузере. Директива client:load запускает гидратацию сразу после загрузки страницы. Проблема: без директивы компонент остаётся статической разметкой (без обработчиков); при неверном выборе директивы виджет ниже первого экрана тянет JS при загрузке без необходимости. Симптомы: кнопка не реагирует на клик, форма не интерактивна, лишний JS в head. Ниже — подключение React-островка с client:load, пример компонента и проверка по документации Astro.

Решение

Островок — интерактивный компонент (React, Vue, Svelte), который гидратируется в браузере. client:load запускает гидратацию после загрузки DOM. Используйте для виджетов, которые должны быть интерактивны сразу (счётчик, форма в шапке/футере, переключатель темы).

Страница Astro:

---
// src/pages/docs.astro
import Layout from '../layouts/BaseLayout.astro';
import Counter from '../components/Counter.tsx';
---
<Layout title="Документация">
  <h1>Документация</h1>
  <p>Весь текст — статический HTML. Кнопка ниже — островок React.</p>
  <Counter client:load />
</Layout>

Компонент React (пример):

// src/components/Counter.tsx
import { useState } from 'react';

export default function Counter() {
  const [count, setCount] = useState(0);
  return (
    <button onClick={() => setCount((c) => c + 1)}>
      Счётчик: {count}
    </button>
  );
}

Для React в проекте должна быть интеграция @astrojs/react в astro.config.mjs. Островок уходит в браузер отдельным бандлом; остальная страница — статический HTML.

Проверка

  1. Сборка и запуск — убедитесь, что страница с островком собирается и компонент отображается:
pnpm build
pnpm preview

Откройте страницу в браузере. Кнопка счётчика должна реагировать на клик (число увеличивается). Если кнопка есть, но не реагирует — проверьте, что указана директива client:load и интеграция React включена.

  1. Диагностика: компонент не гидратируется — откройте DevTools → вкладка Network: должен подгружаться JS-чанк с островком. В консоли не должно быть ошибок от React. Проверьте, что в astro.config.mjs есть react() в integrations.

  2. Статический вывод — в исходном HTML страницы разметка компонента уже есть (рендер при сборке); после загрузки скрипта она «оживает». Для отладки можно временно заменить client:load на client:only="react", чтобы убедиться, что проблема не в SSR (островок тогда рендерится только на клиенте).

Типичные ошибки

  • Забыли директиву — без client:load (или другой client-директивы) компонент остаётся статическим: разметка есть, обработчики не подключаются. Всегда указывайте одну из директив: client:load, client:visible, client:idle, client:only.
  • Не установлена интеграция React — выполните pnpm astro add react и проверьте, что в конфиге есть react() в integrations. Без неё Astro не обрабатывает .tsx/.jsx как островки.
  • Виджет далеко от первого экрана — для блоков ниже fold лучше использовать client:visible, чтобы не грузить их JS при загрузке. См. Островок с client:visible.

Где применять

  • Above the fold: счётчики, формы, переключатели, которые должны быть интерактивны сразу после открытия страницы.
  • Dev и prod: один и тот же синтаксис; в prod после build островки попадают в отдельные чанки и подгружаются по необходимости (при использовании других директив — по условию).

Связанные сниппеты: Островок с client:visible (гидратация при появлении), Astro Actions: форма с Zod, Статический вывод по умолчанию.