Create a validation schema
import { z } from "astro/zod"; export const zNewsletterValues = z.object({ email: z.string().email().min(1),}); export type NewsletterValues = z.infer<typeof zNewsletterValues>;
Create your action
import { zNewsletterValues } from "@/lib/utils";import { defineAsfAction } from "superforms:astro";import { message } from "sveltekit-superforms"; export const server = { //... subscribeToNewsletter: defineAsfAction({ input: zNewsletterValues, handler: async ({ email }, { form }) => { return message(form, "SUCCESS"); }, }), //...};
Initialize the form in your astro layout, page or component
---import { zNewsletterValues } from "src/schemas";import { superValidate } from "sveltekit-superforms";import { zod } from "sveltekit-superforms/adapters";import Form from "./_form.svelte"; const sv = await superValidate(Astro.request, zod(zNewsletterValues));--- <Form client:visible {sv} />
Display the form in your svelte component
<script lang="ts"> import { zNewsletterValues, type NewsletterValues } from "src/schemas"; import { actions } from "astro:actions"; import { superForm, type SuperValidated } from "sveltekit-superforms"; import { zodClient } from "sveltekit-superforms/adapters"; let { sv }: { sv: SuperValidated<NewsletterValues> } = $props(); const sf = superForm(sv, { validators: zodClient(zNewsletterValues), onUpdated: ({ form: { message } }) => { if (message) console.log(message); }, }); const { enhance, form } = sf;</script> <form method="POST" action={actions.subscribeToNewsletter} use:enhance> <input type="email" bind:value={$form.email} /> <button type="submit">Subscribe</button></form>