Embed documentation

Everything you need to put A2Z widgets on a website or app: the plain iframe, the optional auto-height loader, every URL parameter, events, security headers, and step-by-step instructions for common platforms and frameworks. All 152 widgets use the same system.

Quick start

  1. Pick a widget at a2z.tools/embed.
  2. Choose the theme, width, style and starting values, and check the live preview.
  3. Copy the code and paste it into an HTML / custom-code block on your page.

No account, no API key and no payment are needed. Widgets carry no ads.

Basic iframe

The simplest embed is an iframe. It works on every platform, including those that remove <script> tags.

<iframe src="https://a2z.tools/embed/w/emi-calculator?theme=auto&currency=INR"
        title="EMI Calculator by A2Z Tools"
        width="100%" height="560"
        style="border:0;width:100%;max-width:480px"
        loading="lazy" allow="clipboard-write"></iframe>
  • title names the frame for screen readers - keep it.
  • loading="lazy" defers the widget until it is near the viewport.
  • allow="clipboard-write" lets the "Copy result" button work.
  • The widget page URL is /embed/w/{slug}; the slug is the last part of the widget's page address.

Responsive sizing

Every widget is fluid: give the iframe width:100% and, if you want, a max-width. Widgets are tested from 320 px to 1024 px wide without horizontal scrolling. With a plain iframe the height is fixed - the builder measures the widget at the width you choose and fills in a height with a little room to spare. If your layout makes it narrower (and therefore taller), raise height or use the loader below.

Auto height with the loader

The optional loader (about 3 KB) turns placeholders into iframes and keeps each one exactly as tall as its content:

<div data-a2z-widget="world-clock" data-theme="dark"
     data-v-zones="Asia/Kolkata,Europe/London"></div>
<script async src="https://a2z.tools/embed.js"></script>
  • Include the script once per page; it finds every [data-a2z-widget] placeholder, including ones added later.
  • Widgets are created lazily, 400 px before they scroll into view.
  • It also resizes A2Z iframes you placed yourself.
  • It creates one global, window.A2ZEmbed, and loading it twice is harmless.
  • Placeholder attributes: data-a2z-widget (slug, required), data-height (initial px), data-width (max width, e.g. 480 or 80%), data-title-text (iframe title), every option below as data-{name}, and starting values as data-v-{field}.

JavaScript API

A2ZEmbed.scan(rootElement);          // after your framework renders new placeholders
A2ZEmbed.setTheme(element, "dark");   // "light" | "dark" | "auto", without reloading

URL parameters

Every option is a query parameter on the iframe URL (or a data- attribute with the loader). Unknown or invalid values are ignored - nothing you pass is ever rendered as HTML.

ParameterValuesDefaultEffect
themelight, dark, autoautoColour scheme. auto follows the visitor's device setting.
stylestandard, compactstandardCompact tightens spacing and type.
title1, 010 hides the widget's heading (it stays available to screen readers).
border1, 010 removes the outer border.
radius0-2412Corner radius in px.
accent6-digit hex, no #2563ebAccent colour for buttons and highlights; text colour on it is chosen for contrast.
currencyISO 4217 code (USD, EUR, INR, GBP ...)per widgetCurrency for money fields and results.
localeBCP 47 tag (en-IN, de-DE ...)from currencyNumber and date formatting.
unitsmetric, imperialper widgetMeasurement system where a widget supports both.
v_{field}text-Starting value for a field, e.g. v_amount=2500000. Each widget page lists its fields under "Starting values".

Themes

auto is the best default: the widget matches the reader's light or dark preference. If your site has its own dark-mode switch, pass theme=light or theme=dark, and with the loader call A2ZEmbed.setTheme(el, "dark") when your switch changes. The widget background is transparent around its card, so it sits on any page colour.

Currency, units and locale

Money widgets format results with Intl.NumberFormat, so currency=INR gives ₹25,00,000.00 with Indian digit grouping and currency=EUR&locale=de-DE gives 2.500.000,00 €. Input fields always accept "." as the decimal separator and "," only as a digit-group separator, so a value such as "1,5" is refused with a message rather than guessed. Body-measurement widgets offer a metric/imperial switch; set the starting system with units. Widget text is English today; the runtime keeps all interface strings in one table so other languages can be added.

Events and postMessage

A widget frame sends these messages to its parent window (the loader handles them for you):

MessageWhen
{ a2z: "embed", t: "ready", slug }The widget has rendered.
{ a2z: "embed", t: "height", slug, h }The content height changed (px).

The frame accepts one message from its parent: { a2z: "embed", t: "theme", theme: "light" | "dark" | "auto" }. If you listen yourself, check the origin and the source:

window.addEventListener("message", function (e) {
  if (e.origin !== "https://a2z.tools" || e.source !== myIframe.contentWindow) return;
  if (e.data && e.data.a2z === "embed" && e.data.t === "height") {
    myIframe.style.height = Math.min(5000, Math.max(80, e.data.h)) + "px";
  }
});

Widgets never send what a visitor typed to the parent page or anywhere else.

