---
title: "Configuration — Forms for Laravel | Roundly"
description: "Every config key and its default — swappable models, sender key type, field resolvers, typed field types, media uploads and reviews."
url: https://roundly-consulting.com/open-source/docs/forms-for-laravel/configuration
language: en
---

[All packages](https://roundly-consulting.com/open-source.md)

[Forms for Laravel](https://roundly-consulting.com/open-source/docs/forms-for-laravel.md)

# Configuration

The published config/forms.php lets you swap the package models, register field resolvers, map field types to value types, and tune uploads and reviews. In full:

```php
return [
    // Override any model with your own subclass.
    'models' => [
        'form' => \RoundlyConsulting\Forms\Models\Form::class,
        'group' => \RoundlyConsulting\Forms\Models\Group::class,
        'field' => \RoundlyConsulting\Forms\Models\Field::class,
        'submission' => \RoundlyConsulting\Forms\Models\Submission::class,
        'form_submission' => \RoundlyConsulting\Forms\Models\FormSubmission::class,
    ],

    // Key type of the polymorphic sender columns: "bigint", "uuid" or "ulid" — anything else throws.
    'key_type' => env('FORMS_KEY_TYPE', 'bigint'),

    // Map a field `type` to the resolver that reads/writes its value.
    // `default` is used for any type without an explicit mapping. Each value must be
    // a class implementing Resolver; anything else throws.
    'fields' => [
        'default' => \RoundlyConsulting\Forms\Resolvers\DefaultResolver::class,
        'file' => \RoundlyConsulting\Forms\Resolvers\MediaFileResolver::class,
        'image' => \RoundlyConsulting\Forms\Resolvers\MediaFileResolver::class,
    ],

    // Map a field `type` to the attributes AttributeType used to cast stored
    // values and type-check submissions. Unlisted types (e.g. `time`) read back
    // exactly as stored. A value that isn't an AttributeType case throws.
    'field_types' => [
        'number' => 'integer',   // whole numbers; `decimal` / `float` map to 'float'
        'range' => 'integer',
        'float' => 'float',
        'decimal' => 'float',
        'checkbox' => 'boolean',
        'boolean' => 'boolean',
        'toggle' => 'boolean',
        'date' => 'datetime',
        'datetime' => 'datetime',
        'multiselect' => 'array',
        'checkboxes' => 'array',
        'tags' => 'array',
    ],

    // Media settings for file/image fields (backed by media-library-for-laravel).
    'media' => [
        'bucket' => 'attachment',
        'visibility' => 'private',
        'disk' => env('FORMS_MEDIA_DISK'),
        'private_disk' => env('FORMS_MEDIA_PRIVATE_DISK', 'local'),
        'accepted_mime_types' => null,
        'max_file_size' => null,
        'responsive_widths' => null,
        'temporary_url_lifetime' => null,
    ],

    // Submission review via approvals-for-laravel. Disabled by default.
    'approvals' => [
        'enabled' => env('FORMS_APPROVALS_ENABLED', false),
    ],

    // Forms defined declaratively and synced to the DB with `php artisan forms:sync`.
    'definitions' => [],
];
```

## Every key

| Key | Default | Purpose |
| --- | --- | --- |
| `models.form` | Models\\Form | Model used for forms (the package model or a subclass; any other class throws). |
| `models.group` | Models\\Group | Model used for groups. |
| `models.field` | Models\\Field | Model used for fields. |
| `models.submission` | Models\\Submission | Model used for per-field submission rows. |
| `models.form_submission` | Models\\FormSubmission | Aggregate grouping a submission’s rows (the approvals subject). |
| `key_type` | bigint | Key type of the polymorphic sender columns: bigint, uuid or ulid (FORMS\_KEY\_TYPE); blank = not set → bigint; any other value throws. |
| `fields.default` | DefaultResolver | Resolver for any field type without its own mapping. Every fields.\* entry must be a Resolver class; a blank entry is unmapped; anything else throws. |
| `fields.file / fields.image` | MediaFileResolver | Stores the upload as media on the submission row. |
| `field_types` | 12 mappings | Field type → AttributeType for typed reads and validation. time is left unmapped on purpose and reads back as stored. An unmapped type — or one mapped to a blank value — reads as a string; a mapped value that isn’t an AttributeType (integr) throws. |
| `media.bucket` | attachment | Media bucket the submission row registers uploads into (a string; blank = not set → attachment). |
| `media.visibility` | private | private (signed streaming) or public; anything else throws. |
| `media.disk` | null | Disk for every upload (FORMS\_MEDIA\_DISK); null or blank = by visibility — private → media.private\_disk, public → the media library default. |
| `media.private_disk` | local | Non-public disk for private uploads and their variants when media.disk is null (FORMS\_MEDIA\_PRIVATE\_DISK). |
| `media.accepted_mime_types` | null | Restrict accepted mime types to a list of non-empty strings (null or \[\] = open). |
| `media.max_file_size` | null | Max upload size in bytes, at least 1 (null = media default). |
| `media.responsive_widths` | null | Responsive image widths, positive integers (null = media default ladder). |
| `media.temporary_url_lifetime` | null | Signed URL lifetime in minutes, at least 1 (null = media default). |
| `approvals.enabled` | false | Route submissions through the approvals engine (FORMS\_APPROVALS\_ENABLED). Read strictly: true/1/on/yes or false/0/off/no; anything else throws. |
| `definitions` | \[\] | Declarative form definitions synced by forms:sync (each entry an array). |

## Environment

Three settings are env-driven, so the most common changes need no published config:

```bash
FORMS_KEY_TYPE=bigint
FORMS_MEDIA_PRIVATE_DISK=s3-private   # a non-public disk for private uploads
# FORMS_MEDIA_DISK=                   # leave unset to choose the disk by visibility
FORMS_APPROVALS_ENABLED=true
```

Set key\_type before you migrate: it decides the column type of the polymorphic sender columns on submissions and form\_submissions, and every model you use as a sender must share that key type. A blank value (FORMS\_KEY\_TYPE=) is not set and keeps bigint; any value other than bigint, uuid or ulid throws an InvalidConfigurationException.

## Strict settings

A key that is not set — absent, null, or blank like a host’s FORMS\_MEDIA\_DISK= — takes its default; an optional one (media.disk, media.max\_file\_size, media.responsive\_widths, media.temporary\_url\_lifetime) stays unset, and a blank fields.\* or field\_types.\* entry is unmapped. Every value that is set must fit, or it throws RoundlyConsulting\\PackageToolkit\\Exceptions\\InvalidConfigurationException naming the key:

- Integers accept an int or a plain integer string — every env value is a string — so 10MB or 5.5 throws rather than being ignored.
- A non-string bucket or disk name throws, and so does a media.visibility typo — it no longer reads as private.
- A junk list entry throws — accepted\_mime\_types, responsive\_widths or a definitions entry that isn’t an array.
- Every fields.\* entry must be a Resolver class, and every field\_types value an AttributeType case.
- FORMS\_APPROVALS\_ENABLED accepts true/1/on/yes or false/0/off/no; anything else throws.

php artisan about renders a broken setting as INVALID instead of failing.

## Show your open-source love

This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.

[More ways to support, including crypto](https://roundly-consulting.com/support-us.md)

By donating, you agree to our [donation terms](https://roundly-consulting.com/donation-terms.md).

[Support our open source work (opens in a new tab)](https://donate.stripe.com/dRmeVe8FX5PF1Qd9pXcEw00) [Join us on Patreon (opens in a new tab)](https://www.patreon.com/cw/roundly)

## Want this built into your product?

We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.

[Get a quote in 48 hours](https://roundly-consulting.com/contact.md) [Browse all packages](https://roundly-consulting.com/open-source/docs/forms-for-laravel.md)
