@location-state/conform
Synchronize conform with history entries.
Features
- Manage conform state to synchronize with the history location.
- Supports Session Storage and URL as persistent destinations. View the more detail in the
@location-state/core
docs.
Packages
Installation
npm install @location-state/core @location-state/conform
yarn add @location-state/core @location-state/conform
pnpm add @location-state/core @location-state/conform
Configuration
"use client";
import { LocationStateProvider } from "@location-state/core";
export function Providers({ children }: { children: React.ReactNode }) {
return <LocationStateProvider>{children}</LocationStateProvider>;
}
import { Providers } from "./Providers";
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body>
<Providers>{children}</Providers>
</body>
</html>
);
}
Working with Conform state
"use client";
import { getInputProps, useForm } from "@conform-to/react";
import { parseWithZod } from "@conform-to/zod";
import { useLocationForm } from "@location-state/conform";
import { useFormState } from "react-dom";
import { User } from "./schema";
export default function UserForm() {
const [formOptions, getLocationFormProps] = useLocationForm({
location: {
name: "your-form",
storeName: "session",
},
});
const [form, fields] = useForm({
onValidate({ formData }) {
return parseWithZod(formData, { schema: User });
},
...formOptions,
});
return (
<form {...getLocationFormProps(form)} noValidate>
<label htmlFor={fields.firstName.id}>First name</label>
<input
{...getInputProps(fields.firstName, {
type: "text",
})}
key={fields.firstName.key}
/>
<div>{fields.firstName.errors}</div>
<button type="submit">submit</button>
</form>
);
}
Working with Conform and Server Actions
"use server";
import { parseWithZod } from "@conform-to/zod";
import { redirect } from "next/navigation";
import { User } from "./schema";
export async function saveUser(prevState: unknown, formData: FormData) {
const submission = parseWithZod(formData, {
schema: User,
});
if (submission.status !== "success") {
return submission.reply();
}
console.log("submit data", submission.value);
redirect("/success");
}
"use client";
import { getInputProps, useForm } from "@conform-to/react";
import { parseWithZod } from "@conform-to/zod";
import { useLocationForm } from "@location-state/conform";
import { useFormState } from "react-dom";
import { saveUser } from "./action";
import { User } from "./schema";
export default function UserForm() {
const [lastResult, action] = useFormState(saveUser, undefined);
const [formOptions, getLocationFormProps] = useLocationForm({
location: {
name: "your-form",
storeName: "session",
},
});
const [form, fields] = useForm({
lastResult,
onValidate({ formData }) {
return parseWithZod(formData, { schema: User });
},
...formOptions,
});
return (
<form {...getLocationFormProps(form)} action={action} noValidate>
<label htmlFor={fields.firstName.id}>First name</label>
<input
{...getInputProps(fields.firstName, {
type: "text",
})}
key={fields.firstName.key}
/>
<div>{fields.firstName.errors}</div>
<button type="submit">submit</button>
</form>
);
}
API
View the API reference here.