Astro
Most JavaScript frameworks render entire websites as large JavaScript applications. This approach, while simple, can leads to performance issues. Astro offers a solution with its Island Architecture.
Astro builds websites by breaking them into independent, encapsulated "islands" of functionality. Each island can be a single component, a group of components, or an entire page. Astro uses partial hydration, loading only the necessary JavaScript for each interactive island, resulting in faster page loads.
Getting Started with Astro
To create a new Astro project:
npm create astro@latest
This generates the following project structure:
├── README.md
├── astro.config.mjs
├── "package-lock.json"
├── package.json
├── public
│ └── favicon.svg
├── src
│ ├── components
│ │ └── Card.astro
│ ├── env.d.ts
│ ├── layouts
│ │ └── Layout.astro
│ └── pages
│ └── index.astro
└── tsconfig.json
Templates
Astro templates use the .astro file extension. Install the Astro
extension for Visual Studio Code for enhanced language support.
Astro templates consist of two parts:
- Variables: Defined between
---delimiters. - HTML Markup: The rest is HTML markup, this includes
<style>and<script>tags.
---
const items = ["Dog", "Cat", "Platypus"];
---
<ul>
{items.map((item) => (<li>{item}</li>))}
</ul>
Islands
Components are rendered as static HTML by default, no JavaScript is
sent to the client unless explicitly requested. To make a component
interactive, use the client directive:
<MyReactComponent client:load />
There are more options for the client directive:
client:idleload and hydrate component when browsers becomes idle, it has a lower priority asclient:load.client:visibleload and hydrate component when it enters the viewport
Routing
Astro uses file-based routing, similar to Next.js:
/ -> src/pages/index.astro
/about -> src/pages/about.astro
Dynamic Routing
/product/1 -> src/pages/product/[product].astro
/product/2 -> src/pages/product/[product].astro
To use dynamic routing, set the output option in astro.config.mjs to 'server' or 'hybrid':
export default defineConfig({
output: 'server',
})
In src/pages/product/[product].astro, parameters can be accessed via Astro.params:
---
const { product } = Astro.params
---
<div>{ product }</div>
Visiting http://localhost:4321/product/99 should give you "99".
APIs
Requests can also be mapped to a .ts or .js file, in this case the file acts as an API controller.
For Example:
/resource -> src/pages/resource.ts
export async function GET({params, request}) {
return new Response(JSON.stringify({ok: true}))
}
Accessing http://localhost:4321/resource should return {"ok":true}.
Markdown Support
Another interesting feature of Astro is it's built-in Markdown support, which makes it ideal for a lightweight CMS.
For example:
/about -> src/pages/about.md