Embed Our Square Footage Calculator
Add a free, interactive square footage calculator to your blog, contractor site, or real estate page. One script tag — no API key, and it is licensed for commercial use.
Last updated:Live Preview
The box above is a real embed: it is the same <script> tag you are about to copy, loading /embed/square-footage-calculator/ in an iframe and resizing to fit.
Embed Code
Copy and paste this HTML where you want the calculator to appear:
<div id="footycalc-embed"></div>
<script src="https://footycalc.com/js/embed.js"
data-target="footycalc-embed"
data-width="100%"></script>
The script needs no initialization call and no library. It reads its own attributes, inserts one iframe, and listens for a resize message. Nothing is uploaded from your visitors' inputs to us — the arithmetic runs inside the iframe, on their machine.
Options
| Attribute | Default | Description |
|---|---|---|
data-target | footycalc-embed | ID of the container div. If the element does not exist, the script creates one and inserts it before the tag. |
data-width | 100% | iframe width (any CSS length value). |
data-height | 520 | Initial height in px, before the first auto-resize message arrives. |
data-calculator | square-footage-calculator | Embed slug under /embed/. See "Which Slugs Exist" below — the list is short and real. |
data-host | https://footycalc.com | The origin the iframe is built from. Change it only if you are hosting your own verified copy of our embed pages; anything else sends your visitors' input to that origin's code, so treat it as a footgun, not a feature. |
Every attribute the loader actually reads is in that table; the loader reads exactly these five and nothing else. That is not a coincidence — see the caching section for why.
Which Slugs Exist
Today there is one embeddable page:
square-footage-calculator→https://footycalc.com/embed/square-footage-calculator/
Passing any other value to data-calculator yields a 404 inside the iframe, not a fallback. We are documenting the real inventory rather than writing "all calculators available soon" — if you need a second widget, ask and we will tell you honestly whether it exists.
How The Embed Is Cached (And Why That Constrains Changes)
The URL https://footycalc.com/js/embed.js is referenced by other people's websites, so unlike our CSS and JS bundles it cannot be versioned with a ?v= hash: old tags on old pages must keep working. It is therefore served with a one-year immutable cache header:
Cache-Control: public, max-age=31536000, immutable
Two consequences, and we designed around both:
- The script is a permanent, thin loader. It does exactly three jobs — read the five attributes above, insert the iframe, listen for
footycalc-resize. Anything that might need to change tomorrow lives in the iframe's HTML instead. - The embed page is not cached that way. Pages under
/embed/are HTML, and our live HTML responses carryCache-Control: public, max-age=0, must-revalidate. So a layout change, a new shape, or a fix to the widget reaches your visitors on their next page view — no cache-busting on your side.
Why not simply add a shorter cache rule for this one file? Because our host's _headers file joins values when a header is applied twice ("If a header is applied twice in the _headers file, the values are joined with a comma separator"), so a second Cache-Control for /js/embed.js would collide with the /js/* rule instead of replacing it. Keeping the file immutable and moving variability into HTML is the option we can actually verify, so that is the one we took. The trade-off is documented on purpose: almost no widget doc explains why its script URL is frozen.
How Auto-Resize Works
The iframe posts its own height to the parent page; the loader listens and applies it:
- The embedded page measures
max(documentElement.scrollHeight, body.scrollHeight, documentElement.offsetHeight)and callspostMessage({type:'footycalc-resize', height}, '*')on load, on resize, on aResizeObserver, and twice more at 500 ms and 1500 ms to catch late layout. - The loader ignores any message whose
typeis notfootycalc-resize, and any height that is not a number above 100 px — so a rogue frame cannot shrink your layout to zero. - The iframe is created with
loading="lazy"andallow="clipboard-write". Lazy loading defers the frame fetch "until it reaches a calculated distance from the visual viewport", which is why a below-the-fold embed may take a moment longer to size itself.
Attribution
Free embeds must include a visible link to FootyCalc. The embedded page renders that line itself, inside the iframe, below the calculator — the text is "Square footage calculator by FootyCalc" and the link opens in a new tab. Do not remove it, and do not cover the iframe footer with CSS on your page. Hiding the attribution takes back the license in section 6.2 of our Terms of Service.
Terms
- Free for personal and commercial use, under section 6.2 of the Terms of Service — that section, not the general "personal, non-commercial" site-use clause, governs embeds.
- No modification of the iframe content.
- Do not frame the full footycalc.com site — use the
/embed/URL only.
What This Means For Search Engines
The embedded page declares itself noindex, follow in its robots directive, and it is a small page by design: one heading, the calculator, and the attribution line. So the widget never competes with your page for the ranking of "square footage" — the iframe's content is excluded from indexing, while the crawler is still allowed to follow its links.
- Your page keeps the SEO credit. Write your own heading and a paragraph around the embed; that text is what search engines read.
- Do not rely on the iframe for content. Some crawlers do not index iframe text at all, which is exactly what we want here.
- Framing headers. Pages under
/embed/are served withContent-Security-Policy: frame-ancestors *so any origin can embed them, while the rest of the site staysSAMEORIGIN. You can confirm both withcurl -I— see the worked example.
Worked Example: From Script Tag To Final Height
What actually happens when you paste the code above, using measurements we took on our own files on :
- Your page parses the tag.
embed.jsresolves the attributes: targetfootycalc-embed, width100%, height520, slugsquare-footage-calculator, hosthttps://footycalc.com. - It creates
<iframe src="https://footycalc.com/embed/square-footage-calculator/">withstyle.height = "520px". That is the height before any message arrives. - The frame loads. At a container width of 1280 px its document measures 1307 px tall; at a phone-like 390 px it measures 1407 px. The iframe posts each number to the parent, and the loader sets
style.heighttoceil(height) + "px"— so the box grows from 520 px to 1307 px, and re-flows to 1407 px when the layout narrows. - Verify the cache contract yourself:
curl -sI https://footycalc.com/js/embed.js | grep -i cache-controlreturns exactly one line, the immutable one. If you ever see two values joined by a comma, that is a regression in our_headers— tell us.
Set data-height to something close to the final value if you care about layout shift: starting at 1300 instead of 520 means the frame has to grow by ~7 px rather than ~787 px.
Sources and How To Check This Page
On the .gov requirement we apply to our content pages: none applies here. A widget's cache header and postMessage protocol have no government source, and inventing one would be decoration. The sources below are the host's documentation, the web platform reference, and our own served bytes, which you can re-check in about a minute:
- Cloudflare Pages — Custom headers. The exact sentence behind our caching decision: "If a header is applied twice in the _headers file, the values are joined with a comma separator."
- MDN —
<iframe>element reference. Theloading="lazy"andallowattributes this widget sets, including the "calculated distance from the visual viewport" definition of lazy framing quoted above. - CIDR — Embed widget documentation. A peer calculator site's iframe widget doc, used here as a comparator: it documents width/height guidance but, like most widget docs, says nothing about how the script URL is cached.
- Our own bytes, which are the most current source available:
/js/embed.js(44 lines — read it; the fivedata-attributes are all it looks at),/embed/square-footage-calculator/(the frame document, with the attribution line and the inline resize script), and Terms of Service section 6.2 for the license.