---
name: terudo-elements
description: Add a Terudo travel eSIM offer to a website or web app with Terudo Elements (booking confirmation, visa approval, trip or destination page, customer area). Use when the user mentions Terudo, Terudo Elements, selling or offering eSIMs to travellers on their site, or a pk_live_/pk_test_ Terudo key.
---

# Terudo Elements

Terudo Elements are drop-in pieces of Terudo's eSIM shop, rendered in the partner's page (no iframe), paid on Terudo's hosted checkout. Script: `https://terudo.com/elements/v1.js`. Full reference: https://terudo.com/developers/docs/elements.md (or the `terudo-docs` MCP server, `read_doc elements`).

## Rules

- Only a publishable key (`pk_live_…`, `pk_test_…`) goes in a page or a client bundle. A secret key (`sk_…`) never does: it stays in server code and environment secrets.
- Never display net prices, commissions or credit to travellers. Elements never receive them; do not fetch them with a secret key to show them.
- While developing, use `pk_test_terudo_demo_public` (renders real data, checkout disabled) or the partner's own `pk_test_…` key (simulated payment). Switch to `pk_live_…` only when asked.
- Pass what the page already knows: destination (ISO code like `MA`, or a region like `EU-35`), arrival and departure (`YYYY-MM-DD`), the traveller's email, a return URL. Do not ask the traveller again.
- A `returnUrl` from the page is only honoured when its origin is listed on the publishable key, or when it comes from an element session. Tell the user to list their site in the portal (Développeurs).

## 1. Choose the element from the page

| Page | Element | Required options |
| --- | --- | --- |
| Booking or payment confirmation | `booking-banner` | `destination`, `start`, `end` |
| Visa approved, itinerary, trip page | `trip-offer` | `destination`, `start`, `end` |
| Country or destination guide | `plans` | `destination` (+ `days` for daily plans) |
| Shop or "eSIM" menu | `destination-picker` (+ `plansInto`) | none |
| Customer area / "My trip" | `esim-status` | `esimId` (the order's `esim.id`) |
| Email, SMS, chat, native app screen | No element: server-side quote + order, send `checkout_url` | See the terudo-api skill |

## 2. Load and mount

Plain HTML or server-rendered templates: declarative.

```html
<script src="https://terudo.com/elements/v1.js" data-key="pk_test_terudo_demo_public" data-locale="en" defer></script>
<div data-terudo="booking-banner" data-destination="MA" data-start="2026-12-03" data-end="2026-12-09" data-email="…" data-return-url="…"></div>
```

Frameworks (React, Next.js, Vue, Angular, Svelte): load the script once WITHOUT `data-key`, then `Terudo({ key, session, locale, appearance }).mount(name, element, options)` in the component's mount hook, and `handle.update(options)` when props change. Patterns in `references/frameworks.md`. In a single-page app using declarative tags, call `window.terudo.autoMount()` after each route change.

Generate exact code with the docs MCP tool `elements_snippet` (element, framework, destination, dates, key) or `terudo snippet <element> --framework react`.

## 3. Optional: element session (server)

To apply the partner's client discount, prefill a trusted email, reference, trip and return URL, create a session on the server with the secret key at page render time and pass `client_token`:

```http
POST https://terudo.com/api/partner/v1/element_sessions
Authorization: Bearer sk_…
{ "reference": "<booking id>", "client_email": "…", "discount_percent": 5,
  "trip": { "destination": "MA", "start_date": "2026-12-03", "end_date": "2026-12-09" },
  "return_url": "https://…/bookings/<id>", "locale": "fr" }
→ { "client_token": "…", "expires_at": "…" }   (valid 2 hours)
```

Script: `data-session="<client_token>"`, or `Terudo({ session })`. If session creation fails, still render the element without it.

## 4. Brand it

Set `--tdo-color`, `--tdo-on`, `--tdo-radius`, `--tdo-font` on the host (or `appearance: { color, onColor, radius, font }`). Use the site's existing brand colour token, not a new hard-coded colour, when the codebase has one.

## 5. Callbacks

`onSelect`, `onCheckout(order)` (return `false` to stop the redirect and open `order.checkout_url` yourself), `onOpen(quote)` (booking-banner), `onLoad(esim)` (esim-status), `onError(error)` (`error.code`). Wire `onCheckout` to the site's analytics if it has one.

## 6. Verify before finishing

- [ ] No `sk_` string anywhere in client code, templates or bundles.
- [ ] The element renders with the demo or test key (open the page, or describe how to).
- [ ] Destination and dates come from the page's real data, in `YYYY-MM-DD`.
- [ ] CSP (if any) allows `https://terudo.com` in `script-src`, `connect-src`, `img-src`.
- [ ] The publishable key and secret key are read from configuration (env), not hard-coded, except the public demo key in examples.
- [ ] Tell the user the go-live steps: live keys in the portal, list the site on the publishable key.
