#Forms
Capture submissions from any form (contact, waitlist, feedback) without writing a backend. Submitting is browser-safe; reading requires the API key, so it runs on the server.
import { forms } from '@coduck/sdk/forms';import { forms } from '@coduck/sdk/forms';#Submit (browser-safe)
submit() is public — call it from a client component. It only needs NEXT_PUBLIC_CODUCK_PROJECT_ID (injected at deploy).
'use client';
import { forms } from '@coduck/sdk/forms';
async function onSubmit(e: React.FormEvent<HTMLFormElement>) {
e.preventDefault();
const data = new FormData(e.currentTarget);
await forms.submit('contact', {
name: data.get('name'),
email: data.get('email'),
message: data.get('message'),
});
}'use client';
import { forms } from '@coduck/sdk/forms';
async function onSubmit(e: React.FormEvent<HTMLFormElement>) {
e.preventDefault();
const data = new FormData(e.currentTarget);
await forms.submit('contact', {
name: data.get('name'),
email: data.get('email'),
message: data.get('message'),
});
}You can also import the bound helper directly:
import { submit } from '@coduck/sdk/forms';
await submit('waitlist', { email });import { submit } from '@coduck/sdk/forms';
await submit('waitlist', { email });The formName is just a label you choose — submissions are grouped by it.
#Read submissions (server only)
list() and markRead() require CODUCK_API_KEY, so call them from a route handler or server component.
import { forms } from '@coduck/sdk/forms';
const recent = await forms.list({ formName: 'contact', limit: 50 });
await forms.markRead(recent[0].id);import { forms } from '@coduck/sdk/forms';
const recent = await forms.list({ formName: 'contact', limit: 50 });
await forms.markRead(recent[0].id);| Method | Scope | Returns |
|---|---|---|
submit(formName, fields) | browser-safe | void |
list({ formName?, limit? }) | server | FormSubmission[] |
markRead(id) | server | FormSubmission |
Submissions also show up in your project's Forms tab in the cloud panel.
#Type
interface FormSubmission {
id: string;
projectId: string;
formName: string;
fields: Record<string, unknown>;
submitterIp: string | null;
userAgent: string | null;
read: boolean;
createdAt: string;
}interface FormSubmission {
id: string;
projectId: string;
formName: string;
fields: Record<string, unknown>;
submitterIp: string | null;
userAgent: string | null;
read: boolean;
createdAt: string;
}