Начало с Astro
Пълно ръководство за създаване на вашия първи уебсайт с Astro, обхващащо настройка на проекта, компоненти и внедряване.
Astro бързо се превърна в един от най-популярните генератори на статични сайтове и това не е случайно. Неговата островна архитектура рендерира статичното съдържание като HTML, като същевременно позволява на интерактивните елементи да включат клиентски JavaScript там, където е нужен.
Това ръководство преминава през частите на Astro, с които ще работите през първата си седмица: настройка на проекта, компоненти, острови, колекции със съдържание, маршрутизиране и внедряване. То предполага, че се чувствате уверено с HTML, малко TypeScript и командния ред.
Настройка на първия ви проект
Започването с Astro е лесно. Отворете терминала и изпълнете командата за създаване:
npm create astro@latest
Съветникът за настройка ще ви преведе през избора на шаблон, инсталирането на зависимостите и конфигурирането на TypeScript. За повечето проекти шаблонът „Blog“ е отлична отправна точка, с вече конфигурирани колекции със съдържание.
След като приключи, стартирайте сървъра за разработка:
cd my-site
npm run dev
Сайтът се сервира на http://localhost:4321 с презареждане на модулите в движение. Структурата на проекта е малка и си струва да я усвоите рано:
src/pages/съдържа маршрутите, базирани на файлове.src/pages/about.astroстава/about.src/components/съдържа компонентите за многократна употреба. Astro не третира тази папка по специален начин; това е конвенция.src/layouts/съдържа обвивките на страниците, отново по конвенция.public/съдържа файлове, които се копират в изхода без промяна, напримерfavicon.svgилиrobots.txt.astro.config.mjsсъдържа интеграциите, адаптерите и опциите за компилиране.
Разбиране на компонентите в Astro
Компонентите в Astro използват разширението .astro и съчетават синтаксис, подобен на HTML, със секция за скрипт във frontmatter. За разлика от компонентите в React или Vue, компонентите в Astro се рендерират до статичен HTML по време на компилиране, освен ако изрично не включите хидратация от страна на клиента.
Frontmatter на компонента се изпълнява на сървъра по време на компилиране и ви дава достъп до импортиране на файлове, извличане на данни и помощни функции, без тази логика да се изпраща към браузъра.
---
interface Props {
title: string;
href?: string;
}
const { title, href = "/" } = Astro.props;
---
<article class="card">
<h2><a href={href}>{title}</a></h2>
<slot />
</article>
<style>
.card {
padding: 1.5rem;
border-radius: 0.75rem;
}
</style>
В този пример си струва да забележите няколко неща:
- Props са типизирани с обикновен интерфейс
Props. Редакторите иastro checkго разпознават без допълнителна конфигурация. - Слотовете работят както в уеб компонентите. Слотът по подразбиране
<slot />получава вложените елементи, а именуваните слотове (<slot name="footer" />) получават елементите, маркирани съсslot="footer". - Стиловете са ограничени до компонента по подразбиране. Правилото
.cardпо-горе се прилага само за този компонент. Използвайте<style is:global>, когато наистина имате нужда от глобално правило.
Ако сте използвали JSX, основната разлика е, че няма повторно рендериране. Шаблонът се изпълнява веднъж на заявка или компилиране, генерира HTML и толкова.
Острови и клиентски директиви
Статичният HTML е по подразбиране, но рано или късно ще ви трябва нещо интерактивно: поле за търсене, графика, количка. Astro ви позволява да добавяте компоненти от React, Preact, Svelte, Vue или Solid, след като добавите съответната интеграция:
npx astro add react
Компонент от фреймуърк, рендериран без директива, все така генерира само HTML. За да изпратите неговия JavaScript и да го хидратирате, добавете директива client:*:
---
import Counter from "../components/Counter.tsx";
import Chart from "../components/Chart.tsx";
---
<Counter client:load />
<Chart client:visible />
Избирайте директивата според това колко спешно е взаимодействието:
client:loadхидратира веднага. Използвайте я за контроли в горната част на страницата, които потребителят ще използва веднага.client:idleизчаква, докато браузърът се освободи. Подходяща е за уиджети с по-нисък приоритет.client:visibleизчаква, докато компонентът влезе в изгледа при превъртане. Идеална е за графики и вградено съдържание по-надолу в страницата.client:media="(max-width: 768px)"хидратира само когато медийната заявка съвпадне, например за меню само за мобилни устройства.client:only="react"пропуска изцяло рендерирането на сървъра — за компоненти, които зависят от API на браузъра.
Всеки остров се хидратира независимо, така че бавен уиджет в долната част на страницата не блокира останалата част. За много взаимодействия изобщо не ви трябва фреймуърк: таг <script> в компонент .astro се пакетира и дедублира от Astro, което често е достатъчно за превключватели, менюта и бутони за копиране.
Колекции със съдържание
Една от най-силните страни на Astro са колекциите със съдържание. Те осигуряват типово безопасен достъп до съдържанието ви в Markdown и MDX с валидиране по схема. Дефинирайте структурата на съдържанието си веднъж и Astro ще гарантира, че всеки материал съответства на схемата.
Колекциите се дефинират в src/content.config.ts. От Astro 5 насам всяка колекция използва loader, който казва на Astro откъде идват записите. Вграденият loader glob() чете файлове от диска:
import { defineCollection } from "astro:content";
import { glob } from "astro/loaders";
import { z } from "astro/zod";
const blog = defineCollection({
loader: glob({ pattern: "**/*.{md,mdx}", base: "./src/content/blog" }),
schema: z.object({
title: z.string(),
description: z.string(),
publishDate: z.coerce.date(),
tags: z.array(z.string()).default([]),
draft: z.boolean().default(false),
}),
});
export const collections = { blog };
Ако на някоя публикация липсва заглавие или датата ѝ е невалидна, компилирането се проваля със съобщение, което сочи файла. Точно това искате в екип: грешките в съдържанието излизат наяве по време на разработка, а не в продукция.
Заявката към колекция е едно извикване на функция, а резултатите са напълно типизирани:
---
import { getCollection } from "astro:content";
const posts = (await getCollection("blog", ({ data }) => !data.draft))
.sort((a, b) => b.data.publishDate.valueOf() - a.data.publishDate.valueOf());
---
<ul>
{posts.map((post) => (
<li><a href={`/blog/${post.id}/`}>{post.data.title}</a></li>
))}
</ul>
Loader-ите не се ограничават до локални файлове. Loader-ът file() чете един JSON или YAML файл, а можете да напишете и собствен loader, който извлича данни от headless CMS или API, като запазите същото валидиране по схема и същия интерфейс за заявки.
Маршрутизиране и динамични страници
Всеки файл в src/pages/ е маршрут. За страници, генерирани от данни, например по една страница за всяка публикация в блога, използвайте име на файл в квадратни скоби и експортирайте getStaticPaths():
---
// src/pages/blog/[id].astro
import { getCollection, render } from "astro:content";
export async function getStaticPaths() {
const posts = await getCollection("blog");
return posts.map((post) => ({ params: { id: post.id }, props: { post } }));
}
const { post } = Astro.props;
const { Content, headings } = await render(post);
---
<h1>{post.data.title}</h1>
<Content />
render() връща и заглавията в публикацията, което е удобно за изграждане на съдържание, без сами да парсвате каквото и да било.
Внедряване
Astro поддържа множество платформи за внедряване веднага. За Vercel, Netlify, Cloudflare Pages и Node сървъри има официален адаптер, който npx astro add инсталира и конфигурира. За статичните сайтове вграденият изход не изисква допълнителна конфигурация.
Изпълнението на npm run build записва статичен сайт в dist/, който може да се сервира от всеки статичен хостинг или CDN. Когато имате нужда от код, който се изпълнява при всяка заявка, например обработка на форми, автентикация или персонализирани страници, добавете адаптер за своя хостинг:
npx astro add node
С инсталиран адаптер можете да запазите повечето страници предварително рендерирани и да изключите отделни маршрути с export const prerender = false. Преди да внедрите, задайте site в astro.config.mjs, така че каноничните URL адреси, картите на сайта и RSS емисиите да сочат към истинския ви домейн.
Накъде оттук
След като основите ви станат естествени, няколко функционалности си струва да разгледате, приблизително в този ред:
- Изображения. Компонентът
<Image />отastro:assetsсе грижи за преоразмеряването, модерните формати и атрибутите за ширина и височина, които предотвратяват разместването на оформлението. - Преходи между изгледи. Добавянето на компонента
<ClientRouter />към оформлението ви дава анимирана навигация от страна на клиента с много малко код. - Actions. Astro Actions ви дават типово безопасни сървърни функции с валидиране на входните данни — чудесно решение за форми за контакт и бюлетини.
- Сървърни острови. Директивата
server:deferпозволява на предимно статична страница да рендерира при поискване един персонализиран фрагмент, например потребителско меню.
Започнете с малко: едно оформление, една колекция, няколко страници. Astro възнаграждава този подход, защото всяка добавена страница остава толкова бърза, колкото и първата.