> For the complete documentation index, see [llms.txt](https://docs.dapta.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.dapta.ai/dforms/share/embed.md).

# Embed on your website

Put a dForms form inside your own website. Copy the snippet from the Embed dialog, paste it into WordPress, Webflow or plain HTML, and let the script size the frame, bring each new screen into view, r

Instead of sending people away to a Dapta link, you can run the form inside one of your own pages. The embed shows the same published form, collects the same submissions and triggers the same integrations.

***

**Step 1:** Open the form in the editor and click the **Embed** icon (the angle brackets) in the topbar, between **Edit link** and **QR code**.

**Step 2:** The dialog **Embed this form on your site** appears with a ready made snippet. Click **Copy snippet**. The button turns into **Copied**.

<figure><img src="https://3835013762-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FCy5rSNtQmtqYCGzJlNEB%2Fuploads%2Fgit-blob-496ecb4e5259f3068acdeb534acfc05460980038%2Fforms-embed-01-dialog.png?alt=media" alt="The Embed this form on your site dialog with its intro text, the iframe snippet pointing at a /f/ link and the Copy snippet button"><figcaption><p>The snippet is generated for this specific form. Copy it as it is, nothing to fill in.</p></figcaption></figure>

The snippet has two parts: an `iframe` that loads your form, and a small script, `embed.js`, that looks after the frame from your page.

```html
<iframe data-dapta-forms src="https://app.dforms.ai/acme/f/lead-qualification-quiz?embed=1"
        title="Lead qualification quiz" loading="lazy"
        style="width:100%;border:0;min-height:480px;"></iframe>
<script src="https://app.dforms.ai/embed.js" async></script>
```

| Part               | Why it is there                                                                                                                                                                     |
| ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `?embed=1`         | Tells the form it is running inside a page, so it renders at the height of its content instead of filling a whole screen, and reports that height to your page.                     |
| `data-dapta-forms` | The mark the script looks for. Keep it: without it the script ignores the frame, so there is no resizing, no scrolling into view and no page details.                               |
| `title`            | The form name, read out by screen readers. Change it if you want different wording.                                                                                                 |
| `width:100%`       | The form takes the width of whatever you put it in, so it stays responsive.                                                                                                         |
| `min-height:480px` | The height it starts at, and the smallest it ever gets.                                                                                                                             |
| `embed.js`         | Resizes the frame, brings each new screen into view, carries out the ending redirect and tells the form which page it is on. One copy of the script handles every form on the page. |

> **⚠️ Note:** Paste both lines, and load `embed.js` from the address the snippet gives you. A copy of the script saved on your own server still resizes the frame and carries out the redirect, but it never passes your page's details to the form.

***

**Step 3:** Paste the snippet into your page, wherever the form should appear.

* **WordPress:** edit the page, add a **Custom HTML** block and paste the snippet inside it. In the classic editor, switch from **Visual** to **Text** first.
* **Webflow:** drag an **Embed** element onto the canvas, paste the snippet into the code editor and publish the site.
* **Plain HTML, or any other builder:** paste it into the body of your page, inside the container that should hold the form.

If your builder splits code into "head" and "body" boxes, both lines can go in the body box, one after the other.

***

**Step 4:** Load the page and answer the first question to check it. The form should sit flush inside your layout with no scrollbar of its own. Then send a test response and open it in **Submissions**: the **Page** row should show your page.

<figure><img src="https://3835013762-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FCy5rSNtQmtqYCGzJlNEB%2Fuploads%2Fgit-blob-a7e32567812095e094e76d6a9c5d00c051750c9e%2Fforms-embed-02-live-page.png?alt=media" alt="A simple website page with the dForms form running inside it below the page heading"><figcaption><p>The same published form, running inside a normal web page.</p></figcaption></figure>

***

## The height takes care of itself

Questions are not all the same size: a four option question is taller than a single email field. Every time the content changes, the form reports its new height and `embed.js` resizes the frame, so the page grows and shrinks with it and the visitor never scrolls inside a box. After the last answer, the frame shrinks to fit the ending.

The frame is fluid, so a narrow column gets a narrow form:

<figure><img src="https://3835013762-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FCy5rSNtQmtqYCGzJlNEB%2Fuploads%2Fgit-blob-8177fa7a9994eb5ede9450d17fb42eccbab0ee9d%2Fforms-embed-03-mobile.png?alt=media" alt="The same page and embedded form on a phone sized screen" width="375"><figcaption><p>The embed on a phone. The form adapts to the space your layout gives it.</p></figcaption></figure>

> **💡 Tip:** You can embed several forms on one page. Add the `iframe` line for each of them and keep a single `embed.js` line: each frame is looked after on its own.

***

## The form scrolls into view

When the form replaces its whole screen, the new screen starts at the top of the frame. On a long page the visitor may still be scrolled down to where they pressed the button, so `embed.js` scrolls your page back to the top of the form.

* It happens every time a **Slides** form changes screen, and when either layout switches to the sending, reveal, booking or ending screen.
* It only scrolls when the top of the form is off screen. A visitor who can already see it is not moved.
* The scroll is smooth, or instant for visitors whose device asks for reduced motion.
* It never happens when the page loads.

***

## Where the redirect goes

When the [ending screen](/dforms/logic/ending-screen.md) redirects to another page, an embedded form opens that page in the whole browser tab, replacing your page, just like a normal link. This is what lets checkout pages that refuse to run inside a frame work from an embed.

* With `embed.js` on the page, your page carries out the redirect.
* Without it, the form redirects the whole tab on its own.
* One setup cannot redirect at all: an iframe with a `sandbox` attribute that does not include `allow-top-navigation`, on a page without `embed.js`. If your site builder sandboxes iframes, keep the script on the page.

***

## What your page tells the form

A form inside an iframe cannot see the page around it: that page's address, title and cookies belong to your site. `embed.js` runs on your page, so the form asks it, once when it loads and again every time it saves answers. The script answers with:

| Detail                  | What it is                                                                        |
| ----------------------- | --------------------------------------------------------------------------------- |
| Page address            | The full URL of your page, including its query string.                            |
| Page title              | The title of your page, as the browser tab shows it.                              |
| HubSpot page and portal | The HubSpot page ID and portal ID, when your page runs HubSpot.                   |
| HubSpot cookie          | The visitor's `hubspotutk` cookie, when your page runs the HubSpot tracking code. |

Nothing travels the other way: your page never receives what the visitor types.

What the form does with it:

* **The page is saved with the submission.** It shows as the **Page** row when you open a response in [Submissions](/dforms/results/submissions.md), as the **Page URL** column of the [CSV export](/dforms/results/export-csv.md) and as the `visit` object of the [webhook payload](/dforms/connect/webhooks/payload-reference.md).
* **The UTMs of your page count.** If the iframe `src` has no `utm_` parameters, the ones on your page's address are saved with the submission, all of them together. If the `src` carries any `utm_` parameter, those win and the ones on your page are ignored.
* **HubSpot can link the visit.** With the cookie, HubSpot links the submission to the visitor's earlier page views. What you need for that is in [Landing page & HubSpot attribution](/dforms/connect/hubspot/attribution.md).

A few rules keep it to your own form:

* The script only answers iframes marked `data-dapta-forms` whose `src` is on the same address the script was loaded from. The snippet already does this.
* Add `data-dapta-forms-context="off"` to the iframe to send nothing about your page for that form.
* A visitor who opted out of HubSpot tracking (an `__hs_opt_out` or `__hs_do_not_track` cookie) keeps the HubSpot cookie out. The page address and title still go.
* The script reads cookies. It never writes one.

With the `iframe` alone and no `embed.js`, nobody answers. The form waits a fraction of a second, then saves only what the browser reports as the referring page, usually just your site's domain, with no UTMs from your page and no cookie.

***

## Good to know

* The embed always shows the **published** version. Edits you have not published yet stay in your draft.
* Submissions from an embed are ordinary submissions: same **Submissions** table, same **Analytics**, same integrations and emails.
* If you turn a cover screen on, it shows inside the embed too. For a form that has to feel like part of the page, leave the cover off and start on the first question.
* Snippets you pasted earlier keep working, including ones with an older link. If you pasted only the `iframe` line, add the `embed.js` line.
* To force the language of the form inside the embed, add `&lang=es` or `&lang=en` to the iframe `src`. See [Language & button text](/dforms/design/language-and-button-text.md).
* With [spam protection](/dforms/connect/spam-protection.md) on, the check runs inside the frame. There is nothing to set up on your site.
* Tracking IDs set on the form (GTM, Meta Pixel) load and fire inside the frame, not on your page. See [Tracking & pixels](/dforms/connect/tracking-and-pixels.md#embedded-forms).

***

## What's next

* [Your public link](/dforms/share/public-link.md): the plain link, for emails, chats and buttons.
* [Landing page & HubSpot attribution](/dforms/connect/hubspot/attribution.md): link embedded submissions to the visitor's earlier page views in HubSpot.
* [Cover screen & banner](/dforms/design/cover-screen-and-banner.md): decide what the first screen shows.
* [Tracking & pixels](/dforms/connect/tracking-and-pixels.md): measure the embedded form alongside the rest of your site.
* [Analytics](/dforms/results/analytics.md): views, starts and drop-off, wherever the form is running.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.dapta.ai/dforms/share/embed.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