Security and Content-Security-Policy

  • Widget frames run on a2z.tools, isolated from your page by the browser's same-origin policy: they cannot read your page, your cookies or your visitors' data, and your CSS cannot break them.
  • Each frame is served with a strict policy of its own: scripts only from a2z.tools, no inline script, no plugins, no forms posting elsewhere, no cookies.
  • If your site sends a Content-Security-Policy, allow the frame with frame-src https://a2z.tools, and if you use the loader, script-src https://a2z.tools. Badges need img-src https://a2z.tools.
  • You can sandbox the frame. This set is tested with every widget:
    sandbox="allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox allow-downloads"
    (allow-same-origin refers to a2z.tools' own origin, which the widget needs for its scripts; it does not give the widget access to your page.)
  • The loader accepts height messages only from the A2Z origin and only from iframes it knows about, and clamps heights to 80-5000 px.

Privacy

Calculators, converters, generators, clocks and developer tools run entirely in the visitor's browser; nothing typed into them is sent anywhere. Where a widget needs data - exchange rates, a website check, the visitor's own IP address - it asks A2Z's server, which does not store the inputs. Widgets set no cookies and load no advertising, tag manager or session-recording scripts. A2Z counts anonymous totals only: widget, day, event (loaded / used) and the host name of the embedding site. No IP addresses, full URLs or identifiers are kept.

Security badges

Badges are SVG images: https://a2z.tools/badge/{check}/{domain}.svg with check one of ssl, ssl-expiry, https, hsts, headers, spf, dmarc, dnssec, online. Options: style=flat|rounded|square, theme=light|dark, size=compact.

<a href="https://a2z.tools/report/ssl/example.com" target="_blank" rel="nofollow noopener">
  <img src="https://a2z.tools/badge/ssl/example.com.svg" alt="SSL certificate status for example.com, checked by A2Z Tools" height="22">
</a>

Badges state only what was observed ("valid, 43 days left", "5 / 6", "p=reject") and never claim a site is "secure". If A2Z cannot run a check the badge turns grey and says "unavailable" - it is never red because of a problem on A2Z's side. Results are cached for six hours (five minutes for online). The public reports at /report/... are not indexed by search engines.

React

export function EmiWidget() {
  return (
    <iframe
      src="https://a2z.tools/embed/w/emi-calculator?theme=auto&currency=INR"
      title="EMI Calculator by A2Z Tools"
      style={{ border: 0, width: "100%", height: 560 }}
      loading="lazy"
      allow="clipboard-write"
    />
  );
}

With auto height: load https://a2z.tools/embed.js once (for example in your root layout), render <div data-a2z-widget="emi-calculator" />, and call window.A2ZEmbed?.scan() in a useEffect after it mounts.

Next.js

import Script from "next/script";

export default function Page() {
  return (
    <>
      <div data-a2z-widget="world-clock" data-theme="auto" />
      <Script src="https://a2z.tools/embed.js" strategy="lazyOnload" />
    </>
  );
}

Vue

<template>
  <div data-a2z-widget="bmi-calculator" data-units="imperial" ref="w"></div>
</template>
<script setup>
import { onMounted, ref } from "vue";
const w = ref(null);
onMounted(() => window.A2ZEmbed && window.A2ZEmbed.scan(w.value.parentNode));
</script>

Add <script async src="https://a2z.tools/embed.js"></script> to index.html.

Angular

Add the loader to index.html, put <div data-a2z-widget="json-formatter"></div> in a template, and in ngAfterViewInit call (window as any).A2ZEmbed?.scan(). For a plain iframe, bind the URL with DomSanitizer.bypassSecurityTrustResourceUrl only for the fixed https://a2z.tools/embed/w/... address.

Platforms

WordPress

Block editor: add a Custom HTML block and paste the code. Classic editor: switch to the Text tab and paste. Both the iframe and the loader work on self-hosted WordPress; WordPress.com plans without plugins allow the iframe only.

Wix

Add → Embed Code → Embed HTML, choose "Code", paste the iframe code and resize the box. Wix places embeds in its own frame, so use the Simple embed and set the height in the code.

Squarespace

Add a Code block, paste the code and make sure "Display source" is off. The loader works on plans that allow JavaScript in Code blocks; otherwise use the iframe.

Webflow

Drag an Embed element onto the page and paste either version. Publish to see it - the Designer canvas does not run embedded scripts.

Shopify

Online Store → Customize → add a Custom Liquid section (or a "Custom HTML" block in your theme) and paste the code. For a product page, add it to the product template.

Ghost

In the editor, add an HTML card and paste the code.

Blogger

In a post, switch to HTML view and paste; for the sidebar, Layout → Add a Gadget → HTML/JavaScript.

Drupal

Use a text format that allows iframe (Full HTML), or add a custom block with the code. If your filter strips iframes, allow <iframe src title width height style loading allow> for that format.

Joomla

Toggle the editor to code view (or use a Custom module) and paste. If TinyMCE removes the iframe, add iframe to the allowed elements in the editor's plugin settings.

Plain HTML

Paste the code wherever the widget should appear. For the loader, the script tag can go at the end of the page and serve every placeholder on it.

Registry API

The widget list is public JSON (CORS enabled), useful for plugins and integrations:

  • GET /api/widgets - all widgets with name, category, embed URL, default height and supported options.
  • GET /api/widgets/{slug} - one widget.
  • GET /api/widgets/categories - categories with counts.

Attribution

Each widget shows a small "Powered by A2Z Tools" link inside its own frame. Your page receives no hidden links, no keyword-rich anchors and no scripts that insert links. A link from your site is welcome if a widget helps your readers, but it is never a condition of use. Badge snippets link to their public report with rel="nofollow".

Availability and failures

A widget that cannot load shows a short message inside its own frame; it can never break the rest of your page. Live data (exchange rates, website checks) is cached on A2Z's server and labelled with its time; when a source is unavailable the widget says so instead of showing an old or invented number. Widget files are served with long-lived caching, and the frame pages are small and cacheable.