The website widget puts an organization's appointment service on its own website. A visitor clicks a launcher and the chosen form – appointment request, direct booking, digital waiting room or sending documents – opens in a dialog on the same page. You install it with one <script> tag; there is no iframe to size and no event to handle.

What the widget offers and how it looks is configured by the organization owner in MeetOne, not in the embed code. See Set up the website widget.

Prerequisites

  • The website widget is enabled for the organization, and the owner has switched on Show the widget on my website.
  • The snippet from Organization › Integrations › Website widget › Embedding it on your website. It contains the organization's tenant domain and its token.
  • The website is served over HTTPS.

Getting the snippet

Copy the snippet from the settings page rather than building it by hand. It looks like this:

<script src="https://[your-tenant-domain]/widget/v1.js"
        data-meetone-token="[TOKEN]"
        async></script>

The token is a public identifier, not a credential: it is the same token that appears in the organization's public booking links, and it only lets a visitor do what they could already do on those public forms. It is unrelated to API tokens.

Placement

Floating launcher

Paste the snippet once, before the closing </body> tag. A button appears in the bottom corner of every page (right or left, as configured).

Inline card

Put a container exactly where the widget should sit in the page content, followed by the snippet. The floating launcher then steps aside.

<div data-meetone-widget></div>
<script src="https://[your-tenant-domain]/widget/v1.js"
        data-meetone-token="[TOKEN]"
        async></script>

Several <div data-meetone-widget> containers on one page each get their own card. The script itself only needs to appear once; including it twice is harmless.

Both

To show the inline card and the floating launcher together, add data-meetone-widget-floating="true" to the script tag.

Mobile requirements

The settings page lists two additions for the host page, so the dialog displays correctly on phones — the viewport tag keeps it usable when the on-screen keyboard opens:

<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, interactive-widget=resizes-content">
html {
  -webkit-text-size-adjust: none;
  text-size-adjust: none;
}

Always copy the current values from the settings page – they take precedence over this article.

Content Security Policy

If the website sets a Content Security Policy, allow the MeetOne tenant domain in these directives:

script-src  https://[your-tenant-domain];
connect-src https://[your-tenant-domain];
frame-src   https://[your-tenant-domain];

script-src loads the widget, connect-src fetches the organization's widget settings and the widget's stylesheet, and frame-src allows the dialog.

If the policy also restricts styles or images — for example through default-src 'self' — additionally allow style-src 'unsafe-inline' and img-src https://[your-tenant-domain]: the widget adds its own <style> element to the page and loads the team's profile pictures from the tenant domain. Nothing has to be installed or built on your side.

How it behaves on the page

  • Style isolation in both directions. The widget renders inside a shadow root: the site's CSS cannot restyle the widget, and the widget's CSS cannot leak into the site.
  • Light until the first click. On page load the widget fetches one cached script, the organization's settings and the widget's stylesheet, and loads the team's profile pictures if they are shown. Once the page has finished loading, it also opens a hidden iframe to the tenant domain to warm up the dialog. The visible dialog is created on the first click.
  • Keyboard accessible. The dialog is announced as a modal; focus moves to the close button on open and back to the launcher on close; Escape closes it. While focus is inside the form, the browser does not pass Escape from the cross-origin frame to your page – the always-visible close button is the way out.
  • Reduced motion. The launcher's hover animation is switched off under prefers-reduced-motion: reduce.
  • Small screens. At 640 px and below, the dialog spans the full width and docks to the bottom edge; it grows with its content, up to the height of the screen.
  • Fails silently. If the widget is switched off or its settings cannot be loaded, it renders nothing and writes a single console.warn. It never throws into the host page.
  • Single-page apps and page builders. If the page re-renders the contents of its <body>, the widget re-attaches itself. If the <body> element itself is swapped out — as Turbo Drive does, for example — the widget is gone until the next full page load.

Settings changes go live without redeploying

The script URL is stable and the organization's settings are fetched separately. Changes the owner makes – functions, wording, colors, position – reach visitors within about a minute. Switching the widget off makes the embedded script a no-op; nothing has to be removed from the website.

Troubleshooting

Symptom Cause
Nothing appears; the console warns that the widget is not active The widget is switched off, not enabled for the organization, or no function is selected.
Nothing appears; the console warns that the widget could not be loaded (HTTP 404) The data-meetone-token is wrong. Copy the snippet again from the settings page.
Nothing appears; the console reports a blocked resource The Content Security Policy does not allow the tenant domain in script-src or connect-src.
The launcher appears unstyled, in the page flow instead of the corner The Content Security Policy blocks inline styles (style-src).
Nothing appears, no console message The script tag has no data-meetone-token.
The launcher shows, and clicking it opens an empty dialog frame-src is missing from the Content Security Policy.
Send documents is missing The organization's secure inbox upload link is disabled.

Questions? Contact us at support@meetone.io.