Web development
Astro
Astro renders content-driven sites to HTML at build time, adds interactivity only through islands, and organises Markdown entries with typed content collections.
Astro is the web framework for content-driven websites: blogs, marketing pages, documentation and product pages. It renders pages to HTML at build time and strips the JavaScript we did not ask for from the output sent to the browser. The model is server-first: everything stays HTML, CSS and JavaScript.
A project built with Astro is a multi-page site, not one large client-side bundle: the browser receives only the pieces we marked as interactive.
Islands: interactivity only where it is needed
An Astro component renders to HTML with no client-side runtime, and the code in its frontmatter is stripped from the output. A component becomes interactive only when it is turned into a client island with a client:* directive, such as client:load, client:idle or client:visible. The directive also sets the schedule, so a client:visible component is loaded only once it enters the viewport.
- Islands hydrate independently, so a heavy component does not block the others on the page.
- Several UI frameworks can be used on the same page when their integrations are installed.
- A server island is created with the
server:deferdirective, and it requires an adapter. - A framework component without a
client:*directive contributes only HTML and CSS; its framework runtime stays off the page.
Content and type safety
A content collection is a set of related entries with an identical structure. It needs a loader that reads the entries from files or a remote source, and it can declare a schema describing the expected shape of each entry, which reports missing or malformed fields before anything reaches the live site.
- Build-time collections read Markdown, MDX, YAML, TOML and JSON files, and the content lands in the output during the build.
- A live collection queries its source per request, which suits frequently changing data; in exchange it offers no MDX and no image optimization.
- This site is built the same way: blog and project entries are collections with per-language routes, and the schema validates every entry.
Build and output
By default every page is prerendered during the build, and the output is a set of static files. The finished directory can be served from any static host, and file names carry hashes so caching stays predictable. This site uses that model: a static output served by nginx on our Linux server.
- The sitemap integration walks the prerendered routes at build time; dynamic routes under on-demand rendering are not included.
- On-demand rendering needs an adapter for the chosen runtime, and
export const prerender = falsetakes a single route out of prerendering. - Rendering the whole site on the server is the
output: 'server'setting, where the static pages have to be marked instead. - The build can run in a container; here it is part of the Docker based setup.
What to watch
- Zero JavaScript is the default, not a guarantee: every
client:*directive brings its own bundle to the page, together with the runtime of the chosen framework. - Client-side interactivity must be opted in; anything that is not marked does not run in the browser.
- Framework integrations have to be installed and configured, and the build needs a Node.js toolchain.
- Server islands and on-demand rendering are tied to an adapter, so the hosting choice has to account for the runtime.
- Content reflects the state at build time, so an edit requires a rebuild unless a live collection is used.
Further reading
At CyberElectro our marketing pages and this site are built with Astro: content lives in collections, the output is static files, and JavaScript reaches the browser only where it is needed.