Skip to main content

Widget API: Technical Reference

[api] [widget]

For developers who want to integrate the licensio widget into their website or use the branding endpoints directly.

Embed code​

Minimal HTML snippet:

<script
src="https://<tenant>.licensio.io/widget.js"
data-tenant="<tenant>">
</script>

The widget renders an <a> button in the container <div> right after the script tag. All customizations (text, colors, style, size) are read live from the branding API.

Optional data attributes (override per embed)​

Override for individual embeds (overrides API values):

AttributeValuesPurpose
data-button-textstringlabel
data-colorhex #RRGGBBoverrides branding.widget_button_color
data-text-colorhex #RRGGBBoverrides branding.widget_button_text_color
data-stylesolid | outlineoverrides branding.widget_button_style
data-sizesmall | medium | largeoverrides branding.widget_button_size
data-hrefURLoverrides the default <baseUrl>/join
data-custom-domainstringreserved for own-domain hosting (in preparation)
data-debug"true"enable console logs (for development)

Override order​

Each style property is resolved as follows:

`data-Attribut > branding.widget_button_<X> > branding.<base> > Default`

e.g. for primaryColor:

data-color || branding.widget_button_color || branding.primary_color || '#FF6600'

Branding API​

GET /api/portal/branding​

Cross-origin capable (Access-Control-Allow-Origin: *), no auth required.

Response 200 OK:

{
"branding": {
"primary_color": "#F87627",
"button_text_color": "#ffffff",
"button_style": "rounded",
"company_name": "Plant Technology",
"logo_url": "https://...",
"favicon_url": "https://...",
"font": "Oswald",
"widget_button_text": "Lizenz Portal",
"widget_button_color": null,
"widget_button_text_color": null,
"widget_button_style": "solid",
"widget_button_size": "medium"
}
}

Tenant resolution: via the x-tenant-slug header set by the portal middleware (either a subdomain match or a custom-domain lookup).

Cache: no HTTP cache headers (live from DB). Defaults: widget_button_color falls back to branding.primary_color, widget_button_text to 'Lizenz Portal'.

OPTIONS /api/portal/branding​

CORS preflight. Returns:

Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, OPTIONS
Access-Control-Allow-Headers: Content-Type

Style variants​

Solid​

background: <primaryColor>
color: <textColor>
border: 2px solid <primaryColor>

Outline​

background: transparent
color: <primaryColor>
border: 2px solid <primaryColor>

Responsive size​

Padding + font-size are injected via a <style> tag with a media query. The button gets id="licensio-widget-btn" as its selector.

SizeMobileDesktop (>=750px)
Small4px 10px / 11px8px 16px / 13px
Medium6px 14px / 12px10px 20px / 14px
Large8px 18px / 13px14px 28px / 16px

Robustness​

  • !important on all style properties (beats theme CSS)
  • CSS reset (margin, box-sizing, vertical-align, text-transform, box-shadow)
  • DOM insertion with a 3-stage fallback: script.parentNode.insertBefore(container, script.nextSibling) -> document.body.appendChild -> wait for DOMContentLoaded
  • document.currentScript fallback for async/defer scripts: querySelector('script[data-tenant][src*="widget.js"]')
  • Duplicate protection: window.__licensioWidgetLoaded flag
  • Branding API down: renders with default colors instead of being visibly missing

Debugging​

Set data-debug="true" and open the console:

[licensio widget] init { tenant: '...', styleAttr: null, baseUrl: 'https://...' }
[licensio widget] fetching branding https://.../api/portal/branding
[licensio widget] branding response { ok: true, status: 200 }
[licensio widget] branding parsed { primary_color: '#F87627', ... }
[licensio widget] render { style: 'solid', size: 'medium', primaryColor: '#F87627', ... }
[licensio widget] inserted after script tag

CORS for your own endpoints​

If you want to call your own endpoints in the tenant portal from an external domain, note: only /api/portal/branding is CORS-open. All other routes check session cookies and are same-origin only.