Embeddable widget
Drop-in connect UI, so you don't build the DNS setup screen yourself.
The widget is the whole last mile of a custom-domain setup as one script tag: provider detection, the record written the way that provider's form wants it, step-by-step instructions, the provider's own gotchas, one-click setup where it's available, and automatic polling until the domain goes live.
<div id="domain-setup"></div>
<script src="https://domainee.dev/widget.js"></script>
<script>
Domainee.mount('#domain-setup', {
token: '<connect session token from your server>',
onVerified: function (domain) {
window.location.reload();
},
});
</script>
Getting a token
Never put an sk_live_ key in a browser. It is workspace-wide and anyone
can read it in devtools. The widget refuses to start if you pass one.
Instead, mint a connect session on your server. It is scoped to one domain, expires quickly, and can only reach that domain's setup endpoints:
curl -X POST https://api.domainee.dev/v1/domains/$DOMAIN_ID/connect-session \
-H "Authorization: Bearer $DOMAINEE_API_KEY" \
-H "content-type: application/json" \
-d '{ "ttlSeconds": 3600 }'
{
"connectSession": {
"token": "dmn_cs_eyJ3Ijoi…",
"expiresAt": "2026-09-09T18:36:15.000Z",
"domainId": "8f09b47c-…",
"hostname": "acme.com"
}
}
Hand token to the browser. The widget reads the domain id out of it, so you
don't pass one separately.
What the token can do
Only these, and only for its own domain:
GET /v1/domains/{id} | read status |
GET /v1/domains/{id}/instructions | the setup steps |
POST /v1/domains/{id}/check | re-probe DNS |
POST /v1/domains/{id}/dns/apply | write records with a customer token |
Everything else returns 403, including listing domains, deleting one,
touching a different domain, and minting another session. The allowlist is
enforced centrally, so a route added later is not reachable by default.
Tokens are signed rather than stored, so they cannot be revoked before they
expire. Keep ttlSeconds short. The default is one hour; the maximum is 24.
Options
| Option | Required | Notes |
|---|---|---|
token | yes | The connect session token. |
apiBase | Defaults to https://api.domainee.dev. | |
hostname | Shown while the first request is in flight. | |
onVerified | Called once when the domain goes live. |
mount() returns { destroy(), refresh() }. Call destroy() when unmounting
in a single-page app, or the poll keeps running.
Behaviour
- Polls every 15 seconds and stops as soon as the domain verifies.
- Where the provider supports Domain Connect, the widget shows a one-click button instead of records to copy.
- If provider detection fails, it still shows correct generic records rather than an error.
- An expired token renders "this setup link has expired" rather than a blank panel, so mint a fresh one on page load.
Styling
Styles are inlined, so the widget can't restyle your page and your CSS can't
break it. There is deliberately no theming API yet. If you need the setup UI
to match your product exactly, build it against
GET /v1/domains/{id}/instructions,
which returns everything the widget renders.