Clipform

Embed on your website

Add a Clipform to any website with a two-line code snippet.

Add an interactive Clipform to any website. Visitors can watch videos and respond directly on your page - no redirects, no popups.

Quick start

Paste this wherever you want the form to appear:

<div data-embed-id="YOUR_FORM_ID"></div>
<script src="https://www.clipform.io/embed.js"></script>

Replace YOUR_FORM_ID with your form's Form ID - the code at the end of your share link (e.g. the abc123 part of clipform.io/abc123).

That's it. The form renders as a 9:16 vertical video player, centered, up to 460px wide. On phones, tapping the form opens it fullscreen so respondents can answer comfortably - the back button returns them to your page.

Customize with data attributes

Everything is optional - the defaults just work. To tweak them, add attributes to the same <div>:

<div
  data-embed-id="YOUR_FORM_ID"
  data-embed-max-width="400px"
></div>
AttributeDefaultDescription
data-embed-idrequiredYour form's Form ID (your share ID or slot ID)
data-embed-max-width460pxWidth cap. The embed centers itself and never grows wider
data-embed-min-width375pxWidth floor. The embed never shrinks below a usable size
data-embed-height9:16 autoExplicit height. Bypasses the 9:16 ratio - use inside fixed-height containers
data-embed-posterautoYour own poster image URL, or "false" to disable the poster and play button
data-embed-inline-on-mobilefalseSet "true" to keep the form inline on phones instead of opening fullscreen
data-embed-auto-resizefalseSet "true" to let the embed grow past 9:16 to fit the form's content
data-embed-source-A label for where this embed lives (e.g. your domain), shown in analytics

Sizing

By default the embed fills its container's width up to a 460px cap (centered), holds a 9:16 aspect ratio, and never shrinks below a 375px floor - the smallest width where buttons and progress stay comfortably tappable.

Value
Aspect ratio9:16 (portrait)
Default max width460px, centered (override with data-embed-max-width or your own CSS)
Min width floor375px (override with data-embed-min-width)

The cap is a default, not a constraint - your own CSS on the container always wins:

<div style="max-width: 400px; margin: 0 auto;">
  <div data-embed-id="YOUR_FORM_ID"></div>
</div>

When you pass an explicit height via the JavaScript API, the aspect ratio is bypassed and the embed uses your value exactly. This is useful when embedding inside a fixed-size container:

cfEmbed.embed({
  formId: 'YOUR_FORM_ID',
  container: '#my-form',
  height: '780px',
});

Responsive layout

On mobile, the form looks best when it fills the full screen width with no side padding or decorative borders. On desktop, you can wrap it in a frame or add padding. A common pattern:

<style>
  .form-wrapper {
    width: 100%;
    aspect-ratio: 9 / 16;
  }

  @media (min-width: 640px) {
    .form-wrapper {
      max-width: 420px;
      margin: 0 auto;
      border-radius: 16px;
      overflow: hidden;
      box-shadow: 0 8px 30px rgba(0, 0, 0, 0.12);
    }
  }
</style>

<div class="form-wrapper">
  <div data-embed-id="YOUR_FORM_ID"></div>
</div>

Below 640px the form goes edge-to-edge. Above 640px it gets a centered frame with rounded corners.

Mobile behavior

On phones, tapping the poster opens the form in a fullscreen overlay. Respondents stay on your page - the browser back button (or back gesture) closes the overlay and returns them exactly where they were. Progress is kept, so tapping again resumes the form.

Prefer everything inline? Set data-embed-inline-on-mobile="true" (or inlineOnMobile: true in the JavaScript API).

Preventing layout shift

The embed automatically holds its space on your page (a 9:16 box) while the form loads, so surrounding content doesn't jump around. It shows a subtle loading shimmer immediately, so visitors always see that something is on its way.

