omni-embed
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseOmni Embed
Omni 嵌入功能
Embed Omni dashboards in external applications using signed iframe URLs. The SDK handles URL signing and theme customization. Omni's postMessage events enable two-way communication between the parent app and embedded iframe.
@omni-co/embedTip: Useto find dashboards to embed, andomni-content-explorerto manage embed user permissions and user attributes for row-level security.omni-admin
使用签名的iframe URL将Omni仪表板嵌入外部应用程序。 SDK负责处理URL签名和主题自定义。Omni的postMessage事件支持父应用与嵌入的iframe之间的双向通信。
@omni-co/embed提示:使用查找要嵌入的仪表板,使用omni-content-explorer管理嵌入用户权限和行级安全的用户属性。omni-admin
Prerequisites
前置条件
bash
npm install @omni-co/embedbash
undefinedbash
npm install @omni-co/embedbash
undefinedVerify the Omni CLI is installed — if not, ask the user to install it
Verify the Omni CLI is installed — if not, ask the user to install it
command -v omni >/dev/null || echo "ERROR: Omni CLI is not installed."
```bashcommand -v omni >/dev/null || echo "ERROR: Omni CLI is not installed."
```bashShow available profiles and select the appropriate one
Show available profiles and select the appropriate one
omni config show
omni config show
If multiple profiles exist, ask the user which to use, then switch:
If multiple profiles exist, ask the user which to use, then switch:
omni config use <profile-name>
export OMNI_EMBED_SECRET="your-embed-secret" # Admin → Embed (for URL signing)
The embed secret is found in **Admin → Embed** in your Omni instance. The `OMNI_BASE_URL` for embedding uses the `.embed-omniapp.co` domain, not the standard `.omniapp.co` domain.omni config use <profile-name>
export OMNI_EMBED_SECRET="your-embed-secret" # Admin → Embed (for URL signing)
嵌入密钥可在您的Omni实例的**Admin → Embed**中找到。用于嵌入的`OMNI_BASE_URL`使用`.embed-omniapp.co`域名,而非标准的`.omniapp.co`域名。Discovering Commands
命令探索
bash
omni scim --help # Embed user lookup
omni documents --help # Document listing
omni folders --help # Folder listingTip: Useto force structured output for programmatic parsing, or-o jsonfor readable tables. The default is-o human(human in a TTY, JSON when piped).auto
bash
omni scim --help # Embed user lookup
omni documents --help # Document listing
omni folders --help # Folder listing提示:使用强制输出结构化内容以便程序化解析,或使用-o json输出易读的表格。默认值为-o human(在TTY中输出人类可读格式,管道传输时输出JSON)。auto
Signing Embed URLs
签名嵌入URL
Use from the SDK to generate a signed URL server-side, then load it in an iframe client-side.
embedSsoDashboard()@omni-co/embedtypescript
import { embedSsoDashboard, EmbedSessionMode } from "@omni-co/embed";
const embedUrl = await embedSsoDashboard({
contentId: "dashboard-uuid",
secret: process.env.OMNI_EMBED_SECRET,
host: "yourorg.embed-omniapp.co", // Hostname only, no https://
externalId: "user@example.com",
name: "Jane Doe",
userAttributes: { brand: ["Acme"] }, // For row-level security
mode: EmbedSessionMode.SingleContent,
prefersDark: "false",
});使用 SDK中的在服务端生成签名URL,然后在客户端将其加载到iframe中。
@omni-co/embedembedSsoDashboard()typescript
import { embedSsoDashboard, EmbedSessionMode } from "@omni-co/embed";
const embedUrl = await embedSsoDashboard({
contentId: "dashboard-uuid",
secret: process.env.OMNI_EMBED_SECRET,
host: "yourorg.embed-omniapp.co", // Hostname only, no https://
externalId: "user@example.com",
name: "Jane Doe",
userAttributes: { brand: ["Acme"] }, // For row-level security
mode: EmbedSessionMode.SingleContent,
prefersDark: "false",
});Parameters
参数说明
| Parameter | Required | Description |
|---|---|---|
| Yes | Dashboard UUID (from URL or Admin → Dashboards) |
| Yes | Embed secret from Admin → Embed |
| Yes | Embed hostname only — no protocol, no port |
| Yes | Unique user identifier (typically email) |
| Yes | Display name for the user |
| No | |
| No | |
| No | |
| No | Theme object (see Custom Themes below) |
| No | Entity name for workspaces (see Entity Workspaces below) |
Gotcha: The parameter must be a bare hostname (e.g., ). Including a protocol () or port () causes Omni to return 400.
hostyourorg.embed-omniapp.cohttps://:3000| 参数 | 是否必填 | 描述 |
|---|---|---|
| 是 | 仪表板UUID(来自URL或Admin → Dashboards) |
| 是 | 来自Admin → Embed的嵌入密钥 |
| 是 | 仅嵌入主机名——无协议、无端口 |
| 是 | 唯一用户标识符(通常为邮箱) |
| 是 | 用户的显示名称 |
| 否 | 用于行级安全的 |
| 否 | |
| 否 | |
| 否 | 主题对象(见下方自定义主题) |
| 否 | 工作区的实体名称(见下方实体工作区) |
注意事项:参数必须是纯主机名(例如)。包含协议()或端口()会导致Omni返回400错误。
hostyourorg.embed-omniapp.cohttps://:3000Custom Themes
自定义主题
Pass a object to to style the embedded dashboard content (tile backgrounds, text colors, controls, buttons). This controls what's inside the iframe — parent app styling is separate.
customThemeembedSsoDashboard()typescript
const embedUrl = await embedSsoDashboard({
// ...signing params
prefersDark: "false",
customTheme: {
"dashboard-background": "#FEF2F2",
"dashboard-tile-background": "#FFF5F5",
"dashboard-key-color": "#E60000",
"dashboard-key-text-color": "#ffffff",
// ...
},
});向传递对象,以设置嵌入仪表板内容的样式(磁贴背景、文本颜色、控件、按钮)。这控制iframe内部的样式——父应用的样式是独立的。
embedSsoDashboard()customThemetypescript
const embedUrl = await embedSsoDashboard({
// ...签名参数
prefersDark: "false",
customTheme: {
"dashboard-background": "#FEF2F2",
"dashboard-tile-background": "#FFF5F5",
"dashboard-key-color": "#E60000",
"dashboard-key-text-color": "#ffffff",
// ...
},
});Property Reference
属性参考
Page:
| Property | Description |
|---|---|
| Dashboard page background |
| Dashboard page padding |
Tiles:
| Property | Description |
|---|---|
| Spacing around tiles |
| Tile background color |
| Tile box shadow |
| Primary text color in tiles |
| Secondary text color in tiles |
| Tile border color |
| Tile border radius |
| Tile border style |
| Tile border width |
| Title font size |
| Title font weight |
| Title text color |
| Custom title font (woff2 URL) |
| Custom body font |
| Custom code font |
Controls (filter dropdowns):
| Property | Description |
|---|---|
| Filter control background |
| Filter control border radius |
| Filter control border color |
| Filter control text color |
| Placeholder text color |
| Label text above controls |
| Focus outline color |
Control Popovers (dropdown menus):
| Property | Description |
|---|---|
| Popover background |
| Popover text color |
| Secondary text in popovers |
| Link color in popovers |
| Divider color |
| Popover border radius |
| Popover border color |
| Filter input background |
| Filter input border radius |
| Filter input border color |
| Filter input text color |
| Placeholder text |
| Icon color in filter inputs |
| Focus outline for filter inputs |
| Checkbox, radio, and toggle color |
| Checkmark/dot color inside inputs |
| Multi-select token background |
| Multi-select token text color |
Buttons:
| Property | Description |
|---|---|
| Primary action color (Update buttons) |
| Text color on primary buttons |
| Button border radius |
| Transparent button text color |
| Transparent button hover color |
| Menu item hover background |
页面:
| 属性 | 描述 |
|---|---|
| 仪表板页面背景 |
| 仪表板页面内边距 |
磁贴:
| 属性 | 描述 |
|---|---|
| 磁贴周围间距 |
| 磁贴背景颜色 |
| 磁贴阴影 |
| 磁贴中的主要文本颜色 |
| 磁贴中的次要文本颜色 |
| 磁贴边框颜色 |
| 磁贴边框圆角 |
| 磁贴边框样式 |
| 磁贴边框宽度 |
| 标题字体大小 |
| 标题字体粗细 |
| 标题文本颜色 |
| 自定义标题字体(woff2 URL) |
| 自定义正文字体 |
| 自定义代码字体 |
控件(筛选下拉框):
| 属性 | 描述 |
|---|---|
| 筛选控件背景 |
| 筛选控件边框圆角 |
| 筛选控件边框颜色 |
| 筛选控件文本颜色 |
| 占位符文本颜色 |
| 控件上方的标签文本颜色 |
| 聚焦时的轮廓颜色 |
控件弹出框(下拉菜单):
| 属性 | 描述 |
|---|---|
| 弹出框背景 |
| 弹出框文本颜色 |
| 弹出框中的次要文本颜色 |
| 弹出框中的链接颜色 |
| 分隔线颜色 |
| 弹出框边框圆角 |
| 弹出框边框颜色 |
| 筛选输入框背景 |
| 筛选输入框边框圆角 |
| 筛选输入框边框颜色 |
| 筛选输入框文本颜色 |
| 占位符文本颜色 |
| 筛选输入框中的图标颜色 |
| 筛选输入框聚焦时的轮廓颜色 |
| 复选框、单选框和切换按钮的颜色 |
| 输入框内勾选标记/圆点的颜色 |
| 多选标签的背景颜色 |
| 多选标签的文本颜色 |
按钮:
| 属性 | 描述 |
|---|---|
| 主要操作按钮颜色(更新按钮) |
| 主要按钮上的文本颜色 |
| 按钮边框圆角 |
| 透明按钮的文本颜色 |
| 透明按钮的悬停颜色 |
| 菜单项的悬停背景颜色 |
Supported CSS Values
支持的CSS值
- Hex colors: ,
"#FEF2F2""#E60000" - Box shadows with rgba:
"0 2px 8px rgba(230, 0, 0, 0.1)" - Custom fonts via URL:
"url(https://fonts.gstatic.com/...) format('woff2')" - Empty strings to clear defaults:
"" - and
linear-gradient()for backgrounds work in Omni's UI theme editor but may fail when passed via the SDK — use solid hex colors for reliabilityrgba()
- 十六进制颜色:,
"#FEF2F2""#E60000" - 使用rgba的阴影:
"0 2px 8px rgba(230, 0, 0, 0.1)" - 通过URL引入自定义字体:
"url(https://fonts.gstatic.com/...) format('woff2')" - 空字符串用于清除默认值:
"" - 和
linear-gradient()可在Omni的UI主题编辑器中用于背景,但通过SDK传递时可能失效——建议使用纯色十六进制颜色以确保可靠性rgba()
Theming Tips
主题设置技巧
For effective branding, tint backgrounds throughout rather than only coloring buttons:
- → light brand tint (like Tailwind's color-50)
dashboard-background - → slightly lighter than page background
dashboard-tile-background - → brand primary (titles in brand color)
dashboard-tile-title-text-color - → brand primary (labels in brand color)
dashboard-control-label-color - → medium-light brand tint (like color-200)
dashboard-tile-border-color - → brand primary
dashboard-key-color - → brand primary (checkboxes, toggles)
dashboard-filter-input-accent-color
为实现有效的品牌化,应全面调整背景色调,而非仅设置按钮颜色:
- → 浅品牌色调(类似Tailwind的color-50)
dashboard-background - → 比页面背景稍浅的颜色
dashboard-tile-background - → 品牌主色(标题使用品牌色)
dashboard-tile-title-text-color - → 品牌主色(标签使用品牌色)
dashboard-control-label-color - → 中浅品牌色调(类似color-200)
dashboard-tile-border-color - → 品牌主色
dashboard-key-color - → 品牌主色(复选框、切换按钮)
dashboard-filter-input-accent-color
Embed Events
嵌入事件
Omni communicates with the parent app via . All Omni events have .
postMessagesource: "omni"Omni通过与父应用通信。所有Omni事件均包含。
postMessagesource: "omni"Listening for Events
监听事件
javascript
window.addEventListener("message", (event) => {
if (event.data?.source !== "omni") return;
switch (event.data.name) {
case "dashboard:loaded":
// Dashboard ready
break;
case "error":
// Handle error
break;
case "dashboard:tile-drill":
// Handle drill action
break;
}
});javascript
window.addEventListener("message", (event) => {
if (event.data?.source !== "omni") return;
switch (event.data.name) {
case "dashboard:loaded":
// Dashboard ready
break;
case "error":
// Handle error
break;
case "dashboard:tile-drill":
// Handle drill action
break;
}
});Event Reference
事件参考
dashboard:loadedjson
{ "source": "omni", "name": "dashboard:loaded" }dashboard:filtersjson
{
"source": "omni",
"name": "dashboard:filters",
"payload": { /* filter state */ }
}errorjson
{
"source": "omni",
"name": "error",
"payload": {
"href": "https://...",
"message": "Error description"
}
}dashboard:tile-drilljson
{
"source": "omni",
"name": "dashboard:tile-drill",
"payload": {
"userId": "string",
"dashboard": {
"filters": {
"filterName": {
"filter": {},
"asJsonUrlSearchParam": "string"
}
},
"href": "string",
"urlId": "string",
"path": "string",
"title": "string"
},
"tile": {
"id": "string",
"title": "string",
"appliedFilters": {
"filterName": {
"filter": {},
"asJsonUrlSearchParam": "string"
}
}
},
"drill": {
"field": "string",
"fieldLabel": "string",
"drillQueryLabel": "string",
"rowToDrill": { "field_name": "value" }
}
}
}Use for the data from the drilled row. Use from or to sign and embed a different dashboard with those filters applied.
drill.rowToDrillasJsonUrlSearchParamtile.appliedFiltersdashboard.filterspage:changedjson
{
"source": "omni",
"name": "page:changed",
"payload": {
"pathname": "string",
"type": "string"
}
}Custom visualization events — Fired when a user clicks a configured table row or markdown link. Requires setup in Omni: set the table column's Display to Link → Embed event and enter an event name. For markdown, use tags.
<omni-message>json
{
"source": "omni",
"name": "<your-event-name>",
"payload": {
"data": "comma-separated values"
}
}Table setup: field dropdown → Display tab → Display as: Link → URL: Embed event → enter event name.
Markdown setup:
html
<omni-message event-name="product-click" event-data="{{products.name.raw}},{{products.retail_price.raw}}">
Click here
</omni-message>dashboard:loadedjson
{ "source": "omni", "name": "dashboard:loaded" }dashboard:filtersjson
{
"source": "omni",
"name": "dashboard:filters",
"payload": { /* filter state */ }
}errorjson
{
"source": "omni",
"name": "error",
"payload": {
"href": "https://...",
"message": "Error description"
}
}dashboard:tile-drilljson
{
"source": "omni",
"name": "dashboard:tile-drill",
"payload": {
"userId": "string",
"dashboard": {
"filters": {
"filterName": {
"filter": {},
"asJsonUrlSearchParam": "string"
}
},
"href": "string",
"urlId": "string",
"path": "string",
"title": "string"
},
"tile": {
"id": "string",
"title": "string",
"appliedFilters": {
"filterName": {
"filter": {},
"asJsonUrlSearchParam": "string"
}
}
},
"drill": {
"field": "string",
"fieldLabel": "string",
"drillQueryLabel": "string",
"rowToDrill": { "field_name": "value" }
}
}
}使用获取钻取行的数据。使用或中的来签名并嵌入应用了这些筛选条件的其他仪表板。
drill.rowToDrilltile.appliedFiltersdashboard.filtersasJsonUrlSearchParampage:changedjson
{
"source": "omni",
"name": "page:changed",
"payload": {
"pathname": "string",
"type": "string"
}
}自定义可视化事件 — 用户点击配置好的表格行或markdown链接时触发。需要在Omni中进行设置:将表格列的显示方式设置为链接 → 嵌入事件并输入事件名称。对于markdown,使用标签。
<omni-message>json
{
"source": "omni",
"name": "<your-event-name>",
"payload": {
"data": "comma-separated values"
}
}表格设置:字段下拉菜单 → 显示标签页 → 显示为:链接 → URL:嵌入事件 → 输入事件名称。
Markdown设置:
html
<omni-message event-name="product-click" event-data="{{products.name.raw}},{{products.retail_price.raw}}">
Click here
</omni-message>Sending Events to the Iframe
向iframe发送事件
dashboard:filter-change-by-url-parameterjavascript
iframe.contentWindow.postMessage({
source: "omni",
name: "dashboard:filter-change-by-url-parameter",
payload: {
filterUrlParameter: 'f--<filter_id>={"values":["value1","value2"]}'
}
}, iframeOrigin);Get the string by opening the dashboard in Omni, changing filter values, and copying the parameter from the URL.
filterUrlParameterf--dashboard:filter-change-by-url-parameterjavascript
iframe.contentWindow.postMessage({
source: "omni",
name: "dashboard:filter-change-by-url-parameter",
payload: {
filterUrlParameter: 'f--<filter_id>={"values":["value1","value2"]}'
}
}, iframeOrigin);获取字符串的方法:在Omni中打开仪表板,更改筛选值,然后从URL中复制参数。
filterUrlParameterf--Entity Workspaces
实体工作区
Entity workspaces let embed users create and save their own dashboards within a scoped folder.
typescript
import {
embedSsoDashboard,
EmbedSessionMode,
EmbedEntityFolderContentRoles,
EmbedUiSettings,
EmbedConnectionRoles,
} from "@omni-co/embed";
const embedUrl = await embedSsoDashboard({
// ...standard signing params
entity: "acme",
entityFolderContentRole: EmbedEntityFolderContentRoles.EDITOR,
mode: EmbedSessionMode.Application,
uiSettings: {
[EmbedUiSettings.SHOW_NAVIGATION]: false,
},
connectionRoles: {
"connection-uuid": EmbedConnectionRoles.RESTRICTED_QUERIER,
},
});| Parameter | Description |
|---|---|
| Entity name — scopes the user's folder (e.g., derived from email domain) |
| |
| Must be |
| Control Omni's built-in UI (e.g., hide Omni's sidebar if you provide your own) |
| Grant query access: |
实体工作区允许嵌入用户在限定的文件夹内创建并保存自己的仪表板。
typescript
import {
embedSsoDashboard,
EmbedSessionMode,
EmbedEntityFolderContentRoles,
EmbedUiSettings,
EmbedConnectionRoles,
} from "@omni-co/embed";
const embedUrl = await embedSsoDashboard({
// ...标准签名参数
entity: "acme",
entityFolderContentRole: EmbedEntityFolderContentRoles.EDITOR,
mode: EmbedSessionMode.Application,
uiSettings: {
[EmbedUiSettings.SHOW_NAVIGATION]: false,
},
connectionRoles: {
"connection-uuid": EmbedConnectionRoles.RESTRICTED_QUERIER,
},
});| 参数 | 描述 |
|---|---|
| 实体名称——限定用户的文件夹范围(例如从邮箱域名派生) |
| |
| 必须设置为 |
| 控制Omni的内置UI(例如如果您提供了自己的侧边栏,则隐藏Omni的侧边栏) |
| 授予查询权限: |
Embed Users and Permissions
嵌入用户与权限
When building permission-aware experiences (e.g., a sidebar that only shows dashboards a user can access), use these REST API calls. Note: API calls use the domain, not the embed domain.
.omniapp.co.embed-omniapp.co构建权限感知体验(例如仅显示用户可访问仪表板的侧边栏)时,请使用以下REST API调用。注意:API调用使用域名,而非嵌入域名。
.omniapp.co.embed-omniapp.coLook Up an Embed User
查询嵌入用户
bash
omni scim embed-users-list --filter 'embedExternalId eq "user@example.com"'Returns the Omni user ID for the given . If no user is found, the user hasn't accessed any embedded dashboards yet.
externalIdbash
omni scim embed-users-list --filter 'embedExternalId eq "user@example.com"'返回给定对应的Omni用户ID。如果未找到用户,则表示该用户尚未访问过任何嵌入的仪表板。
externalIdList Documents by User Permission
按用户权限列出文档
bash
omni documents list --userid <omniUserId>Response uses array (not ):
recordsdocumentsjson
{
"pageInfo": {
"hasNextPage": false,
"nextCursor": null,
"pageSize": 20,
"totalRecords": 5
},
"records": [
{
"identifier": "fb007aa3",
"name": "Sales Dashboard",
"hasDashboard": true,
"folder": {
"id": "...",
"name": "Sales",
"path": "sales/regional"
}
}
]
}Use as the for embed signing. Filter for to get embeddable dashboards only.
identifiercontentIdhasDashboard: truebash
omni documents list --userid <omniUserId>响应使用数组(而非):
recordsdocumentsjson
{
"pageInfo": {
"hasNextPage": false,
"nextCursor": null,
"pageSize": 20,
"totalRecords": 5
},
"records": [
{
"identifier": "fb007aa3",
"name": "Sales Dashboard",
"hasDashboard": true,
"folder": {
"id": "...",
"name": "Sales",
"path": "sales/regional"
}
}
]
}使用作为嵌入签名的。筛选以仅获取可嵌入的仪表板。
identifiercontentIdhasDashboard: trueList Folders for Friendly Names
列出文件夹以获取友好名称
Entity folders have technical paths like . Map paths to display names:
omni-system-sso-embed-entity-folder-pocbash
omni folders listBuild a mapping from the response to display user-friendly folder names.
path → name实体文件夹的技术路径类似。将路径映射为显示名称:
omni-system-sso-embed-entity-folder-pocbash
omni folders list从响应中构建的映射关系,以显示用户友好的文件夹名称。
路径 → 名称Domain Mapping
域名映射
The embed domain () and API domain () are different:
.embed-omniapp.co.omniapp.coEmbed: yourorg.embed-omniapp.co → used for iframe URLs
API: yourorg.omniapp.co → used for REST API callsWhen your app stores the embed domain, convert it for API calls by replacing with .
.embed-omniapp.co.omniapp.co嵌入域名()和API域名()不同:
.embed-omniapp.co.omniapp.co嵌入域名: yourorg.embed-omniapp.co → 用于iframe URL
API域名: yourorg.omniapp.co → 用于REST API调用当您的应用存储嵌入域名时,可通过将替换为来转换为API调用域名。
.embed-omniapp.co.omniapp.coDocs Reference
文档参考
Related Skills
相关技能
- omni-content-explorer — find dashboards to embed
- omni-content-builder — create dashboards before embedding them
- omni-admin — manage embed user permissions, user attributes for RLS, and connections
- omni-model-explorer — understand available fields for embed event data
- omni-content-explorer — 查找要嵌入的仪表板
- omni-content-builder — 在嵌入前创建仪表板
- omni-admin — 管理嵌入用户权限、RLS的用户属性以及连接
- omni-model-explorer — 了解嵌入事件数据可用的字段