A Fillo form owns interactive state and makes browser requests, so in the App Router it lives in a Client Component.
Install the React package
pnpm add @usefillo/reactAdd the optional default stylesheet from a global CSS entry or root layout:
// app/layout.tsx
import "@usefillo/react/styles.css";Create a client component
// app/contact/ContactForm.tsx
"use client";
import { FilloForm } from "@usefillo/react";
export function ContactForm() {
return (
<FilloForm
formId="your-published-form-id"
onSubmitted={(responseId) => {
console.info("Fillo response", responseId);
}}
/>
);
}Render it from the route:
import { ContactForm } from "./ContactForm";
export default function ContactPage() {
return <ContactForm />;
}The form ID or slug must point at a published form. Public load and submit requests don't need a publishable key — add a pk_ client only when the app has to sync a code-defined schema or use a custom API origin.
Pass signed-in identity safely
Build the respondent HMAC in a Server Component or server-only helper, then pass the ID, email, name, and hash into the client component. Never expose the workspace identity secret through NEXT_PUBLIC_ environment variables.
Match your app's styling
Fillo's stylesheet uses cascade layers, so Tailwind utilities can override named slots and state attributes. On Tailwind v3 or a reset-heavy app, use styles.unlayered.css instead. Test server render, hydration, route navigation, the error state, and narrow layouts.
Try it
Start with a prompt and your coding agent builds the first form, staged for your review — or open the editor.
Related
- Contact example: Inspect the renderer and submission lifecycle used below.
- Embed quickstart: Choose published-ID or code-defined rendering.
- React form guide: Use the same component outside Next.js.
- Styling: Override slots with Tailwind or plain CSS.