Embeddable Elements
Embed Karrio’s shipping UI components directly into any web application. Embeddable Elements are self-contained, iframe-based widgets that work with any frontend framework or vanilla HTML, no React dependency required on the host page.
Overview
Karrio Elements provide drop-in UI components that connect to your Karrio instance via API token. Each element runs inside an isolated iframe, ensuring zero CSS conflicts, framework compatibility, and secure token handling.
Available Elements
| Element | Description | Use Case |
|---|---|---|
| Rate Sheet Editor | Full-featured rate sheet creation and editing interface | Custom rate management in partner portals |
| Developer Tools | Interactive developer drawer with API logs, events, webhooks, GraphiQL, and Swagger playground | Debugging and API exploration in admin panels |
| Template Editor | HTML document template editor with live preview and PDF generation | Custom packing slips, invoices, and shipping documents |
| Carrier Connections | Carrier account management with connection list, creation, editing, and OAuth support | Carrier onboarding in partner portals |
Architecture
The host page loads a lightweight script (elements.js, ~3KB, no React) that manages iframe lifecycle and communication via postMessage. The iframe contains the full React application, pre-built and bundled with all dependencies.
Quick Start
1. Include the Elements Script
Add the elements script to your HTML page. This script exposes window.KarrioElements.
1<script src="https://your-karrio-instance/static/karrio/elements/elements.js"></script>
2. Mount a Rate Sheet Editor
1<div id="editor"></div> 2 3<script> 4 const editor = KarrioElements.mount('#editor', { 5 host: 'https://api.karrio.io', 6 token: 'key_xxxxxxxxxx', 7 rateSheetId: 'rsh_...', // optional, omit for new sheet 8 carrier: 'custom', // optional 9 connectionId: 'conn_...', // optional 10 admin: false, // use admin GraphQL endpoint 11 iframeSrc: 'https://your-karrio-instance/static/karrio/elements/ratesheet.html', 12 }); 13 14 editor 15 .on('save', (data) => console.log('Rate sheet saved:', data)) 16 .on('close', () => editor.unmount()) 17 .on('error', (err) => console.error('Error:', err)); 18</script>
3. Mount Developer Tools
1<div id="devtools"></div> 2 3<script> 4 const devtools = KarrioElements.mountDevtools('#devtools', { 5 host: 'https://api.karrio.io', 6 token: 'key_xxxxxxxxxx', 7 admin: false, 8 defaultView: 'activity', // activity, api-keys, logs, events, webhooks, apps, playground, graphiql 9 iframeSrc: 'https://your-karrio-instance/static/karrio/elements/devtools.html', 10 }); 11 12 devtools 13 .on('close', () => devtools.unmount()) 14 .on('error', (err) => console.error('Error:', err)); 15</script>
4. Mount a Template Editor
1<div id="template"></div> 2 3<script> 4 const tmpl = KarrioElements.mountTemplateEditor('#template', { 5 host: 'https://api.karrio.io', 6 token: 'key_xxxxxxxxxx', 7 templateId: 'tpl_...', // optional, omit for new template 8 admin: false, 9 iframeSrc: 'https://your-karrio-instance/static/karrio/elements/template-editor.html', 10 }); 11 12 tmpl 13 .on('save', () => console.log('Template saved')) 14 .on('close', () => tmpl.unmount()) 15 .on('error', (err) => console.error('Error:', err)); 16</script>
5. Mount Carrier Connections
1<div id="connections"></div> 2 3<script> 4 const conn = KarrioElements.mountConnections('#connections', { 5 host: 'https://api.karrio.io', 6 token: 'key_xxxxxxxxxx', 7 connectionId: 'car_...', // optional, opens edit dialog for this connection 8 carrier: 'fedex', // optional, pre-selects carrier for new connection 9 admin: false, 10 iframeSrc: 'https://your-karrio-instance/static/karrio/elements/connections.html', 11 }); 12 13 conn 14 .on('save', (data) => console.log('Connection saved:', data)) 15 .on('close', () => conn.unmount()) 16 .on('error', (err) => console.error('Error:', err)); 17</script>
API Reference
KarrioElements.mount(selector, options)
Mounts the Rate Sheet Editor element.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
selector | string | HTMLElement | Yes | CSS selector or DOM element to mount into |
options.host | string | Yes | Karrio API base URL (e.g. https://api.karrio.io) |
options.token | string | Yes | Karrio API key (key_...) |
options.rateSheetId | string | No | ID of existing rate sheet to edit. Omit for new |
options.carrier | string | No | Carrier slug (e.g. custom, fedex) |
options.connectionId | string | No | Carrier connection ID |
options.admin | boolean | No | Use admin GraphQL endpoint (/admin/graphql) |
options.iframeSrc | string | No | Custom URL for the ratesheet HTML page |
Returns: EditorHandle
| Method | Description |
|---|---|
.on(event, callback) | Register event listener. Returns handle for chaining |
.unmount() | Remove the element from the DOM |
.update(options) | Update configuration and re-initialize |
Events: save, close, error
KarrioElements.mountDevtools(selector, options)
Mounts the Developer Tools drawer element.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
selector | string | HTMLElement | Yes | CSS selector or DOM element to mount into |
options.host | string | Yes | Karrio API base URL |
options.token | string | Yes | Karrio API key |
options.admin | boolean | No | Use admin GraphQL endpoint |
options.defaultView | string | No | Tab to open by default (see below) |
options.iframeSrc | string | No | Custom URL for the devtools HTML page |
Default Views: activity, api-keys, logs, events, webhooks, apps, playground, graphiql
Returns: DevtoolsHandle
| Method | Description |
|---|---|
.on(event, callback) | Register event listener. Returns handle for chaining |
.unmount() | Remove the element from the DOM |
Events: close, error
KarrioElements.mountTemplateEditor(selector, options)
Mounts the Document Template Editor element.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
selector | string | HTMLElement | Yes | CSS selector or DOM element to mount into |
options.host | string | Yes | Karrio API base URL |
options.token | string | Yes | Karrio API key |
options.admin | boolean | No | Use admin GraphQL endpoint |
options.templateId | string | No | ID of existing template to edit. Omit for new |
options.iframeSrc | string | No | Custom URL for the template-editor HTML page |
Returns: EditorHandle
| Method | Description |
|---|---|
.on(event, callback) | Register event listener. Returns handle for chaining |
.unmount() | Remove the element from the DOM |
.update(options) | Update configuration and re-initialize |
Events: save, close, error
KarrioElements.mountConnections(selector, options)
Mounts the Carrier Connections management element.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
selector | string | HTMLElement | Yes | CSS selector or DOM element to mount into |
options.host | string | Yes | Karrio API base URL |
options.token | string | Yes | Karrio API key |
options.admin | boolean | No | Use admin GraphQL endpoint |
options.connectionId | string | No | Open edit dialog for this connection on mount |
options.carrier | string | No | Pre-select carrier when adding a new connection |
options.iframeSrc | string | No | Custom URL for the connections HTML page |
Returns: EditorHandle
| Method | Description |
|---|---|
.on(event, callback) | Register event listener. Returns handle for chaining |
.unmount() | Remove the element from the DOM |
.update(options) | Update configuration and re-initialize |
Events: save, close, error
Self-Hosting Elements
When self-hosting Karrio, elements are built and served as static files from the Django server.
Build Elements
1./bin/server build:elements
This command:
- Installs dependencies and builds the Vite project in
packages/elements/ - Copies all output files to
apps/api/karrio/server/static/karrio/elements/ - Runs
collectstaticto make them available at/static/karrio/elements/
Output Files
| File | Description |
|---|---|
elements.js | Host-side mounting script (~3KB, no React) |
globals.css | Shared Tailwind CSS styles |
ratesheet.js | Rate Sheet Editor React bundle |
ratesheet.html | Rate Sheet Editor iframe shell |
devtools.js | Developer Tools React bundle |
devtools.css | Developer Tools styles (GraphiQL, Swagger) |
devtools.html | Developer Tools iframe shell |
template-editor.js | Template Editor React bundle |
template-editor.html | Template Editor iframe shell |
connections.js | Carrier Connections React bundle |
connections.html | Carrier Connections iframe shell |
chunks/ | Shared code-split chunks |
Serving from Django
Once built, elements are available at:
https://your-karrio-instance/static/karrio/elements/elements.js
https://your-karrio-instance/static/karrio/elements/ratesheet.html
https://your-karrio-instance/static/karrio/elements/devtools.html
https://your-karrio-instance/static/karrio/elements/template-editor.html
https://your-karrio-instance/static/karrio/elements/connections.html
Set the iframeSrc option to point to the HTML files on your Karrio instance.
Framework Integration Examples
React
1import { useEffect, useRef } from 'react'; 2 3declare global { 4 interface Window { 5 KarrioElements: { 6 mount: (selector: string | HTMLElement, options: any) => any; 7 mountDevtools: (selector: string | HTMLElement, options: any) => any; 8 }; 9 } 10} 11 12export function KarrioRateSheetEditor({ host, token, rateSheetId, onSave, onClose }: { 13 host: string; 14 token: string; 15 rateSheetId?: string; 16 onSave?: (data: any) => void; 17 onClose?: () => void; 18}) { 19 const containerRef = useRef<HTMLDivElement>(null); 20 const handleRef = useRef<any>(null); 21 22 useEffect(() => { 23 if (!containerRef.current) return; 24 25 handleRef.current = window.KarrioElements.mount(containerRef.current, { 26 host, 27 token, 28 rateSheetId, 29 }); 30 31 handleRef.current 32 .on('save', (data: any) => onSave?.(data)) 33 .on('close', () => onClose?.()); 34 35 return () => handleRef.current?.unmount(); 36 }, [host, token, rateSheetId]); 37 38 return <div ref={containerRef} style={{ minHeight: 600 }} />; 39}
Vue 3
1<template> 2 <div ref="container" style="min-height: 600px" /> 3</template> 4 5<script setup> 6import { ref, onMounted, onUnmounted } from 'vue'; 7 8const props = defineProps({ 9 host: { type: String, required: true }, 10 token: { type: String, required: true }, 11 rateSheetId: String, 12}); 13 14const emit = defineEmits(['save', 'close']); 15const container = ref(null); 16let handle = null; 17 18onMounted(() => { 19 handle = window.KarrioElements.mount(container.value, { 20 host: props.host, 21 token: props.token, 22 rateSheetId: props.rateSheetId, 23 }); 24 25 handle 26 .on('save', (data) => emit('save', data)) 27 .on('close', () => emit('close')); 28}); 29 30onUnmounted(() => handle?.unmount()); 31</script>
Vanilla JavaScript
1<!DOCTYPE html> 2<html> 3<head> 4 <title>Karrio Rate Sheet Editor</title> 5 <style> 6 #editor { max-width: 1200px; margin: 40px auto; } 7 </style> 8</head> 9<body> 10 <div id="editor"></div> 11 12 <script src="/static/karrio/elements/elements.js"></script> 13 <script> 14 const editor = KarrioElements.mount('#editor', { 15 host: 'https://api.karrio.io', 16 token: 'key_xxxxxxxxxx', 17 }); 18 19 editor.on('close', () => { 20 editor.unmount(); 21 window.location.href = '/rate-sheets'; 22 }); 23 </script> 24</body> 25</html>
Security Considerations
[!NOTE] Elements use iframe isolation to prevent CSS and JavaScript conflicts with the host page. All API communication happens within the iframe using token-based authentication.
- Token scope: Use API keys with the minimum required permissions. Rate Sheet Editor needs rate sheet read/write access. Developer Tools needs read access to logs, events, and webhooks.
- CORS: The Karrio API must allow requests from the iframe origin. When self-hosting, ensure your CORS configuration includes the domain serving the element HTML files.
- iframe sandboxing: The host page creates iframes with standard permissions. For additional security, configure your CSP headers to restrict the iframe
srcto your Karrio instance.
Troubleshooting
Element does not load
Verify that the iframeSrc URL is accessible from the browser. Open the URL directly to confirm the HTML page loads.
401 Unauthorized errors
Ensure the API token is valid and has the required permissions. Elements use Token authentication (not Bearer).
Chunks fail to load (404)
All element files (*.js, *.css, chunks/) must be served from the same directory as the HTML file. If using a CDN or custom path, ensure all files are co-located.
CSS conflicts
Elements render inside an iframe, so host page styles cannot leak in. If styles look wrong, verify that globals.css and (for devtools) devtools.css are loaded by the HTML shell.
Next Steps
- API Integration - Learn about the GraphQL and REST APIs used by elements
- Building Apps - Build full Karrio Apps with custom UI
- Webhooks - Set up real-time event notifications
