# Script embed

The script embed is a small loader plus a JavaScript call, and it's what powers everything the plain [iframe embed](/embeds/iframe-embed) can't do: pop-ups, side tabs, the chatbot layout, the full-page layout, the slider, auto-resizing height, and prefilled/passed-in data.

## How it works

A script embed has up to two parts, depending on the layout:

1. A placeholder element the script hydrates into the live form, either a hidden `<iframe data-formsapp-src="...">` (standard and full-page layouts) or a `<button formsappId="...">` that acts as the trigger (pop-up and slider layouts). Chatbot and side-tab layouts create their own trigger and need no placeholder at all.
2. A `<script>` tag that loads `embed.js` from forms.app's CDN and, once loaded, calls `new formsapp(...)` to render the form.


## The `formsapp()` constructor

```js
new formsapp(formId, layout, options, domain);
```

| Parameter | Type | Description |
|  --- | --- | --- |
| `formId` | `string` | Your form's ID, for example `'69d4bd130b443bda40c8f65a'`. |
| `layout` | `string` | One of `'standard'`, `'fullscreen'`, `'popover'`, `'sidetab'`, `'popup'`, `'slider'`. |
| `options` | `object` | Layout-specific settings such as width, height, button styling, and animations. See [Embed options](/embeds/embed-options). |
| `domain` | `string` | Your account's data-region base URL, for example `'https://eu.forms.app'`. Must match the domain shown on your form's Share page. |


## Standard (inline) layout

The default layout: the form renders inline, in place of the placeholder iframe.

```html
<iframe data-formsapp-src="https://eu.forms.app/form/69d4bd130b443bda40c8f65a" title="Cake Order Form - Made with forms.app"></iframe>
<script src="https://cdn.formsapp.io/embed.js" type="text/javascript" async defer onload="new formsapp('69d4bd130b443bda40c8f65a', 'standard', {'width':'100vw','height':'600px'}, 'https://eu.forms.app');"></script>
```

Update the `title` attribute to describe your own form; it's used as a fallback accessible name.

### Auto-resizing height

Pass `'height':'formHeight'` instead of a fixed pixel value so the embed resizes itself as the form's content changes, for example across multi-step forms or conditional logic:

```html
<script src="https://cdn.formsapp.io/embed.js" type="text/javascript" async defer onload="new formsapp('69d4bd130b443bda40c8f65a', 'standard', {'width':'100vw','height':'formHeight'}, 'https://eu.forms.app');"></script>
```

## Other layouts

| Layout value | Also known as | Best for |
|  --- | --- | --- |
| `'fullscreen'` | [Full page](/embeds/embed-options/fullscreen) | A dedicated page or route for the form. |
| `'popover'` | [Chatbot](/embeds/embed-options/chatbot) | A chat-bubble widget in the corner of the screen. |
| `'sidetab'` | [Side tab](/embeds/embed-options/sidetab) | A small tab on the screen edge that expands into the form. |
| `'popup'` | [Pop-up](/embeds/embed-options/popup) | A modal, opened by click, page load, or after a delay. |
| `'slider'` | [Slider](/embeds/embed-options/slider) | A panel that slides in from the screen edge. |


## Loading the script once per page

If you're embedding more than one widget on the same page (for example a pop-up and a side tab), include the `<script src="https://cdn.formsapp.io/embed.js">` tag only once. Call `new formsapp(...)` once per widget after it loads.

Using a JavaScript framework?
The `onload` inline attribute shown above works in plain HTML, but isn't idiomatic in React, Next.js, or Vue. See [Examples](/embeds/examples) for the framework-appropriate way to load the script and call `formsapp()`.

## What's next

- [Embed options](/embeds/embed-options) for the full settings reference of every layout.
- [Passing data to your form](/embeds/passing-form-data).
- [Examples](/embeds/examples) for React, Next.js, Vue, and Kotlin.