By default, the embed fetches a thumbnail of the first question and displays it as a poster with a play button while the interactive form loads behind it. Visitors see content immediately and know the embed is interactive. When they click play, the form crossfades in - if it has already loaded, playback starts instantly; if it's still loading, the Clipform loading screen appears briefly before the form starts.

To provide your own poster image (skipping the auto-fetch), use the data-embed-poster attribute:

<div
  data-embed-id="YOUR_FORM_ID"
  data-embed-poster="https://example.com/my-thumbnail.jpg"
></div>

To disable the poster entirely, set data-embed-poster="false". The embed shows the loading shimmer (or your backgroundColor, if you set one) until the form loads.

JavaScript API

For more control, use the JavaScript API instead of data attributes:

<div id="my-form"></div>
<script src="https://www.clipform.io/embed.js"></script>
<script>
  cfEmbed.embed({
    formId: 'YOUR_FORM_ID',
    container: '#my-form',
    onComplete: function(data) {
      console.log('Form completed:', data.formId);
    }
  });
</script>

Options

OptionTypeDefaultDescription
formIdstringrequiredYour form's Form ID (your share ID or slot ID)
containerstringrequiredCSS selector for the container element
maxWidthstring'460px'Width cap, centered. Your own CSS on the container also overrides it
minWidthstring'375px'Width floor. The embed holds this even in narrower columns
heightstring9:16 autoExplicit CSS height. When set, bypasses the 9:16 aspect ratio
widthstring'100%'CSS width for the iframe
posterstring | falseauto-fetchedThumbnail URL shown while the form loads. Set to false to disable
backgroundColorstring'transparent'Loading background. Replaces the default shimmer
borderRadiusstring'8px'Corner rounding
autoResizebooleanfalseOpt in to grow the embed to the form's content height instead of holding 9:16
inlineOnMobilebooleanfalseKeep the form inline on phones instead of opening fullscreen on tap
sourcestring-A label for where this embed lives, shown in analytics
titlestring'Embedded form'Accessible label for the iframe (screen readers)

Lifecycle callbacks (onReady, onStarted, onComplete, and more) are listed under Events.

Events

Lifecycle callbacks let your page react to the form - fire your own analytics, show a thank-you message, or redirect after completion. Pass them to cfEmbed.embed():

cfEmbed.embed({
  formId: 'YOUR_FORM_ID',
  container: '#my-form',
  onStarted: function (data) { console.log('started', data.formId); },
  onComplete: function (data) { console.log('completed', data.formId); },
});
CallbackFires whenReceives
onReady(iframe)The form has loaded and is readythe iframe element
onStarted(data)The respondent answers the first node{ formId }
onNodeComplete(data)The respondent finishes a node{ formId, nodeId, index } - index counts nodes completed so far
onComplete(data)The respondent completes the form{ formId }
onEndScreenButtonClick(data)The respondent clicks an end-screen button{ formId, nodeId }
onLoad(iframe)The form is first revealed (legacy - prefer onReady)the iframe element

Privacy: callbacks carry IDs and counts only, never the respondent's answers. Answer content stays between the form and Clipform, so forwarding these events to your own analytics is safe.

Troubleshooting

Form not loading

  • Check that the Form ID is correct (the 8-12 character code from your share link)
  • Make sure the form is set to Live in the dashboard
  • Check browser console for errors

Form appears but video won't play

  • Embedded forms use click-to-play. The respondent must click the play button to start.

Content is clipped

The embed sizes itself to a 9:16 box from its container's width, so make sure the container has a defined width and isn't constrained to a shorter height. If you're embedding inside a fixed-height container, pass an explicit height option so the embed fills your container instead.

Embed overflows a narrow column

The embed holds a 375px minimum width so buttons and progress stay usable - in a narrower column it overflows rather than shrinking into an unusable form. Give the column more room, or lower the floor with data-embed-min-width if you accept smaller tap targets.

Camera/microphone not working

The embed iframe includes allow="camera; microphone" permissions. If your site has a strict Content Security Policy, you may need to add camera and microphone to your permissions-policy header.

On this page