Skip to content

Add the widget to a website

Paste one block of code where the price form should appear. It works on any site that lets you add custom HTML, once the site is listed in the widget's settings.

View as Markdown

The code

Copy it from Install in the dashboard, where the widget ID is already filled in. It looks like this:

Website codeHTML
<iframe id="instant-quote" data-measuredbid-widget src="https://measuredbid.com/quote/your-widget-id" title="Your business price estimate"
  style="width:100%;border:0;min-height:640px" loading="lazy"></iframe>
<script>
  (function () {
    var s = document.currentScript, f = s && s.previousElementSibling;
    if (!f || f.tagName !== "IFRAME") f = document.getElementById("instant-quote");
    if (!f) return;
    var lastStep = null;
    var q = new URLSearchParams(location.search), p = new URLSearchParams();
    ["utm_source","utm_medium","utm_campaign","utm_term","utm_content","gclid","gbraid","wbraid","fbclid","msclkid"].forEach(function (k) {
      if (q.get(k)) p.set(k, q.get(k));
    });
    p.set("ref", location.href);
    f.src = f.src + (f.src.indexOf("?") < 0 ? "?" : "&") + p.toString();
    window.addEventListener("message", function (e) {
      if (e.origin !== "https://measuredbid.com" || e.source !== f.contentWindow) return;
      if (!e.data || typeof e.data !== "object") return;
      if (e.data.type === "instant-quote:height" && typeof e.data.height === "number" && Number.isFinite(e.data.height) && e.data.height > 0 && e.data.height <= 20000) f.style.height = Math.ceil(e.data.height) + "px";
      if (e.data.type !== "instant-quote:step" || ["address","confirm","result","no_data","booked"].indexOf(e.data.step) < 0 || e.data.brand !== new URL(f.src).pathname.split("/").pop() || e.data.step === lastStep) return;
      lastStep = e.data.step;
      if (e.data && e.data.type === "instant-quote:step" && e.data.step !== "address") {
        f.style.minHeight = "0";
        if (f.getBoundingClientRect().top < 0) f.scrollIntoView({behavior: window.matchMedia("(prefers-reduced-motion: reduce)").matches ? "auto" : "smooth", block: "start"});
      }
      if (e.data && e.data.type === "instant-quote:step" && window.dataLayer)
        window.dataLayer.push({ event: "iq_step", step: e.data.step, brand: e.data.brand });
    });
  })();
</script>
  • Loads the widget in an iframe, 100% wide, 640px tall until it knows its real height.
  • Resizes the iframe to fit each step, so there's no inner scrollbar.
  • Copies ad tracking from the page's address into the lead: utm_source, utm_medium, utm_campaign, utm_term, utm_content and gclid, gbraid, wbraid, fbclid, msclkid, plus the page address as ref.
  • Scrolls back to the top of the widget when a step changes and the top is off screen.
  • Pushes an iq_step event to window.dataLayer when Google Tag Manager is on the page. See events.

Allow your website

The widget only loads on websites listed in its settings. Browsers enforce this with the frame-ancestors security header, and an unlisted site shows a blank box.

  • Open Widgets, pick the widget, and find Websites. Add one address per line.
  • List every version visitors use: https://example.com and https://www.example.com are different sites.
  • https://*.example.com covers every subdomain, but not example.com itself.
  • Addresses must use https. The one exception is http://localhost for testing on your own computer.
  • Up to 20 addresses. Changes apply within a minute.

Where to paste it

PlatformWhereNotes
Any HTML sitePaste it in the page's HTML where the form should appear.Nothing else needed.
WordPressInstall the Measured Bid plugin and use the [instant_quote] shortcode, or paste the code in a Custom HTML block.The plugin is easiest. A Custom HTML block needs an account that is allowed to add scripts.
SquarespaceAdd a Code block and paste the code.Check the live page, not the editor preview.
WebflowAdd a Code Embed element and paste the code.Publish the site to test it.
ShopifyOnline Store, Themes, Customize, then add a Custom Liquid section and paste the code.
HighLevel sites and funnelsAdd a Custom JS/HTML element and paste the code.
WixAdd, Embed Code, Embed HTML, then paste the code.Wix runs pasted code inside a frame of its own, served from a filesusr.com address. Add https://*.filesusr.com to Websites along with your domain, and set the element about 900px tall.
GoDaddy Website BuilderAdd a section, pick HTML, then paste the code.GoDaddy also runs it inside a frame of its own. If the box stays blank, find that frame's address (how) and add it to Websites. Set a tall height.
React, Next.js, VueRender the iframe yourself.Frameworks don't run script tags inside injected HTML. Use the component below.

React and other frameworks

This component does what the pasted script does: builds the widget address with tracking, resizes the frame, and drops the loading height after the first step. Replace your-widget-id. For Vue or Svelte, keep the same steps.

MeasuredBidWidget.jsxJS
"use client";
import { useEffect, useRef } from "react";

const APP = "https://measuredbid.com";
const WIDGET = "your-widget-id";
const PASS = ["utm_source","utm_medium","utm_campaign","utm_term","utm_content","gclid","gbraid","wbraid","fbclid","msclkid"];

export function MeasuredBidWidget({ title = "Price estimate" }) {
  const ref = useRef(null);

  useEffect(() => {
    const frame = ref.current;
    // Carry ad tracking from this page into the lead, plus the page itself.
    const page = new URLSearchParams(window.location.search);
    const params = new URLSearchParams();
    PASS.forEach((key) => page.get(key) && params.set(key, page.get(key)));
    params.set("ref", window.location.href);
    frame.src = `${APP}/quote/${WIDGET}?${params}`;

    function onMessage(e) {
      if (e.origin !== APP || e.source !== frame.contentWindow || !e.data) return;
      const { type, height, step } = e.data;
      if (type === "instant-quote:height" && Number.isFinite(height) && height > 0 && height <= 20000) {
        frame.style.height = `${Math.ceil(height)}px`;
      }
      if (type === "instant-quote:step" && step !== "address") frame.style.minHeight = "0";
    }
    window.addEventListener("message", onMessage);
    return () => window.removeEventListener("message", onMessage);
  }, []);

  return <iframe ref={ref} title={title} style={{ width: "100%", border: 0, minHeight: 640 }} />;
}

Every widget has a homeowner link: https://measuredbid.com/quote/your-widget-id. It needs no code and no Websites entry, so it works on any page, in texts and emails, and on Google Business Profile and Facebook. Add URL parameters to open it on one trade or prefill the address.

ButtonHTML
<a href="https://measuredbid.com/quote/your-widget-id?service=gutters" target="_blank" rel="noopener">Get a price</a>

More than one widget on a page

Paste each widget's code where it should appear. Each script handles the iframe right before it, so keep each iframe and its script together. The WordPress shortcode can be used several times on one page.

Test it

  • Add your staging address, or http://localhost:3000 (your port), to Websites, then open the page and price an address.
  • Each new house priced counts as one estimate on the account. Pricing the same house again doesn't. The free trial includes 25.
  • Demo widgets show what homeowners see without an account: https://measuredbid.com/quote/demo-gutters. They only work as a direct link, not inside another site, and their leads aren't saved. IDs: demo-washing, demo-gutters, demo-painting, demo-siding, demo-roofing, demo-lighting, demo-holiday.
  • Send the form once to see the lead arrive in the dashboard and any webhook.