> ## Documentation Index
> Fetch the complete documentation index at: https://formsplugin.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Framer CMS

> Send Framer Forms submissions straight into a CMS collection in your own Framer project using the Forms Plugin.

# Send Form Submissions to Framer CMS

Turn form submissions into CMS entries in the same Framer project — useful for testimonials, job applications, directory listings, or anything you want to display back on your site.

***

## Step 1 - Create a Framer API Key

The Forms Plugin uses Framer's Server API to write entries into your collection.

1. Open your project in Framer
2. Go to **Site Settings** → **General**
3. Generate a new **API Key**
4. Copy the key

<Warning>
  A Framer API key can edit, publish, and deploy the project it belongs to — it is far more powerful than a typical integration key. Treat it like a password, use a key scoped to this project only, and generate a new one if you ever remove the component from your site.
</Warning>

***

## Step 2 - Copy Your Project URL

The integration needs to know which project to write to.

Copy the project URL from your browser's address bar while the project is open. It looks like:

```
https://framer.com/projects/Website--aabbccdd1122
```

***

## Step 3 - Insert Framer CMS Component Into Your Form

Select your form in the Framer canvas and insert the Framer CMS component.

The component connects your form to your CMS and automatically detects the form fields in your form layout.

***

## Step 4 - Configure CMS Settings

After inserting the component, configure it in the properties panel.

1. Select the **Framer CMS Integration** component in your form
2. Open the properties panel on the right side
3. Paste your **API Key**
4. Paste your **Project URL**
5. Enter the **Collection** name

### Required Fields

* **API Key** - The Framer API key created in Step 1.
* **Project URL** - The project the entries are written to.
* **Collection** - The collection entries are added to. Optional; defaults to `Form Submissions`.

### Optional Fields

* **Slug From** - The form fields joined to name each entry, in the order you list them. Click **+** to add a field. Leave empty to use the email address.
* **Join With** - What goes between each slug field: Dash, Underscore, Dot, Comma, Space, None, or Custom.
* **Separator** - Your own separator text. Only shown when Join With is set to Custom.
* **Always Unique** - Add a random suffix to every slug. Off by default so slugs stay readable.
* **Add As Draft** - When on, entries are added as drafts and excluded when you publish. When off, entries are ready to go live with your next publish.

### How slugs are built

Values from your chosen fields are joined with your separator, then made URL-safe.

| Slug From | Join With | Result |
| - | - | - |
| `name`, `email` | Dash | `vivian-barker-vivian-example-com` |
| `name`, `email` | Underscore | `vivian-barker_vivian-example-com` |
| `name` | — | `vivian-barker` |

Dashes and underscores survive into the slug. Commas, dots and spaces are not valid in a URL, so they become dashes — pick Dash or Underscore if you want the separator visible in the address.

Empty fields drop out of the join, so an optional field left blank never leaves a dangling separator.

Slugs are lower-cased, accents are stripped, repeated dashes collapse, and the result is trimmed to 80 characters. If nothing usable survives, the entry is named `entry`.

<Note>
  Framer requires every slug in a collection to be unique. With **Always Unique** off, the clean slug is used as-is and a short suffix is added **only** if that slug is already taken — so a second "Vivian Barker" is still saved, never dropped.
</Note>

### If the Collection Does Not Exist

You do not have to create the collection first. When you enter a collection name the plugin checks your project and tells you what it found:

| Status on the canvas | What it means |
| - | - |
| Integration active | The collection already exists and entries will be added to it |
| Collection will be created on first entry | No collection with that name yet — it is created automatically with the first submission |

Missing fields are added to the collection for you, matched by name and created with the **Type** you set on the mapping — except **Option**, which cannot be created automatically because it needs its list of options. A mapping set to Option that targets a field which does not exist yet is created as **Text** instead. A collection you built yourself keeps its own field types and ordering; only fields that are genuinely missing are appended.

***

## Step 5 - Configure Field Mapping

Map your form fields to CMS field names.

Each row is a form field, the CMS field it writes to, and that field's **Type**.

<Warning>
  One mapping must target a CMS field named **email**. Without it the submission is not sent at all, and no error appears on the form. The email is always written to a field called `email`, which is created on the collection if it does not exist.
</Warning>

### Example Mapping

| Form Field | CMS Field | Type |
| - | - | - |
| email | Email | Text |
| name | Name | Text |
| message | Message | Formatted Text |
| age | Age | Number |
| newsletter | Subscribed | Toggle |
| start | StartDate | Date |
| photo | Photo | Image |

### Supported Types

| Type | Accepts | Notes |
| - | - | - |
| **Text** | any text | the default |
| **Formatted Text** | text or HTML | rich text fields |
| **Number** | digits | non-numeric values are skipped |
| **Toggle** | `true/on/yes/1/checked` → on; `false/off/no/0/unchecked` or empty → off | any other answer counts as on |
| **Date** | any parseable date | stored as ISO |
| **Link** | a URL | |
| **Image** | an `http://` or `https://` URL | see below |
| **File** | an `http://` or `https://` URL | see below |
| **Color** | a colour value such as `#RRGGBB` | passed through as-is, not validated |
| **Option** | must match an existing option on the field | matched on the option name or its id, case-insensitively |

Not supported: **Collection Reference**, **Multi Collection Reference** and **Array** fields. These need to point at another CMS item, which a form field cannot express. Values aimed at them are skipped.

### Images and Files

Upload fields hand us a **hosted URL**, not the file itself, so that URL is what gets written to the CMS. The value must start with `http://` or `https://` — a relative path is skipped.

<Note>
  The **Type** you pick only matters when the field has to be created. If the field already exists in your collection, its own type always wins — so a mapping can never change or mis-describe a field you built yourself.
</Note>

<Tip>
  Keep your mapping to the fields you actually want to display — Framer limits how many custom fields a collection can hold.
</Tip>

### Other things worth knowing

* The collection's **title field** is filled automatically from your slug source when no mapping claims it, so entries never show as untitled in the CMS list.
* A mapping that targets the collection's **slug column** is ignored. The slug is set from **Slug From**, not from a mapping.
* If a missing field cannot be added, the entry is still saved with the fields that do exist, and the failure is recorded in the integration log.

### When a value does not fit

A value that cannot be stored in its field — letters in a Number, an option that does not exist — is **skipped, and the rest of the entry is still saved**. Losing one field is better than losing the whole submission. Skipped values are recorded in the integration log with the reason.

***

## Step 6 - Result

When a user submits the form, a new entry appears in your CMS collection straight away.

<Note>
  New entries appear in the CMS immediately, but your **live site** only shows them after you publish the project. This is the same behaviour as editing CMS content by hand.
</Note>

***

## Troubleshooting

| Message | What it means |
| - | - |
| Framer project URL is required (framer.com/projects/...) | The Project URL field is empty. |
| Framer rejected the connection: Invalid project URL or ID | The URL is not a Framer project URL. Copy it again from the address bar. |
| Framer rejected the API key or project URL | The key is wrong, was revoked, or belongs to a different project. |
| Could not reach this Framer project | Framer could not be reached. Check the key and project URL, then try again. |

## Next Steps

* [Integrations Overview](/docs/integrations/overview)
* [Contact Support](https://go.formsplugin.com/contact) if you need help
