Widget Documentation
Everything you need to embed and customize the <image-layer> widget for image, video, voice, and text workflows in your application.
Quick Start
Add the widget to any HTML page in three lines:
<script type="module" src="https://cdn.imagelayer.app/widget/latest/image-layer.js"></script>
<image-layer
api-key="il_live_your_api_key_here"
api-url="https://api.imagelayer.app"
session-token="SESSION_TOKEN_FROM_YOUR_SERVER"
></image-layer> The widget renders as a self-contained UI. Users choose a supported workflow, generate on-brand output, and stay inside your product the whole time.
Installation
CDN (recommended)
<script type="module" src="https://cdn.imagelayer.app/widget/latest/image-layer.js"></script> Self-hosted
Copy the built widget files to your static assets and reference the local path:
<script type="module" src="/assets/image-layer.js"></script> Attributes
All configuration is done via HTML attributes on the <image-layer> element.
| Attribute | Type | Default | Description |
|---|---|---|---|
| api-key | string | "" | Required. Your organization's API key from the dashboard. |
| api-url | string | "" | Required. Base URL of the ImageLayer API. |
| session-token | string | "" | Required. JWT from POST /v1/auth/session. |
| theme | "light" | "dark" | "auto" | "auto" | Color scheme. "auto" follows the system light/dark preference; "dark" forces dark palette. |
| show-model-selector | boolean | true | Show AI model dropdown (Gemini Flash, Pro, Imagen 4). |
| demo-mode | boolean | false | Enable the limited hosted demo experience for previews and local testing. |
| demo-config | string (JSON) | undefined | JSON configuration for demo mode content types and platform presets. |
| brand-guidelines | boolean | false | Enables the brand guidelines toggle in the widget UI. |
| brand-guidelines-data | string (JSON) | undefined | JSON object with brand guidelines configuration (colors, tone, style rules). |
| animation-style | "spring" | "smooth" | "none" | "spring" | Controls the animation style for UI transitions. |
Events
The widget emits custom events that bubble up through the DOM. Listen with addEventListener.
| Event | Fires when | event.detail |
|---|---|---|
| il:generate | User submits a prompt or selects a history item. | { prompt: string, output_mode: string } |
| il:submit | User finalizes the branded image. | { url: string, blob: Blob } |
| il:error | An error occurs during generation. | { error: string } |
| il:text-generated | AI text generation completes. | { text: string } |
| il:quota-exceeded | The user exceeds their credit quota. | { current: number, limit: number, plan: string, canPurchaseCredits: boolean } |
const widget = document.querySelector('image-layer');
widget.addEventListener('il:generate', (e) => {
console.log('Generating:', e.detail.prompt);
});
widget.addEventListener('il:submit', (e) => {
console.log('Final image URL:', e.detail.url);
// e.detail.blob contains the raw Blob for upload
});
widget.addEventListener('il:error', (e) => {
console.error('Widget error:', e.detail.error);
}); Theming
The widget uses CSS custom properties for full visual customization.
Override them on the <image-layer> element to match your brand.
image-layer {
/* Brand colors */
--il-primary: #6366F1;
--il-primary-hover: #4F46E5;
--il-accent: #10B981;
--il-accent-hover: #059669;
/* Backgrounds */
--il-bg: #FFFFFF;
--il-bg-secondary: #F8FAFC;
--il-bg-tertiary: #F1F5F9;
/* Text */
--il-text: #0F172A;
--il-text-secondary: #475569;
--il-text-muted: #94A3B8;
/* Borders */
--il-border: #E2E8F0;
--il-border-hover: #CBD5E1;
/* Error / Success */
--il-error: #EF4444;
--il-success: var(--il-accent);
/* Border radius */
--il-radius: 10px;
--il-radius-sm: 6px;
--il-radius-lg: 14px;
--il-radius-full: 9999px;
/* Typography */
--il-font: 'Inter', system-ui, sans-serif;
/* Shadows */
--il-shadow-xs: 0 1px 2px rgba(0,0,0,0.04);
--il-shadow: 0 1px 3px rgba(0,0,0,0.08), 0 1px 2px -1px rgba(0,0,0,0.08);
--il-shadow-md: 0 4px 6px -1px rgba(0,0,0,0.08), 0 2px 4px -2px rgba(0,0,0,0.06);
--il-shadow-lg: 0 10px 15px -3px rgba(0,0,0,0.08), 0 4px 6px -4px rgba(0,0,0,0.04);
} Dark Theme
Set theme="dark" on the element. Override dark-specific variables:
image-layer[theme="dark"] {
--il-bg: #0F172A;
--il-text: #F1F5F9;
--il-border: #334155;
--il-primary: #818CF8;
} Server-Side Setup
The widget requires a session token to authenticate end users. Your server obtains this token by calling the ImageLayer API.
1. Get your API key
Go to Dashboard → API Keys and create a new key.
2. Create a session (server-side)
Call POST /v1/auth/session from your backend:
curl -X POST https://api.imagelayer.app/v1/auth/session \
-H "X-API-Key: il_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"external_user_id": "user-123",
"display_name": "Jane Doe"
}' Response:
{
"session_token": "eyJhbG...",
"expires_at": "2026-03-29T22:00:00.000Z",
"user": {
"id": "uuid",
"external_id": "user-123",
"display_name": "Jane Doe"
}
} 3. Pass the token to the widget
Inject session_token into the widget's session-token attribute — server-side when rendering, or client-side after fetching from your API.
Full Integration Example
A complete HTML page with session creation and widget embedding.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>My App — AI Media Generator</title>
<script type="module" src="https://cdn.imagelayer.app/widget/latest/image-layer.js"></script>
<style>
image-layer {
max-width: 480px;
margin: 40px auto;
--il-primary: #2563EB;
--il-radius-lg: 16px;
}
</style>
</head>
<body>
<image-layer
id="widget"
api-key="il_live_your_api_key"
api-url="https://api.imagelayer.app"
theme="light"
></image-layer>
<script>
// Fetch session token from YOUR backend
async function initWidget() {
const res = await fetch('/api/imagelayer-session');
const { session_token } = await res.json();
document.getElementById('widget').setAttribute('session-token', session_token);
}
const widget = document.getElementById('widget');
widget.addEventListener('il:submit', (e) => {
// Upload the final branded image to your storage
const formData = new FormData();
formData.append('image', e.detail.blob, 'branded-image.png');
fetch('/api/upload', { method: 'POST', body: formData });
});
initWidget();
</script>
</body>
</html> Demo Mode
For previews and local development, use demo mode to render the hosted limited demo experience:
<image-layer
api-url="http://localhost:3001"
demo-mode
show-model-selector
theme="dark"
></image-layer>