Перейти к содержимому

Фронтенд-фреймворки

Создавайте сайты на Astro, не отказываясь от любимых компонентных фреймворков. Создавайте островки Astro с использованием UI-инструментов по вашему выбору.

Astro поддерживает популярные фреймворки, включая React, Preact, Svelte, Vue, SolidJS и AlpineJS через официальные интеграции.

Другие интеграции, поддерживаемые сообществом (например, для Angular, Qwik или Elm), можно найти в нашем каталоге.

UI-фреймворки

Вы можете установить одну или несколько таких интеграций в свой проект.

Подробности об установке и настройке ищите в руководстве по интеграциям.

Используйте компоненты JavaScript-фреймворков на страницах, в макетах и компонентах Astro точно так же, как и обычные компоненты Astro! Все они могут храниться в /src/components или быть организованы любым удобным вам способом.

Чтобы использовать компонент, импортируйте его по относительному пути в скрипте вашего Astro-компонента. Затем используйте его в шаблоне вместе с другими компонентами, HTML-элементами и JSX-выражениями.

src/pages/static-components.astro
---
import MyReactComponent from '../components/MyReactComponent.jsx';
---
<html>
<body>
<h1>Используйте компоненты React прямо в Astro!</h1>
<MyReactComponent />
</body>
</html>

По умолчанию компоненты фреймворков рендерятся только на сервере в виде статического HTML. Это удобно для компонентов, не требующих интерактивности, так как позволяет не отправлять лишний JavaScript в браузер.

Чтобы сделать компонент интерактивным (гидрировать его), используйте директиву client:*. Это атрибуты, которые определяют, когда JavaScript-код компонента должен быть отправлен в браузер.

Для всех директив, кроме client:only, компонент сначала рендерится на сервере для создания статического HTML. Затем код JavaScript отправляется в браузер согласно выбранной директиве, и компонент «оживает» (происходит гидратация).

src/pages/interactive-components.astro
---
// Пример: гидратация компонентов в браузере.
import InteractiveButton from '../components/InteractiveButton.jsx';
import InteractiveCounter from '../components/InteractiveCounter.jsx';
import InteractiveModal from '../components/InteractiveModal.svelte';
---
<!-- JavaScript этого компонента начнет загружаться сразу при загрузке страницы -->
<InteractiveButton client:load />
<!-- Код компонента не будет отправлен клиенту до тех пор,
пока пользователь не прокрутит страницу до его появления -->
<InteractiveCounter client:visible />
<!-- Этот компонент не рендерится на сервере, а создается сразу на клиенте -->
<InteractiveModal client:only="svelte" />

Код самого фреймворка (React, Svelte и др.) будет отправлен вместе с кодом компонента. Если на странице несколько компонентов используют один фреймворк, он будет отправлен только один раз.

Для компонентов доступны следующие директивы: client:load, client:idle, client:visible, client:media={QUERY} и client:only={FRAMEWORK}.

Полное описание каждой директивы и примеры использования смотрите в справочнике директив.

Вы можете импортировать и использовать компоненты разных фреймворков в одном Astro-файле.

src/pages/mixing-frameworks.astro
---
// Пример: использование компонентов разных фреймворков на одной странице.
import MyReactComponent from '../components/MyReactComponent.jsx';
import MySvelteComponent from '../components/MySvelteComponent.svelte';
import MyVueComponent from '../components/MyVueComponent.vue';
---
<div>
<MySvelteComponent />
<MyReactComponent />
<MyVueComponent />
</div>

Astro распознаёт фреймворк по расширению файла. Если разные фреймворки используют одно расширение (например, React и Preact оба используют .jsx), может потребоваться дополнительная настройка.

Вы можете передавать данные (пропсы) из компонентов Astro в компоненты фреймворков:

src/pages/frameworks-props.astro
---
import TodoList from '../components/TodoList.jsx';
import Counter from '../components/Counter.svelte';
---
<div>
<TodoList initialTodos={["изучить Astro", "проверить PR"]} />
<Counter startingCount={1} />
</div>

