Skip to content
Menu

Server-first forms for Astro

Your form.
Your server.
One place.

Form state, validation, and server actions in your .astro components. Build interactive forms with the server tools you already know.

npm install @astro-utils/forms
---
import { getCollection } from "astro:content";
import { Bind, BindForm, BInput, BButton } from "@astro-utils/forms/forms.js";
import Layout from "../layouts/Layout.astro";
const bind = Bind({ query: "" });
let products = await getCollection("products");
async function search() {
products = products.filter(product =>
product.name.toLowerCase().includes(bind.name.toLowerCase())
);
}
---
<Layout>
<BindForm {bind}>
<label for="query">Find a product</label>
<BInput id="query" name="query" />
<BButton onClick={search}>Search</BButton>
<p>{products.length} products found</p>
<ul>
{products.map(({ data }) => <li>{data.name} — ${data.price}</li>)}
</ul>
</BindForm>
</Layout>

Search an Astro content collection on the server. Render the results here. Setup and collection schema →

Start with something useful.

All examples ↗

Build on Astro.

Building with an AI agent?

Give your agent the documentation index, start with the implementation guide, or download the complete Markdown documentation. All examples include source files.

Coming from ASP.NET, PHP, or Next.js?

Astro Utils brings familiar server-side ideas into Astro: bound controls and postbacks for ASP.NET developers, HTML close to server logic for PHP developers, and form actions close to the UI for Next.js developers. The APIs and state model are specific to Astro Utils.