Embed script
Add an Agoo booking widget or pre-registration form to any website with one script tag and an HTML attribute.
This is designed and scheduled but not built yet. We document it now so you can plan your integration.
The embed script puts your Agoo booking page or visitor pre-registration form inside any web page: a static site, a CMS, or an app built with any framework. You add one script tag and mark where the widget goes. There is nothing to install or build.
Use the React components if your site is built with React and you want the widget rendered in your own page's styles. On WordPress, use the WordPress plugin, which uses this script for you.
Plan access
The embed script works on every plan that has booking pages, in live and test mode. It shows your hosted booking and pre-registration pages from
app.agoo.ardent.africa in a frame, so it doesn't need API access on your plan. The React components, which call the API
directly, need Pro or Enterprise in live mode.
These snippets will work once the script is published.
Add a booking widget
Get a publishable key and a booking type ID
An admin creates a publishable key in Console → Developers → API keys. Use agoo_pk_test_… while you build: test bookings go to your test-mode sandbox and send no messages. The booking type ID (btype_…) is shown on the booking type's page in the console.
A publishable key is safe to put in a web page. It can only read your public booking types and the visitor types open for pre-registration, and create bookings and pre-registrations.
Add the script once per page
<script src="https://js.agoo.ardent.africa/v1/embed.js" defer></script>Mark where the widget goes
<div data-agoo-booking="btype_01jv4dk79q9g8xe6szaeavsntc" data-agoo-key="agoo_pk_test_…"></div>When the page loads, the script finds every element with data-agoo-booking or data-agoo-preregister and renders the widget inside it. The widget sizes its height to its content, so leave the element's height unset.
Add a pre-registration form
The same script renders a pre-registration form for a site. Visitors fill in who they are, who they're visiting and your custom questions, and get their QR pass by SMS, WhatsApp or email.
The form offers only the visitor types an admin has opened for pre-registration in Console → Settings → Forms, and asks only the questions asked of the visitor, never the fields your staff fill in. See Forms and fields.
Without data-agoo-host, visitors search for their host inside the hosted page. Your page and your publishable key never see your staff directory. This is the way to offer host search on your site: the React form needs the host set.
<div data-agoo-preregister="site_01kjpt3yw0fz0v414608h9x65s" data-agoo-key="agoo_pk_test_…"></div>Data attributes
| Attribute | On | Value |
|---|---|---|
data-agoo-booking | Booking widget | The booking type, btype_…. Required for a booking widget. |
data-agoo-preregister | Pre-registration | The site, site_…. Required for a pre-registration form. |
data-agoo-key | Both | Your publishable key, agoo_pk_live_… or agoo_pk_test_…. Required. |
data-agoo-date | Booking widget | The day to show first, YYYY-MM-DD. |
data-agoo-visitor-type | Pre-registration | A visit type key: built-in, such as meeting or contractor, or one your organisation added, such as parent_pickup. It must be open for pre-registration. Omit to let the visitor choose from the types that are. |
data-agoo-host | Pre-registration | Fix the host, person_…. Omit to let the visitor search for their host on the hosted page. |
data-agoo-name, data-agoo-email, data-agoo-phone | Both | Prefill details you already know. The visitor can still edit them. |
data-agoo-theme | Both | light, dark or auto (follows the visitor's system setting). Default light. |
data-agoo-color-primary | Both | A hex colour for buttons and highlights, such as #0b5d4b. Default: your organisation's brand colour. |
Unknown attributes are ignored. An element with a missing or invalid required attribute shows a short message in place of the widget and logs the reason to the browser console.
How it works
The script replaces each marked element's contents with an <iframe> served from https://app.agoo.ardent.africa. The booking or pre-registration form runs inside that frame, with your organisation's branding, privacy notice and custom questions, and talks to Agoo directly. Visitors' answers never pass through your page's scripts.
The frame tells the script its height and what happened, and the script passes that on to your page as events. The script only accepts messages from https://app.agoo.ardent.africa.
Pages that change after loading
The script renders widgets that exist when it runs. If your page adds a widget later, for example in a single-page app or a modal, call Agoo.mount after adding the element:
const el = document.createElement("div")
el.dataset.agooBooking = "btype_01jv4dk79q9g8xe6szaeavsntc"
el.dataset.agooKey = "agoo_pk_test_…"
document.querySelector("#booking-modal").append(el)
window.Agoo.mount(el)Agoo.mount() with no argument renders every marked element on the page that isn't already rendered. Agoo.unmount(el) removes a widget.
Events
The script dispatches CustomEvents on window. Each event's detail includes element, the element the widget is in, so you can tell widgets apart.
| Event | When | detail |
|---|---|---|
agoo:ready | A widget has loaded and is showing | { element } |
agoo:booked | A booking is made | { element, booking_id, status, start_at, end_at }, with status confirmed, or pending when the host must confirm it |
agoo:preregistered | A pre-registration is created | { element, visit_id, status, expected_at }, with status expected or awaiting_approval |
agoo:error | A widget couldn't load or a request failed | { element, code, message }, using the API's error codes |
<script>
window.addEventListener("agoo:booked", (event) => {
const { booking_id, start_at } = event.detail
// Send a conversion to your own analytics (no personal data is included)
window.dataLayer?.push({ event: "agoo_booking", booking_id, start_at })
window.location.href = `/thank-you?ref=${encodeURIComponent(booking_id)}`
})
window.addEventListener("agoo:error", (event) => {
console.warn("Agoo widget error", event.detail.code, event.detail.message)
})
</script>Events carry IDs and times, never the visitor's name, phone number or answers. To act on the full booking or visit, use the booking.created and visit.created webhooks on your server.
Content Security Policy
If your site sends a Content-Security-Policy header, allow the script and the frame it creates:
script-src 'self' https://js.agoo.ardent.africa;
frame-src https://app.agoo.ardent.africa;Merge these sources into your existing script-src and frame-src directives rather than adding second copies. If your policy has no frame-src, browsers fall back to child-src, then default-src: allow https://app.agoo.ardent.africa there instead.
The script at /v1/embed.js receives backwards-compatible fixes without changing its address, so you can't pin it with a fixed integrity hash. A breaking change would ship at a new address (/v2/).
Test mode
With an agoo_pk_test_… key, the widget shows a small "Test mode" label and works on your test-mode sandbox: bookings and pre-registrations are created there, confirmations appear in the console's test outbox, and nothing is sent to the visitor. Swap in your agoo_pk_live_… key when you go live.
Troubleshooting
Check the browser console. The usual causes are a missing data-agoo-key, a typo in the btype_… or site_… ID, or a Content Security Policy
that blocks the script or the frame.
The booking type is private (only public booking types can be booked with a publishable key), or it belongs to the other mode: a test key can't see live booking types, and a live key can't see test ones.
The visit type key in data-agoo-visitor-type is misspelt, or that type is turned off or isn't open for pre-registration. An admin opens a type
for pre-registration in Console → Settings → Forms.
Remove any fixed height or overflow: hidden from the element and its parents. The widget sets its own height.
Add your listeners before the widget finishes, for example in a script that runs before embed.js or at the top of the page. agoo:booked fires
once per booking.