Listings iFrame Snippets
Before you start
- Your Boom contact will provide the link to put in place of the <YOUR_LINK_HERE> placeholder. It always starts with https://boom.rent/.
- Only the link gets replaced. The script line is literal: https://boom.rent/boom-embed.js is the real address, not a placeholder.
- If the default embedding dimensions do not work as expected on your web page, please reach out to your Boom contact for assistance.
- Boom recommends testing your changes on Desktop and Mobile devices before you publish.
- Test on a real phone, on your published page. Site-builder previews (Duda, HubSpot, Wix…) often do not run custom scripts, so the embed can look broken in the editor and work fine once published.
List of ready to use snippets
Recommended snippet - the widget sizes itself
Embeds the listings and lets the widget take exactly the height of its content, so your page is the only thing that scrolls - on desktop and on every mobile browser. The height:90vh is only what visitors see until the listings load; a moment later the widget grows to fit.
<iframe
src="<YOUR_LINK_HERE>"
id="boom-iframe"
style="height:90vh;width:100%"
title="Boom Listings"
frameborder="0"
allow="camera; microphone"
>
</iframe>
<script src="https://boom.rent/boom-embed.js?handoffMode=auto-height" async></script>For the widget to grow, its height has to be free to change:
- Do not wrap the iframe in a box with a fixed height and overflow: hidden (some site builders add one). A wrapper with rounded corners and overflow: hidden is fine as long as it has no fixed height.
- Do not pin the iframe height in your site's CSS with !important.
If either is present, the widget notices within a couple of seconds and falls back to the fixed-height behaviour below - nothing breaks, you just do not get the single-scroll experience.
Keep allow="camera; microphone" on the iframe. When a visitor requests a showing, Boom may ask them to verify their identity with a photo of their ID and a selfie. Browsers let an embedded page use the camera only when the iframe tag allows it. Without the attribute, the camera fails at once and the browser never even asks the visitor for permission.
- Your page must be served over https. Browsers do not give the camera to anything on a plain http page.
- If your site sends a Permissions-Policy header that mentions camera, it must include Boom, e.g. Permissions-Policy: camera=(self "https://boom.rent"). If the header does not mention the camera at all, nothing needs to change.
Fixed-height widget (scrollable within size constraints)
The classic embed: the widget keeps the height you give it and the listings scroll inside it. On mobile, the script hands scrolling over to your page whenever the visitor reaches the top or bottom of the listings (see "Scrolling on mobile with the fixed-height widget").
<iframe
src="<YOUR_LINK_HERE>"
id="boom-iframe"
style="height:90vh;width:100%"
title="Boom Listings"
frameborder="0"
allow="camera; microphone"
>
</iframe>
<script src="https://boom.rent/boom-embed.js" async></script>Fixed-height widget with a separate mobile height
Same as above, with the widget fixed to 768px on phones and tablets.
<div>
<style>
#boom-iframe { height: 90vh; width: 100% }
@media screen and (max-width: 810px) {
#boom-iframe { height: 768px; }
}
</style>
<iframe
src="<YOUR_LINK_HERE>"
id="boom-iframe"
title="Boom Listings"
frameborder="0"
allow="camera; microphone"
>
</iframe>
<script src="https://boom.rent/boom-embed.js" async></script>
</div>You can use this snippet as a base for experimentation.
- To tweak the desktop size, replace height: 90vh with the desired desktop height.
- To tweak the mobile size, replace height: 768px with the desired mobile height.
- With the recommended (self-sizing) script line these heights only apply until the listings load.
HubSpot integration
HubSpot requires a CSS selector to attach the embed to the right element on your page. Replace <USE_YOUR_CSS_PARENT_SELECTOR> with an actual selector that exists on the page.
var wrapper = document.querySelector('<USE_YOUR_CSS_PARENT_SELECTOR>');
<script type='text/javascript'>
document.addEventListener('DOMContentLoaded', function () {
var wrapper = document.querySelector('<USE_YOUR_CSS_PARENT_SELECTOR>');
if (!wrapper) return;
var boomLink = '<YOUR_LINK_HERE>';
// Create loading indicator
var loader = document.createElement('div');
loader.id = 'boom-loader';
loader.style.cssText = 'display:flex;align-items:center;justify-content:center;height:90vh;width:100%;background:#f5f5f5;font-family:sans-serif;color:#676767;font-size:16px;';
loader.innerHTML = '<span>Loading listings...</span>';
// Create iframe
var iframe = document.createElement('iframe');
iframe.src = boomLink;
iframe.id = 'boom-iframe';
iframe.title = 'Boom Listings';
iframe.frameBorder = '0';
// Lets identity verification inside the widget use the camera.
iframe.allow = 'camera; microphone';
iframe.style.cssText = 'height:90vh;width:100%;display:none;';
// Swap loader for iframe on load
iframe.addEventListener('load', function () {
loader.style.display = 'none';
iframe.style.display = 'block';
});
wrapper.appendChild(loader);
wrapper.appendChild(iframe);
// Boom embed helper: sizes the widget to its content, smooth scrolling around
// it, conversion tracking. It must come from the same host as the listings link.
// Drop "?handoffMode=auto-height" if you prefer the fixed-height widget.
var helper = document.createElement('script');
helper.src = new URL(boomLink).origin + '/boom-embed.js?handoffMode=auto-height';
helper.async = true;
document.head.appendChild(helper);
});
</script>
How the self-sizing widget works
The listings report their height to the script on your page, and the script sets the iframe to match. As the visitor filters, pages or opens a listing, the widget grows and shrinks with its content. There is no scrollbar inside the widget, and no "stuck" scrolling on mobile.
- When the visitor goes to the next page of listings or opens a listing, the script scrolls your page back to the top of the widget - the new content starts there.
- While a dialog inside the widget is open (the filters sheet on phones, the photo gallery), the script holds your page still and opens the dialog within the part of the widget that is on screen.
- Several widgets on one page are fine; each is sized on its own.
Known limits: on phones, the Apply / Contact buttons of a listing scroll with the content instead of staying pinned to the bottom; if your site has a fixed header, the top of the widget lands under it after a page change.
Scrolling on mobile with the fixed-height widget
With a fixed-height widget the listings scroll inside the iframe. On mobile browsers a scroll gesture cannot cross the iframe boundary, so without help a visitor who reaches the top or bottom of the feed appears "stuck": the rest of your page - your navigation above, your footer below - stays out of reach, and visitors may conclude that listings are missing when they simply cannot scroll past the widget.
The boom-embed.js line fixes this. When a visitor reaches an edge of the feed, the script gently scrolls your page onward in that direction, keeping the widget's search bar and pagination on screen. To carry on, the visitor scrolls the part of the page around the widget. Nothing to configure.
Good to know (both variants)
- It is the same script that powers conversion tracking (§4) - one include covers both.
- Load it by src, from https://boom.rent - the same host as your listings link. The script only trusts the widget it was loaded from; loading it from another address, or pasting its contents inline, disables it silently.
- Only one copy runs per page, so extra copies are harmless - but keep them identical: with a plain copy and a ?handoffMode=auto-height copy on the same page, whichever loads first decides the mode.
- No personal data ever crosses the frame boundary.
- If you already embed Boom with an older snippet, just add the one script line next to your existing iframe. To switch an existing embed to the self-sizing widget, add ?handoffMode=auto-height to that line.
Ad campaign & conversion tracking
Everything in this section is optional configuration - the listings pages work without it. (The boom-embed.js script itself is part of the standard snippets above and stays: it also sizes the widget and handles scrolling around it, see "How the self-sizing widget works"). Set it up when your marketing team wants to measure what the embedded pages produce: which ad campaigns drive leads and showings, how visitors move through the funnel, or when they want to fire their own tags (Meta pixel, GA4, anything routed through Google Tag Manager) on a successful submission.
Because Boom's pages run inside an iframe on your site, tracking needs a small amount of glue in two directions:
- Into the frame - when a visitor lands on your page from an ad, the click ID (gclid) and campaign tags (utm_*) are on your page's URL. The iframe cannot read them on its own; a one-time snippet forwards them in.
- Out of the frame - when a visitor submits a form inside the iframe, tools on your page (GTM, Meta pixel) cannot see it happen. A one-line script bridges the signal out.
1. Forward ad-click parameters into the iframe
Browsers do not let an embedded iframe read the address bar of the page that embeds it. So when a visitor arrives from an ad - e.g. yoursite.com/rentals?gclid=Cj0K...&utm_campaign=spring - Boom never sees those parameters unless your page passes them along.
Add the data-boom-embed attribute to every Boom iframe on the page, then paste this script once, anywhere after the iframe(s):
<iframe data-boom-embed src="<YOUR_LINK_HERE>" id="boom-iframe" style="height:90vh;width:100%" title="Boom Listings" frameborder="0" allow="camera; microphone"></iframe>
<script>
(function () {
var KEYS = ["gclid", "utm_source", "utm_medium", "utm_campaign", "utm_term", "utm_content"];
var pageParams = new URLSearchParams(window.location.search);
document.querySelectorAll("iframe[data-boom-embed]").forEach(function (frame) {
try {
var src = new URL(frame.getAttribute("src"), window.location.href);
var changed = false;
KEYS.forEach(function (key) {
var value = pageParams.get(key);
if (value) { src.searchParams.set(key, value); changed = true; }
});
if (changed) frame.setAttribute("src", src.toString());
} catch (e) { /* leave the iframe untouched */ }
});
})();
</script>What it does: copies gclid, utm_source, utm_medium, utm_campaign, utm_term and utm_content from your page's URL onto the iframe's URL - only when they are present. Boom then stores them on the resulting Lead and Showing records and uses the gclid to report Google Ads conversions (§3).
Without this snippet, Google Ads conversion reporting falls back to Google's own cookie matching (which only works some of the time), and campaign tags won't be attached to your leads in Boom. If you run any paid campaigns to pages with a Boom embed, add it.
2. Google Analytics (GA4)
If you use GA4, Boom can report the visitor funnel inside the embedded pages straight into your GA4 property. No snippet changes are needed.
Setup: Boom Portal → Settings → Integration → Google Analytics → paste your GA4 Measurement ID (G-XXXXXXXX).
Once saved, these events appear in your GA4 property:
Event in GA4 | Fired when |
|---|---|
listing_contact_us_attempted | A visitor opens the Contact Us form on a listing |
listing_request_showing_attempted | A visitor starts the Request a Showing flow |
listing_apply_attempted | A visitor clicks Apply on a listing |
listing_custom_button_attempted | A visitor clicks a custom button configured on your listings |
contact_us_submitted | A visitor submits the contact / "about you" form on a listing |
request_showing_slot_selected | A visitor picks a showing time slot |
request_showing_completed | A showing is booked |
prescreening_submitted | A visitor submits the pre-screening questionnaire |
contact_form_submitted | An embedded contact form is submitted |
3. Google Ads conversion tracking
If you run Google Ads campaigns, Boom can report a real Google Ads conversion (not just an analytics event) when a visitor converts inside the embed - so your Google Ads dashboard shows "Campaign X drove N leads / M showings".
Setup:
- In Google Ads, find your conversion action's ID and label: Goals → Conversions → your conversion action → Tag setup → "Use Google tag" - you'll see a Conversion ID (AW-123456789) and a Conversion Label. Create up to two conversion actions: one for contact form submitted, one for showing booked.
- In the Boom Portal → Settings → Integration → Google Ads → paste the Conversion ID and the label(s).
- Add the forwarding snippet from §1 to your page - strongly recommended, so the click ID reaches the iframe and conversions attribute reliably.
Conversions are then reported at exactly two moments:
- Contact Form Submitted label - a visitor submits a contact form (on a listing or embedded).
- Showing Booked label - a visitor books a showing.
4. Google Tag Manager / Meta pixel (host-page events)
If you prefer to fire your own tags - a Meta pixel Lead event, a GA4 tag in your own container, anything else in GTM - Boom can notify your page whenever a visitor completes a submission inside the iframe.
If you used one of the snippets at the top of this page, the script is already on your page - skip to step 2.
Step 1 - add the bridge script next to your iframe (once per page, covers every Boom embed on it):
<script src="https://boom.rent/boom-embed.js" async></script>Use the address exactly as written: https://boom.rent is the host of every Boom listings link, and the script only trusts messages from the host it was loaded from - loading it from anywhere else, or pasting its contents inline, means events will be ignored. If a snippet above already put the script on your page, do not add a second, plain copy: only one copy runs, and a plain one loading first would switch off the self-sizing widget.
Step 2 - create one GTM trigger. On each successful submission the script pushes a Custom Event onto your data layer:
{
event: "boom_form_submitted",
boom_source: "request_showing.completed", // which flow completed
boom_partner_slug: "your-company",
boom_property_slug: "maple-court", // present when a property is known
boom_unit_slug: "unit-3b", // present when a unit is known
boom_lead_id: "idle_x1y2z3" // present when a lead was created
}In GTM: Triggers → New → Custom Event → event name boom_form_submitted, then attach your existing Meta pixel / GA4 / other tag to that trigger.
Data layer field | Meaning |
|---|---|
boom_source | Which flow completed: contact_form.submitted, contact_us.submitted, request_showing.completed, or request_showing.submitted (showing requested, pending time confirmation) |
boom_partner_slug | Your company identifier - always present |
boom_property_slug | The property, when known |
boom_unit_slug | The unit, when known |
boom_lead_id | The created lead's ID - works well as Meta's eventID for deduplication |
Optionally create Data Layer Variables for the boom_* fields to segment or deduplicate.
- No personal data ever crosses the frame boundary - IDs and slugs only, never a name, email, or phone number.
- Meta ads: nothing needs to be forwarded into the iframe for Meta - your pixel and its _fbp/_fbc cookies live on your page, and this event lets GTM fire the pixel right there. Attribution happens on Meta's side.
- The script is safe to include on pages without GTM, and safe to paste more than once - it deduplicates itself.
Verifying your setup
The easiest tool for this is Google Tag Assistant - it shows every Google tag and data layer event firing on a page in real time.
- Open your page with test parameters appended, e.g. yoursite.com/rentals?gclid=TEST123&utm_source=google&utm_campaign=test.
- Submit a contact form or book a showing through the embed.
- Your own tags (GTM): connect Tag Assistant to your page - GTM Preview mode does this automatically. The boom_form_submitted event appears in the data layer with the identifiers attached, and you can watch your Meta / GA4 / other tags fire on it.
- Boom's GA4 & Google Ads tags: they fire inside the iframe, so Tag Assistant on your page won't see them - instead, connect Tag Assistant to the Boom page itself: open your Boom listings link directly in a new tab with the same test parameters. Alternatively, in DevTools → Network a request to googleadservices.com with send_to=AW-.../<label> confirms the Ads conversion; it appears in Google Ads within a few hours.
- GA4: the events appear in Reports → Realtime.
- Your Boom contact can confirm the campaign tags (gclid=TEST123) were stored on the resulting lead.
- Scrolling. On a real phone, open your published page. With the recommended snippet the widget has no scrollbar of its own: swipe anywhere and the whole page scrolls, and after tapping page 2 the page comes back to the top of the widget. With a fixed-height widget, swipe the listings to their end: the page should continue scrolling to reveal what is below the widget, and swiping back to the feed's top brings your navigation back into view. If nothing happens, confirm that the script tag is present and loads from https://boom.rent/boom-embed.js
- Identity verification. On a real phone, on your published page, open a listing, choose Schedule Showing and go through the steps until Verify your identity. When you are asked to photograph your ID, the browser must ask for camera permission. If you see "Couldn't access camera" and no permission prompt appeared, check that the iframe tag has allow="camera; microphone", that your page is on https, and that no Permissions-Policy header on your site blocks the camera.
.