Embed overview
Add a floating agent to an existing website with a secure, framework-independent loader.
Add a floating agent to an existing website with a secure, framework-independent loader.
How the embed works#
embed.js adds one fixed launcher to the host document. The visitor's first click reveals a lazy-loaded iframe from https://makeagent.fast; the agent and conversation remain isolated from the host page inside that frame. Host CSS cannot restyle the chat, and agent content cannot rewrite the host document.
The loader is public and does not use an API key. Access is controlled by the site's published state, its Enable embedding switch, and the exact parent-origin allowlist. The site slug is an identifier, not a secret.
Prerequisites#
Before copying code:
- Create and test an agent in the dashboard.
- Publish the site that owns it.
- Open the site's Embed page and turn Enable embedding on.
- Add every parent origin that will render the launcher.
- Save, then copy the generated snippet.
An origin contains only the scheme, hostname, and optional port. It never contains a path. These are four different origins and must be added separately when you use them:
https://example.com
https://www.example.com
https://staging.example.com
http://localhost:3000Do not enter https://example.com/pricing, *.example.com, or a trailing wildcard. If production redirects from the bare domain to www, allowlist the origin that remains in the browser address bar after the redirect.
Install the loader#
Place one script before the closing </body> tag, or use the browser-only lifecycle recommended by your framework guide.
<script
src="https://makeagent.fast/embed.js"
data-agent="YOUR_SITE_SLUG"
data-position="right"
data-label="Ask us"
data-accent="#6d5ce7"
data-locale="en"
data-theme="light"
async
></script>Only data-agent is required. Do not put a MAF API key, provider key, connector token, visitor identity, or private customer data in any data-* attribute.
Configure attributes#
| Attribute | Accepted value | Default | Effect |
|---|---|---|---|
data-agent | Published site slug | Required | Selects the site and agent to load |
data-position | left or right | right | Anchors the launcher and panel |
data-label | Plain text | Icon only | Adds visible text and supplies the launcher label |
data-accent | CSS color such as #6d5ce7 | Site appearance | Overrides the launcher background |
data-locale | Supported locale such as en or ko | Site/browser behavior | Requests the widget UI language |
data-theme | light or dark | Host/OS detection | Pins the initial widget theme |
Without a theme override, the loader samples the host background and then falls back to the visitor's OS preference. It also passes the host font family to the frame and fetches the latest launcher appearance. A failed appearance request does not block the launcher; it keeps the safe default style.
Runtime behavior#
- Load the script once per document. Repeating the same slug is idempotent and still produces one
maf-embed-root-YOUR_SITE_SLUGroot. - Different agents may coexist on one document. The loader marks each processed script with
data-maf-bootstrappedso an async fallback initializes every distinctdata-agenttag exactly once. - The iframe is lazy and hidden until the visitor opens it. It requests microphone, autoplay, and clipboard-write permission only through the browser's iframe permission model.
- In a client-side routed app, mount the loader in the highest layout that should own it so route changes do not reload the conversation.
- Removing only the script element does not remove an already-created launcher. For route-specific teardown, also remove the matching
maf-embed-root-...element. Reload the script after teardown to mount it again. - The frame and loader exchange only namespaced lifecycle messages. The loader rejects messages that do not come from the Make Agent Fast origin and current site slug.
Verify the installation#
Test the public page, not only a website-builder editor preview:
- Open the deployed URL in a private window and confirm its exact origin is allowlisted.
- Confirm
https://makeagent.fast/embed.jsreturns200in the Network panel. - Confirm a single element with
data-maf-embed="YOUR_SITE_SLUG"exists. - Open the launcher and confirm the iframe request to
/embed/YOUR_SITE_SLUGsucceeds. - Send a realistic question and confirm it appears in Conversations.
- Test a narrow mobile viewport and, if enabled, microphone permission.
Diagnose a missing launcher#
| Symptom | Likely cause | Fix |
|---|---|---|
Console warns missing data-agent | The slug attribute is absent or on a different script | Put data-agent on the embed.js tag |
embed.js is blocked | CSP or a consent manager rejected the script | Allow the script origin or load it after the required consent |
| Launcher appears but the frame refuses to load | Site is unpublished, embedding is off, or parent origin differs | Recheck all three values in the dashboard |
| Works on localhost but not production | Only the development origin is allowlisted | Add the exact deployed HTTPS origin |
| Two different agents appear | The document loads two different slugs | Keep only the intended site slug |
| Chat opens but voice does not | Browser permission or Permissions Policy blocks microphone | Follow Security and CSP |
Choose an installation guide#
Use HTML and JavaScript for a normal script tag. For React, Vue, SvelteKit, Astro, or a website builder, choose the matching guide in the sidebar. Platforms that do not allow arbitrary JavaScript, such as many Notion and Linktree surfaces, should link to the published hosted agent instead.