Customization
The widget ships with Osigu's default theme, but you can align it with your host app's brand in three ways: theme presets, CSS variables, and behaviour hooks.
Theme presets
The simplest control: pick light, dark, or auto via the theme option.
OsiguPreAuth.mount({ theme: 'auto', /* ... */ });
auto respects the user's prefers-color-scheme media query.
CSS variables
For fine-grained control, override the CSS variables the widget exposes. Set them on the host element (or globally on :root):
#osigu-preauth {
--osigu-color-primary: #4f46e5; /* buttons, links */
--osigu-color-primary-fg: #ffffff; /* text on primary */
--osigu-color-bg: #ffffff; /* widget background */
--osigu-color-fg: #0f172a; /* main text */
--osigu-color-muted: #64748b; /* secondary text */
--osigu-color-border: #e2e8f0; /* borders */
--osigu-color-success: #16a34a;
--osigu-color-warning: #d97706;
--osigu-color-danger: #dc2626;
--osigu-radius-sm: 4px;
--osigu-radius-md: 8px;
--osigu-radius-lg: 12px;
--osigu-font-family: 'Inter', system-ui, sans-serif;
--osigu-font-size-base: 14px;
--osigu-spacing-unit: 4px;
}
Dark mode: nest under [data-theme='dark']:
[data-theme='dark'] #osigu-preauth {
--osigu-color-bg: #0f172a;
--osigu-color-fg: #e2e8f0;
/* ... */
}
The widget automatically applies data-theme='dark' on its own root when theme: 'dark' or when theme: 'auto' resolves to dark. Your CSS can piggy-back on that attribute.
What you can't restyle
To keep the widget accessible and to protect the sponsor-required UX (e.g. the OTP challenge, biometric capture), some things are locked:
- Step ordering (search → products → indication → review).
- OTP challenge modal (renders in an iframe hosted by Osigu, styled from within).
- Error state layout.
- Legal fine-print (sponsor consent language, GDPR notice).
If you need to move a step or reorder the flow, the widget isn't the right fit — wire the REST API instead.
Locale customisation
If you want the widget in a language other than the three we ship (en, es, pt-BR), file a request with support@osigu.com. We do not support ad-hoc translations passed in via config, because translation quality and sponsor legal-text accuracy matter.
Behaviour hooks
Two hooks let you inject logic without forking the widget:
beforeSubmit
Called right before the widget POSTs to /authorization-requests. Return a mutated payload, or false to cancel.
hooks: {
beforeSubmit: async (payload) => {
// Attach an internal case number
payload.additional_data = { ...payload.additional_data, case_id: mySession.caseId };
// Or gate on your own business rules
if (payload.products.some((p) => p.quantity > 100)) {
showConfirmDialog('Bulk quantity — are you sure?');
const confirmed = await confirmed$;
if (!confirmed) return false;
}
return payload;
}
}
decorateSearchResult
Post-process each beneficiary that comes back from the sponsor search, before the user sees it. Useful for stamping internal identifiers on the search result cards.
hooks: {
decorateSearchResult: (b) => {
const local = localPatientDb.getBy(b.document_number);
return { ...b, meta: { local_id: local?.id, last_visit: local?.last_visit } };
}
}
Multiple widgets on the same page
You can mount more than one widget on the same page — they don't share state. Give each a different container. Common case: a "quick pre-auth" widget on a doctor's dashboard next to a "quick prescription" widget.
Related
- Configuration — the option list including all hooks.
- Events — what the widget emits when hooks trigger flow changes.