Embed documentation

Everything you need to put A2Z widgets on a website or app: Smart Embed (auto height, recommended), the Simple Embed iframe, every URL parameter, events, security headers, and step-by-step instructions for common platforms and frameworks. All 505 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 Smart Embed code (selected by default) and paste it into an HTML / custom-code block on your page. If your site builder strips or sandboxes scripts, use the Simple Embed tab instead.

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

Advertisement

Smart Embed (auto height) - recommended

Smart Embed is the default on every widget page. A small loader (about 4 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. Several widgets on one page share the one script.
  • Each widget still runs in its own isolated iframe; the loader never injects anything else into your page and sets no cookies.
  • It tells each widget the address of the page it is on - origin and path only, never the query string, #fragment or login details - so A2Z can show where a widget is used (see Privacy). data-analytics="off" on the script tag, Do Not Track and Global Privacy Control switch this off.
  • 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

Simple Embed (iframe)

The fallback: a plain iframe with a fixed height. It works on every platform, including those that remove or sandbox <script> tags (Wix Embed HTML, Google Sites).

<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.

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 two messages, only from its direct parent: { a2z: "embed", t: "theme", theme: "light" | "dark" | "auto" }, and { a2z: "embed", t: "ctx", p } - the page address the official loader sends once, which the widget keeps only when its origin matches the parent's. 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. It sends the page context only to those iframes, addressed to the A2Z origin.
  • A widget accepts the page context only from its direct parent window, and keeps the address only when its origin is the one the browser itself reports for that parent.

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 totals per widget, day and event (loaded, shown, used) and where the widget is shown: the embedding site's host name and, where the browser or the loader makes it known, the page address reduced to origin and path - without query string, #fragment or login details, and with path parts that look personal or secret (email addresses, tokens, long numbers, the part after /user/, /reset/, /order/...) removed. No IP addresses, user agents, cookies or identifiers are stored. To estimate unique visitors, the server hashes the IP address and user agent with a random salt that exists only in memory for one day; the hash itself is never stored.

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.

Page Kit: components that live on your page

Some website essentials cannot work inside a frame. A frame cannot see the address of the page around it (browsers send only your site's domain), cannot float over your content, cannot scroll your page and cannot read your headings. Share buttons, floating contact buttons, back-to-top, reading progress and an automatic table of contents therefore use the A2Z Page Kit instead of an iframe:

<div data-a2z-kit="social-share-buttons" data-networks="facebook,x,linkedin,whatsapp,copy" data-layout="float-left"></div>
<script async src="https://a2z.tools/embed/kit.js" referrerpolicy="no-referrer"></script>
  • Isolated. Each component is drawn inside a Shadow DOM attached to your placeholder (or, for floating components, to a small element the kit adds at the end of <body>). Your CSS cannot distort it and its CSS cannot touch your page. Text inherits your page's font.
  • Options are data-* attributes on the placeholder; the builder on each widget page writes them for you. Common ones: data-theme="auto|light|dark|inherit" (auto reads the background behind the component), data-accent="#4b5bd6", data-analytics="off", data-datalayer="on" (where a widget offers it, it pushes its events into your own Google Tag Manager or GA4 dataLayer).
  • What it loads. kit.js, then only what the component needs from https://a2z.tools/embed/kit/: the component, one or two small stylesheets, the network list and the icon set it draws. A typical share bar is about 25 KB compressed. No social network, advertising or tag-manager script is ever loaded, and no cookies are set.
  • Which page is shared. The address you fix in the builder; otherwise your <link rel="canonical"> (unless it points at your home page from a deeper page); otherwise the address in the browser without its #fragment and without advertising parameters such as utm_*, fbclid and gclid.
  • Single-page apps. The kit watches the page: placeholders your router adds are drawn, and floating components disappear with their placeholder. Share links are rebuilt at the moment of the click, so they always use the current address. window.A2ZKit.scan() forces a re-scan.
  • Content-Security-Policy. If your site sends one, allow script-src https://a2z.tools and style-src https://a2z.tools.
  • Counting. A2Z counts totals: which component loaded on which page (origin and path only, redacted as described under Privacy), and which button was pressed (for example "facebook" or "copy"). Never the query string, share text, phone numbers, email addresses or anything a visitor types - and every request the kit makes to A2Z, including the script tag in the code, is sent without a Referer header. data-analytics="off", the browser's Do Not Track setting and Global Privacy Control switch counting off entirely.
  • No JavaScript? Anything you put inside the placeholder is shown until the kit draws the component (and stays if scripts are blocked) - for example plain links to your social profiles.

Some kit components that show content rather than act on the page (follow icons, profile cards, review grids, size charts) can also be embedded as a plain iframe; their builder shows an Iframe tab.

React

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

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"
    />
  );
}

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. Smart Embed works on self-hosted WordPress; WordPress.com plans without plugins remove scripts, so use the Simple Embed there.

Wix

Add → Embed Code → Embed HTML, choose "Code", paste the code and resize the box. Wix runs embed code inside its own fixed-size frame, so auto height cannot grow the box: use the Simple Embed and set the height in the code.

Google Sites

Insert → Embed → Embed code, paste the code and resize the box. Google Sites runs embed code inside a sandbox frame on googleusercontent.com with a fixed size, so use the Simple Embed and set the height. (This is also why A2Z's statistics show such placements as "Google sandbox".)

Squarespace

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

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. With Smart Embed, the script tag can go once 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. The default embed code also adds one visible line under the widget on your page - "Widget name by A2Z Tools" - linking to the tool with rel="nofollow". It is optional: untick it in the builder or delete the line and the widget works exactly the same. Your page never receives hidden links or keyword-rich anchors, and no script inserts or restores a link. Page Kit components (buttons, bars) add no line. 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.

Advertisement