Public Form URLs
When you publish a form, it becomes accessible at a slug-based URL:Slug Generation
Each form is assigned a unique slug on creation:- Auto-generated by Prisma
- URL-safe characters only
- Guaranteed unique across all forms
- Persists for the lifetime of the form
Slugs are stored in the database with a unique constraint, preventing collisions even at scale.
Form Rendering
The public form page dynamically renders fields based on the stored schema.Page Load Flow
1
Extract slug from URL
Next.js dynamic routing captures the slug from the URL path.
2
Fetch form data
The component fetches form configuration from the API using the slug.
3
Render form fields
Fields are dynamically rendered based on their type using the
renderField function.Field Rendering
Each field type has specialized rendering logic:- Text & Email
- Select Dropdown
- Checkboxes
Form State Management
Form values are tracked in React state:Value Updates
Each field change updates the centralized state object:Form Submission
When the user clicks Submit, the form data is validated and sent to the API.1
User clicks Submit
The form’s
onSubmit handler is triggered.2
Browser validation
HTML5 validation runs automatically for required fields and input types (email, number, etc.).
3
Prevent default & submit
The handler prevents default form behavior and sends an API request.
4
Server-side validation
The API validates the submission (see next section).
5
Success message
On success, a thank you message is displayed.
Validation
Multiple layers of validation ensure data integrity.Client-Side Validation
HTML5 validation runs automatically:requiredattribute for mandatory fieldstype="email"for email formattype="number"for numeric values
Server-Side Validation
The API performs comprehensive validation before storing responses.1
Check form ID
2
Validate data object
3
Verify form exists
4
Validate required fields
5
Store response
Response Storage
Responses are stored in theFormsResponses table:
Key Features
JSON Storage
JSON Storage
The
data field stores the entire submission as JSON, allowing flexible schemas without migrations.Example stored data:Cascade Deletion
Cascade Deletion
When a form is deleted, all its responses are automatically removed via
onDelete: Cascade.Timestamp Tracking
Timestamp Tracking
createdAt automatically records when each response was submitted for analytics and exports.Error States
The public form page handles various error scenarios:- Loading
- Form Not Found
- API Error
- Submission Failed
UX Features
Loading States
The submit button shows loading state during submission:Required Field Indicators
Required fields are clearly marked with a red asterisk:API Endpoint
POST/api/forms/submit
Request Body:
app/api/forms/submit/route.ts