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

# Embed a form

> Add a FormFlows.ai form to any website or app using an iframe, JavaScript snippet, or React component.

You can embed any published form directly into your website or application without sending visitors to a separate page. FormFlows.ai supports three embedding methods — choose the one that fits your tech stack.

<Tabs>
  <Tab title="iframe">
    An iframe is the simplest option and works on any website, CMS, or landing page builder (WordPress, Webflow, Framer, Squarespace, etc.).

    <Steps>
      <Step title="Copy your form ID">
        Open your form in the dashboard. The form ID appears in the URL: `app.formflows.ai/forms/FORM_ID`. You can also click **Share → Embed** to go directly to the embed panel.
      </Step>

      <Step title="Paste the iframe snippet">
        Add the following snippet wherever you want the form to appear in your HTML:

        ```html theme={null}
        <iframe
          src="https://forms.formflows.ai/f/FORM_ID"
          width="100%"
          height="600"
          frameborder="0"
          allow="camera; microphone"
          title="Contact form"
        ></iframe>
        ```

        Replace `FORM_ID` with your actual form ID. Set `height` to match your form length, or use `style="min-height: 600px;"` and let the snippet auto-resize (see tip below).
      </Step>

      <Step title="Enable auto-resize (optional)">
        To have the iframe expand to fit the form's full height automatically, add the resize script immediately after the iframe:

        ```html theme={null}
        <script src="https://cdn.formflows.ai/embed/resize.js" defer></script>
        ```

        This script listens for height change events from the embedded form and adjusts the iframe accordingly.
      </Step>
    </Steps>

    <Tip>
      For better performance, add `loading="lazy"` to the iframe tag. This defers loading until the iframe scrolls into view, which reduces initial page load time.
    </Tip>
  </Tab>

  <Tab title="JavaScript snippet">
    The JavaScript embed gives you more control over how and when the form appears. It supports three display modes: **inline** (replaces a container element), **popup** (modal overlay), and **slider** (panel slides in from the side).

    <Steps>
      <Step title="Add the loader script">
        Paste this script tag once in the `<head>` of your page, or just before `</body>`:

        ```html theme={null}
        <script src="https://cdn.formflows.ai/embed/v2.js" defer></script>
        ```
      </Step>

      <Step title="Initialize the embed">
        Call `FormFlows.embed()` after the script loads. Choose the mode that fits your UX.

        <Tabs>
          <Tab title="Inline">
            Renders the form inside an existing element on your page. Add a container `<div>` where you want the form, then call `embed()` with that element's ID:

            ```html theme={null}
            <div id="my-form-container"></div>

            <script>
              window.addEventListener('FormFlowsReady', function () {
                FormFlows.embed('FORM_ID', {
                  mode: 'inline',
                  target: '#my-form-container',
                });
              });
            </script>
            ```
          </Tab>

          <Tab title="Popup">
            Opens the form in a centered modal overlay. You control when it triggers — attach it to a button, a timer, or exit intent:

            ```html theme={null}
            <!-- Trigger: button click -->
            <button id="open-form">Get in touch</button>

            <script>
              window.addEventListener('FormFlowsReady', function () {
                // Button click
                document.getElementById('open-form').addEventListener('click', function () {
                  FormFlows.embed('FORM_ID', { mode: 'popup' });
                });

                // Timer (opens after 5 seconds)
                setTimeout(function () {
                  FormFlows.embed('FORM_ID', { mode: 'popup' });
                }, 5000);

                // Exit intent (fires when cursor leaves the browser window)
                FormFlows.embed('FORM_ID', {
                  mode: 'popup',
                  trigger: 'exit-intent',
                });
              });
            </script>
            ```
          </Tab>

          <Tab title="Slider">
            Slides a panel in from the right side of the screen — useful for feedback widgets and support forms:

            ```html theme={null}
            <button id="open-slider">Leave feedback</button>

            <script>
              window.addEventListener('FormFlowsReady', function () {
                document.getElementById('open-slider').addEventListener('click', function () {
                  FormFlows.embed('FORM_ID', {
                    mode: 'slider',
                    position: 'right', // 'right' or 'left'
                  });
                });
              });
            </script>
            ```
          </Tab>
        </Tabs>
      </Step>

      <Step title="Handle submission events (optional)">
        Listen for the `formflows:submit` event to run custom code after a successful submission — for example, to fire analytics events or redirect the user:

        ```javascript theme={null}
        window.addEventListener('formflows:submit', function (event) {
          console.log('Submission received:', event.detail.submissionId);
          // your custom logic here
        });
        ```
      </Step>
    </Steps>

    <Tip>
      All `FormFlows.embed()` calls accept a `prefill` object to pre-populate fields from page context — for example, `prefill: { email: currentUser.email }`. This saves your visitors from retyping information you already have.
    </Tip>
  </Tab>

  <Tab title="React component">
    If your site runs on React or Next.js, use the official `@formflows/react` package for a fully typed, framework-native integration.

    <Steps>
      <Step title="Install the package">
        ```bash theme={null}
        npm install @formflows/react
        ```
      </Step>

      <Step title="Render the component">
        Import `FormFlowsEmbed` and pass your form ID. The component renders an auto-resizing, accessible iframe by default:

        ```tsx theme={null}
        import { FormFlowsEmbed } from '@formflows/react';

        export default function ContactPage() {
          return (
            <main>
              <h1>Contact us</h1>
              <FormFlowsEmbed formId="FORM_ID" />
            </main>
          );
        }
        ```
      </Step>

      <Step title="Use display mode props">
        Pass `mode` to switch between inline, popup, and slider. Additional props control the trigger and appearance:

        ```tsx theme={null}
        import { FormFlowsEmbed } from '@formflows/react';

        // Popup triggered by a custom button
        export function FeedbackButton() {
          return (
            <FormFlowsEmbed
              formId="FORM_ID"
              mode="popup"
              trigger="button"
              buttonLabel="Send feedback"
              buttonClassName="btn btn-primary"
            />
          );
        }

        // Inline with pre-filled fields
        export function PrefilledForm({ userEmail }: { userEmail: string }) {
          return (
            <FormFlowsEmbed
              formId="FORM_ID"
              mode="inline"
              prefill={{ email: userEmail }}
            />
          );
        }
        ```
      </Step>

      <Step title="Handle submission callbacks">
        Use the `onSubmit` prop to respond to successful submissions inside your React component tree:

        ```tsx theme={null}
        import { FormFlowsEmbed } from '@formflows/react';

        export function SignupForm() {
          function handleSubmit(submissionId: string) {
            // redirect, show a toast, update state, etc.
            console.log('Submitted:', submissionId);
          }

          return (
            <FormFlowsEmbed
              formId="FORM_ID"
              onSubmit={handleSubmit}
            />
          );
        }
        ```
      </Step>
    </Steps>

    <Note>
      For Next.js App Router, add `'use client'` at the top of any file that imports `FormFlowsEmbed`, since the component uses browser APIs.
    </Note>
  </Tab>
</Tabs>

## Allowed domains

By default, FormFlows.ai allows embeds from any domain. To restrict your form to specific origins — which prevents others from embedding it on their own sites — add your domains to the allowlist.

<Note>
  Go to **Form settings → Embed → Allowed domains** and add each domain where the form will be embedded (for example, `https://yourcompany.com`). Requests from unlisted origins will be blocked with a CORS error. Leave the list empty to allow all origins.
</Note>

## Full-page embed

To display a form as a full-page experience — filling the entire browser viewport — apply these styles to both the iframe and its parent:

```html theme={null}
<style>
  html, body { margin: 0; height: 100%; }
  #form-wrapper { height: 100vh; }
</style>

<div id="form-wrapper">
  <iframe
    src="https://forms.formflows.ai/f/FORM_ID"
    width="100%"
    height="100%"
    frameborder="0"
    title="Application form"
  ></iframe>
</div>
```

## What's next

<CardGroup cols={2}>
  <Card title="Share links" icon="link" href="/guides/share-links">
    Share your form via a direct URL, QR code, or email — no embedding required.
  </Card>

  <Card title="Access control" icon="lock" href="/guides/access-control">
    Restrict who can view or submit your form.
  </Card>
</CardGroup>