Пропсы, передаваемые интерактивным компонентам (с директивой client:*), должны быть сериализуемыми — то есть их можно преобразовать в формат для передачи по сети. Astro поддерживает большинство стандартных типов: объекты, числа, строки, массивы, Map, Set, регулярные выражения, даты, BigInt, URL и Uint8Array.

Неподдерживаемые структуры, такие как функции, можно передавать только в статические компоненты (без client:*). Astro не может передать функцию с сервера так, чтобы она осталась работоспособной на клиенте.

Внутри Astro-компонента вы можете передавать дочерние элементы в компоненты фреймворков. У каждого фреймворка свои правила доступа к ним: React, Preact и Solid используют пропс children, в то время как Svelte и Vue используют элемент <slot />.

src/pages/component-children.astro
---
import MyReactSidebar from '../components/MyReactSidebar.jsx';
---
<MyReactSidebar>
<p>Это боковая панель с текстом и кнопкой.</p>
</MyReactSidebar>

Также можно использовать именованные слоты.

Для React, Preact и Solid такие слоты станут пропсами верхнего уровня. Имена в kebab-case будут преобразованы в camelCase.

src/pages/named-slots.astro
---
import MySidebar from '../components/MySidebar.jsx';
---
<MySidebar>
<h2 slot="title">Меню</h2>
<p>Основное содержимое панели.</p>
<ul slot="social-links">
<li><a href="https://github.com/withastro">GitHub</a></li>
</ul>
</MySidebar>
src/components/MySidebar.jsx
export default function MySidebar(props) {
return (
<aside>
<header>{props.title}</header>
<main>{props.children}</main>
<footer>{props.socialLinks}</footer>
</aside>
)
}

Для Svelte и Vue эти слоты доступны через элемент <slot> с атрибутом name. Имена в kebab-case сохраняются.

src/components/MySidebar.svelte
<aside>
<header><slot name="title" /></header>
<main><slot /></main>
<footer><slot name="social-links" /></footer>
</aside>

Внутри .astro файла дочерние элементы компонента фреймворка также могут быть интерактивными. Это позволяет рекурсивно вкладывать компоненты друг в друга.

src/pages/nested-components.astro
---
import MyReactSidebar from '../components/MyReactSidebar.jsx';
import MyReactButton from '../components/MyReactButton.jsx';
import MySvelteButton from '../components/MySvelteButton.svelte';
---
<MyReactSidebar>
<p>Текст в боковой панели.</p>
<div slot="actions">
<MyReactButton client:idle />
<MySvelteButton client:idle />
</div>
</MyReactSidebar>

Это позволяет строить целые приложения на вашем любимом фреймворке и рендерить их внутри страниц Astro.

Можно ли использовать компоненты Astro внутри компонентов фреймворков?

Заголовок раздела «Можно ли использовать компоненты Astro внутри компонентов фреймворков?»

Компонент UI-фреймворка становится «островком» этого фреймворка. Он должен состоять только из валидного кода этого фреймворка и его библиотек. Вы не можете импортировать .astro компоненты в файлы .jsx или .svelte.

Однако вы можете использовать паттерн слотов Astro для передачи статического контента, сгенерированного Astro-компонентами, в качестве дочерних элементов внутри .astro файла:

src/pages/astro-children.astro
---
import MyReactComponent from '../components/MyReactComponent.jsx';
import MyAstroComponent from '../components/MyAstroComponent.astro';
---
<MyReactComponent>
<MyAstroComponent slot="name" />
</MyReactComponent>

Попытка добавить директиву client: к Astro-компоненту приведет к ошибке.

Компоненты Astro — это шаблоны, которые не имеют клиентской части. Но вы можете добавить тег <script> в шаблон Astro-компонента, чтобы отправить JavaScript, который выполнится в глобальной области видимости браузера.