Skip to content

Installation

  1. Place a container. Put an element carrying data-mo-tool where you want the calculator to appear. The value is the tool’s key.

    <div data-mo-tool="kdv"></div>
  2. Add the loader. Once per page, preferably at the end of the body:

    <script src="https://api.mirac-ozdemir.com/widget.js" async></script>
  3. Done. When the page loads, the loader replaces the container with an iframe.

You can put a fallback link inside the container (visible if the script does not load). The loader replaces the container’s existing content with the iframe:

<div data-mo-tool="kdv">
<a href="https://mirac-ozdemir.com/tr/araclar/kdv-hesaplama">Open the VAT calculator</a>
</div>

You can also write the same container as a custom element (<mo-calculator tool="kdv">): Custom elements and SDK. For a search box and a category list see Widget kinds.

The attributes below are for a data-mo-tool (calculator) container. The extra attributes of the search and category widgets are on the Widget kinds page.

Attribute Values Default Description
data-mo-tool Tool key: ^[a-z0-9]+(-[a-z0-9]+)*$, 2–64 characters required The key of the tool to embed.
data-locale tr, en tr Interface language. If the tool is not published in that language, the widget shows “not found”.
data-theme auto, light, dark, inherit auto auto follows the visitor’s system theme; inherit follows your page’s theme (see below).
data-header true/false (1/0, yes/no) true false hides the tool title; useful when you use your own heading.
data-height Integer px, clamped to 120–10000 remembered height, else 480 The initial height; it then adjusts to the content automatically.
data-accent 6 hex digits, # optional (0a7d5a) site colour Primary colour; the text colour on it is derived from its luminance.
data-radius none, sm, md, lg md Corner radius scale.
data-density comfortable, compact comfortable Spacing scale.
data-view full, result full result shows only the result panel: Widget kinds.
data-autorun true/false false Calculates right after the inputs are applied.
data-input-<field> prefilled value (≤ 64 characters) none Fills a single input (see below).
data-inputs JSON object none Fills several inputs.
data-title text (up to 200 characters) localized title The iframe’s title attribute (accessibility).
data-lazy true/false true false loads the iframe eagerly.

An invalid value is written to the console as an English console.warn and that container is skipped (e.g. [MiracOzdemirWidget] Invalid data-locale value: "de" (expected one of: tr, en)). Values are validated against strict allow-lists; if you generate the options dynamically from elsewhere, be aware of this behaviour.

To fill the form on load, use data-input-<field> attributes. <field> is the name of the tool’s input field (the field name in the tool definition); in the attribute it is written in kebab-case and the loader converts it to camelCase (data-input-vat-rate-option → vatRateOption).

<div
data-mo-tool="kdv"
data-input-amount="1000"
data-input-mode="exclusive"
data-input-vat-rate-option="standard"
data-autorun="true"
></div>

You can give the same values as JSON; if both are used, the data-input-* values override those in the JSON:

<div data-mo-tool="kdv" data-inputs='{"amount":"1000","mode":"exclusive"}' data-autorun="true"></div>

Rules:

  • Values use the same canonical format as calculation requests: decimals as strings ("1234.56"), booleans true/false, enums as the option key, dates YYYY-MM-DD.
  • At most 50 fields, each value at most 64 characters. Field names must match ^[a-z][A-Za-z0-9_]{0,63}$.
  • Unknown fields and invalid values are silently ignored (the same rule as share links); the widget still opens.
  • data-autorun="true" runs the calculation by itself once the inputs are applied; the mo:result event arrives after that calculation.
  • An invalid data-inputs (not a JSON object) logs a warning and the container is skipped.

To provide values later, use setInputs.

data-theme="inherit" takes the widget’s theme from your page. The loader checks, in order: a data-theme, data-bs-theme or data-color-mode attribute (light/dark) on the container or its ancestors, a dark/theme-dark/dark-mode (or light/theme-light/light-mode) class, then the computed color-scheme, and finally prefers-color-scheme. If your page’s theme changes at runtime (those attributes/classes change on <html> or <body>, or the system theme changes), the widget is updated without reloading the iframe.

While the iframe loads, the loader draws a skeleton placeholder in the container and keeps the iframe invisible until it is ready, so the content is not pushed down. The initial height is determined in this order: data-height if given; otherwise the last measured height for the same {tool, locale, view} (kept in your site’s localStorage under a mo-widget-h:… key, best effort); otherwise 480.

  • If you want no shift at all, give the tool’s typical height with data-height.
  • data-lazy="false" loads the iframe immediately (for widgets near the top of the page).
  • The loader also adds a <link rel="preconnect"> to the site origin; the first load gets faster.
  • If the container’s position is static, the loader sets it to relative (for the placeholder).

You can put as many widgets as you like on the same page; adding the loader once is enough. If you add the script twice by accident, the second load only rescans; no duplicate widgets are created.

<div data-mo-tool="kdv" data-height="520"></div>
<div data-mo-tool="gelir-vergisi-hesaplama" data-theme="dark" data-accent="0a7d5a"></div>
<script src="https://api.mirac-ozdemir.com/widget.js" async></script>

The loader scans once when the page loads. If you add containers later (with a framework, with AJAX), mount them with window.MiracOzdemirWidget:

container.setAttribute('data-mo-tool', 'kdv');
window.MiracOzdemirWidget.mount(container); // returns the iframe, or null if invalid

Call unmount(container) before removing the container. To change options afterwards you usually do not need unmount: update. Framework examples: Framework integrations.

The loader creates the iframe with these attributes (for accessibility and security):

  • title: localized, e.g. Calculator: kdv (tr: Hesaplama araci: kdv); or your data-title. When the iframe becomes ready, and unless you gave data-title, it is replaced with the tool’s title.
  • width="100%", loading="lazy" (eager with data-lazy="false")
  • referrerpolicy="strict-origin-when-cross-origin"
  • sandbox="allow-scripts allow-same-origin allow-forms allow-popups allow-popups-to-escape-sandbox"
  • Style: width:100%; border:0; display:block; height:<px>; opacity:0 until ready
  • Your page must be served over HTTPS (mixed content is blocked).
  • If your page has a Content-Security-Policy, allow the script and iframe sources: Security and CSP.
  • No cookies or user registration are needed.
  • To pin the script to a fixed version with an integrity (SRI) check: Versioning policy.