# Email Input Field Trigger





<Warning>
  **WAIT...** Make sure that you have added the [**Surface Tag**](/platform/traffic/surface-tag) to your site before proceeding.
</Warning>

## 1. Add the HTML Form [#1-add-the-html-form]

Your HTML form needs the `surface-form-handler` class:

```html
<form class="surface-form-handler">
  <input type="email" placeholder="Enter your email" required />
  <button type="submit">Submit</button>
</form>
```

<Note>
  Add the &#x2A;*`surface-form-handler`** class to any external form that you want to use to trigger the Surface Form popup.
</Note>

## 2. Modify the Surface Form Embedding Script [#2-modify-the-surface-form-embedding-script]

Modify the Surface Form Embedding Script to include the `data-question-id` attribute.

<Note>
  You must replace the &#x2A;*`<question_id>`*&#x2A; within &#x2A;*`data-question-id`** attribute below with the question ID from the Surface Form Builder.
</Note>

<Frame>
    <img alt="Question ID Location" src="__img0" />
</Frame>

```html
<!-- Start Surface Form Embed -->

<script data-question-id="<question_id>">
  (function () {
    const surface_src = "surface_form_url";
    const surface_embed_type = "slideover"; // works on all embedding types!
    const target_element_class = "surface-form-button";
    const c = new SurfaceEmbed(
      surface_src,
      surface_embed_type,
      target_element_class,
    );
  })();
</script>

<!-- End Surface Form Embed -->
```

## 3. Test Your Integration [#3-test-your-integration]

* Enter a valid email in the input field and press "Submit" or hit "Enter".
* Verify that the Surface Form popup is displayed as expected.

## Optimize Speed [#optimize-speed]

Add the following `<link>` tags inside the `<head>` of your site:

```html
<!-- Speed up connections to forms.withsurface.com by performing early DNS resolution and TCP handshake -->
<link rel="dns-prefetch" href="https://forms.withsurface.com">
<link rel="preconnect" href="https://forms.withsurface.com" crossorigin>

<!--  Fetch the form in advance, so it's ready when a user opens it. -->
<link rel="prefetch" href="REPLACE ME WITH FORM URL" as="document">
```

<Info>
  Replace `REPLACE ME WITH FORM URL` with a Surface Form URL.
</Info>

<Info>
  If the form uses a custom domain, replace `forms.withsurface.com` in the connection hints with your verified domain. See [Use the Surface Tag with a Custom Domain](/platform/traffic/custom-domains).
</Info>

## Explanation [#explanation]

1. dns-prefetch → Resolves the domain early to skip DNS lookup delays.
2. preconnect → Prepares the TCP + TLS handshake so the browser is ready to request assets immediately.
3. prefetch → Fetches the form in advance, so it's ready when a user opens it.

## Where to Paste It [#where-to-paste-it]

The constructor script goes in the same place as any other triggered embed.
Your existing email input needs `class="surface-form-handler"` on its `<form>`.

<Tabs>
  <Tab title="Webflow">
    Webflow [dashboard](https://webflow.com/dashboard) → **Project Settings** →
    **Custom Code**, and paste it into the **Footer Code** section. Publish the
    site for it to take effect.

    Then give the trigger element the class: select the button in Designer, open
    the **Style** panel, and add `surface-form-button` to the Style Selector.
  </Tab>

  <Tab title="Framer">
    Framer → project **Settings** → **Custom Code** → **End of `<body>` tag**.

    Framer has no class field, so the trigger needs a code override. In the
    element's **Code Overrides**, create a file called `SurfaceFormButton` and
    add:

    ```tsx
    export function withClass(Component): ComponentType {
      return (props) => {
        props.className += " surface-form-button" // keep the leading space
        return <Component {...props} />
      }
    }
    ```

    Then select `SurfaceFormButton` → `withClass` on the element.

    <Tip>
      Custom code is a paid Framer feature.
    </Tip>
  </Tab>

  <Tab title="WordPress">
    Use a header/footer plugin. [WPCode](https://wordpress.org/plugins/insert-headers-and-footers/)
    is the usual choice. **Code Snippets → Header & Footer**, paste into the
    **Footer** box, save.

    Add `surface-form-button` to the trigger element's CSS classes in the block
    editor's **Advanced** panel.
  </Tab>

  <Tab title="Next.js">
    In `app/layout.tsx` (App Router) or `pages/_document.tsx` (Pages Router),
    using `next/script` with `strategy="afterInteractive"`:

    ```tsx
    import Script from "next/script";

    <Script
      id="surface-form-script"
      strategy="afterInteractive"
      dangerouslySetInnerHTML={{ __html: `
        (function () {
          const surface_src = "REPLACE ME WITH FORM URL";
          const surface_embed_type = "popup";
          const target_element_class = "surface-form-button";
          new SurfaceEmbed(surface_src, surface_embed_type, target_element_class);
        })();
      `}}
    />
    ```

    Then `<button className="surface-form-button">Open form</button>`.
  </Tab>

  <Tab title="React">
    In `public/index.html`, at the end of `<body>`.

    Then `<button className="surface-form-button">Open form</button>` anywhere in
    your tree. The embed script binds by class, so it works with elements React
    renders later.
  </Tab>

  <Tab title="Unbounce">
    In the page editor's bottom toolbar → **JavaScript** → **Add New JavaScript*&#x2A;,
    with placement &#x2A;*"Before the body Tag"**.

    Unbounce loads scripts unpredictably, so guard the constructor and run it on
    first interaction:

    ```html
    <script>
      let surfaceInitialized = false;
      function initializeSurfaceForm() {
        if (surfaceInitialized || typeof SurfaceEmbed === "undefined") return;
        surfaceInitialized = true;
        new SurfaceEmbed("REPLACE ME WITH FORM URL", "popup", "surface-form-button");
      }
      document.addEventListener("click", initializeSurfaceForm, { once: true });
      document.addEventListener("scroll", initializeSurfaceForm, { once: true });
    </script>
    ```
  </Tab>

  <Tab title="HTML">
    Anywhere before `</body>`, on every page that has a trigger element. Give
    that element `class="surface-form-button"`.
  </Tab>
</Tabs>
