Skip to content

Framework integrations

In single-page applications, container elements are created after the page has loaded; so you need to load the loader once and call mount/unmount in every component. The examples below follow the same pattern: load the script (if needed) → mount the container → unmount when the component is removed. To write less code you can use the custom elements or the SDK components in the last three tabs.

import { useEffect, useRef } from 'react';
const LOADER = 'https://api.mirac-ozdemir.com/widget.js';
let loading: Promise<void> | null = null;
function loadWidget(): Promise<void> {
if (window.MiracOzdemirWidget) return Promise.resolve();
loading ??= new Promise((resolve, reject) => {
const script = document.createElement('script');
script.src = LOADER;
script.async = true;
script.onload = () => resolve();
script.onerror = () => reject(new Error('Failed to load widget.js'));
document.head.append(script);
});
return loading;
}
export function Calculator({ tool, locale = 'tr' }: { tool: string; locale?: 'tr' | 'en' }) {
const ref = useRef<HTMLDivElement>(null);
useEffect(() => {
const node = ref.current;
if (!node) return;
let active = true;
loadWidget().then(() => active && window.MiracOzdemirWidget?.mount(node)).catch(console.error);
return () => {
active = false;
window.MiracOzdemirWidget?.unmount(node);
};
}, [tool, locale]);
return <div ref={ref} data-mo-tool={tool} data-locale={locale} />;
}
Platform How
WordPress Add a Custom HTML block in the block editor and paste the installation code. If the script is filtered, add <script … async> to the theme’s footer.php and leave the container in the post.
Webflow / Wix / Squarespace Paste the container and the script together into an Embed / HTML element. If the script is blocked, use a plain iframe.
Google Tag Manager Place the container on the page; add only <script src="…/widget.js" async></script> to a Custom HTML tag. Even if the tag runs after the page has loaded, the loader scans by itself.
Markdown / static site If it allows HTML, write the container and the script directly. In Astro/Hugo/Jekyll, add the script at the end of the template.
Email Not supported (scripts and iframes do not work in email). Link to the tool page instead.
  • When a component changes tool or locale, unmount the widget and mount it again (the React example above does this with the dependency array), or call update(el, { tool, locale }). Options such as theme, accent colour, radius, density, title and view need no rebuild: update applies them without reloading the iframe. To follow your page’s theme use data-theme="inherit".
  • To feed prefilled values from form state use setInputs(el, values); to get the result on demand use await calculate(el).
  • There is no window during server-side rendering (SSR); mounting must be done only on the client.
  • You can put a fallback link inside the container in SSR; after hydration the widget replaces it with the iframe. In some frameworks, if the framework itself manages this child element, it may give a warning; in that case leave the container empty and put the fallback link next to it.