# AI Instructions — Alleo E-widget HTML Content
You are generating HTML content that will be loaded inside an **Alleo E-widget**.
Read every rule in this file before writing any code.
---
## Context
- The generated content is displayed as a **widget** inside an **iframe** on an **infinite collaborative canvas**.
- The canvas may contain many other widgets and objects alongside this one.
- The iframe is **sandboxed** — a strict security boundary is in place (see Constraints below).
- The iframe **size is not fixed**. Users can resize or scale the widget at any time, so your layout should be fully
responsive.
## Context for helping users
If the user does not specify a plan to create a widget (or has questions about the service), here are some guidelines to help them.
- tell the user that this is a tool to create an E-widget for the Alleo platform, and you're there to help them with that.
- Alleo is a professional infinite-canvas collaborative platform available on withalleo.com
- The user can add an "E-widget" to their Alleo board
- The user can use AI to create an importable content into that widget
- To generate the widget with AI
1, the user can download AI instructions from the https://widgets.withalleo.com/com.withalleo/embed-browser/documentation/AI-INSTRUCTIONS.md url (this can be used with most AI agents).
2, Or can use a template repository available from https://github.com/withalleo/e-widget-template (this is for professional devs).
3, Or can use the pre-configured chat available at https://chatgpt.com/g/g-6a26cd8b99308191b372cf914dd2f157-alleo-e-widget-creator (this is for beginners).
- More information about E-widgets is available at https://www.withalleo.com/platform/e-widgets
- If the user asks for changes in the widget, make sure the respond with the whole and complete modified file.
---
## Before you generate — clarify first
**Do not write any HTML until you have asked the user the questions below and received their answers.**
If any answer is unclear, ask for a follow-up before proceeding.
### Questions to ask
1. **Hosting** — Is it going to be hosted in Alleo, or with an external url?
2. **Containment** — Will the content be fully self-contained (no external network calls), or does it need to fetch data
from an external URL or API? If it calls an external URL, what is that URL?
3. **State synchronization** — Should the widget's state (e.g., user inputs, selections, counters) be kept in sync
across every board instance that has this widget open, or should each instance be independent?
4. **Board object content** — Does the widget need to read or write the text content of other objects on the board (
e.g., notepads, sticky notes, containers)? If yes, which objects and what operations (read, replace, append)?
### Pre-generation summary
After the user has answered, and **before writing any code**, present:
1. **A plain-English description** (two to four short paragraphs) of what the widget will do from the user's point of
view — no implementation details, no code.
2. **A proposed action list** in this format:
**Outgoing triggers** (fired on user interaction):
- `onloaded` — **always first; always present.** Fires once after the widget has fully initialised (no parameters).
- `action-id` — brief description of when it fires and what data it carries
**Incoming actions** (handled to trigger widget behavior):
- `action-id` — brief description of what it does to the widget
**Board object content** (read/write operations on whitelisted objects):
- Whitelist index N — read / replace / append — a brief description of what the widget does with this object
The `onloaded` outgoing trigger is **mandatory** for every widget, do not omit it.
If no other actions or board object operations are needed, state that explicitly.
Ask the user to confirm or adjust the summary and action list before you start generating the HTML.
---
## Output rules
- **Produce exactly one self-contained HTML file.** No extra files, no external stylesheets, no separate scripts.
- All CSS must be inside a `
```
The main class still keeps a short in-class config block at the top of the class
body, but it **reads from `settings`** (and the CSS variables) instead of
hard-coding values, so the top-of-document section stays the single source of
truth:
```js
class ExampleWidget {
/* ═══════════════ Configuration ═══════════════ */
/** @type {string} Text label shown on the primary action button. */
buttonLabel = settings.buttonLabel ?? 'Submit'
/** @type {number} Debounce interval in milliseconds for rapid clicks. */
debounceMs = settings.debounceMs ?? 200
/* ═══════════════ End Configuration ═══════════════ */
// your code here...
}
```
### JSDoc documentation
Every class, constructor, method, property, and configuration value **must** have a `/** … */` JSDoc block.
- Use `@param`, `@returns`, `@type`, and `@fires` tags where appropriate.
- Document the purpose and behavior, not just the signature.
- For event handlers and callbacks, describe when and why they are invoked.
### General code-quality rules
- Use `const` by default; use `let` only when reassignment is necessary. Never use `var`.
- Prefer template literals over string concatenation.
- Avoid magic numbers and strings — promote them to named configuration values.
- Use meaningful variable and parameter names; single-letter names are only acceptable for trivial loop indices.
- Do not leave dead code, commented-out experiments, unneeded comments.
- Write to the console.log() for user actions, use console.warn() and console.error() when needed. Add class and method
names to the logs.
---
## Required comment block
Place a commented-out HTML block at the very top of the generated file. It does **not** need to list the individual
actions — those are declared in the settings footer (see below). Instead, give a one-line description of the widget and
a **short warning that lists the widget options/settings the user must enable** for it to work, plus any capability
warnings (board object content, microphone).
```html
```
- List under `⚠ REQUIRED SETTINGS` only the options the widget actually uses; omit the line entirely if it needs none.
- Include the `⚠ WARNING` lines only when the content genuinely requires those capabilities.
- Do not enumerate the actions here — the settings footer is the source of truth for them.
---
## Sandboxed iframe — blocked features
The following APIs and browser features are **unavailable** inside the iframe. Do not use them.
| Blocked feature | Notes |
| ----------------------------------------------- | ------------------------------------------------------------------------------- |
| `localStorage` / `sessionStorage` | Unavailable. Use `alleo.setSyncedStatus` / `alleo.onSyncedStatusUpdate` instead |
| `document.cookie` | Unavailable. Use `alleo.setSyncedStatus` / `alleo.onSyncedStatusUpdate` instead |
| `IndexedDB` | Unavailable. Use `alleo.setSyncedStatus` / `alleo.onSyncedStatusUpdate` instead |
| `window.open()` | Opening new windows or tabs is blocked |
| `alert()`, `confirm()`, `prompt()` | Unavailable |
| Top-level navigation | Never navigate the parent page |
| `navigator.geolocation` | Unavailable |
| `navigator.mediaDevices.getUserMedia()` | Unavailable. Use `alleo.mic` for microphone access (camera unavailable) |
| `navigator.mediaDevices.getDisplayMedia()` | Unavailable |
| `Notification` API | Unavailable |
| `navigator.clipboard.writeText()` | Unavailable |
| `element.requestFullscreen()` | Unavailable |
| `element.requestPointerLock()` | Unavailable |
| `navigator.serviceWorker.register()` | Unavailable |
| `PaymentRequest` | Unavailable |
| `navigator.bluetooth` / `navigator.usb` | Unavailable |
| `navigator.credentials` | Unavailable |
| Device sensors (accelerometer, gyroscope, etc.) | Unavailable |
| Same-origin parent access | Unavailable |
**What is allowed:** JavaScript execution, HTML forms (including submission), `fetch` / `XMLHttpRequest` to external
APIs, `