Browse API 1 documentation
grove.webPane.open()
Open or reuse an isolated packaged HTML page beside a joined channel.
Open or reuse an isolated packaged HTML page beside a joined channel.
Signature
grove.webPane.open(path: string, options: { channel: string; id?: string }): void
Availability
Server-scoped headless Root with ui.web-pane. Network data requests inside the page require matching accepted hostPermissions. Unavailable to tabs, visible panes/windows, conversation Roots, composer utilities, application Roots, and settings pages.
Parameters
| Parameter | Required | Description |
|---|---|---|
path |
Yes | Package-root-relative .html or .htm path, optionally with query parameters. The resolved URL must fit 4,096 UTF-8 bytes. No remote/absolute URLs, traversal, or fragments. A leading / is allowed. |
options.channel |
Yes | Explicit confirmed joined channel on this network; same channel validation as grove.send. |
options.id |
No | Reuse identifier, default main. Up to 64 characters; trimmed/lowercased, using letters, numbers, hyphen, underscore, or dot. |
Return value
Returns undefined; no window handle, response body, or navigation Promise.
Behavior and errors
Overlong paths or IDs throw RangeError synchronously in the facade. Native validation refuses missing grants, invalid values, unjoined channels, and non-package pages. Reusing an id replaces/selects the same logical pane. The page has no Grove bridge or IRC context and uses ephemeral browser storage. It receives the same packaged-script CSP and approved network data origins as its owner. Top-level navigation stays within packaged HTML; deliberate external links follow Mango’s ordinary link behavior. The pane closes with its owner.
Remote pages previously accepted by this API are now rejected. Bundle the UI and its JavaScript dependencies in the .grove package and use fetch for data (subject to browser CORS). Treat query parameters and API responses as untrusted data. Never turn them into scripts or unsanitized HTML. A user-opened isolated Web tab remains available for normal website browsing.
Example
// Requires ui.member-actions as well for the menu contribution.
grove.on('memberAction', event => {
if (event.action !== 'profile') return
grove.webPane.open('profile.html?user=' + encodeURIComponent(event.member), {
channel: event.channel, id: 'profile'
})
})
grove.memberActions.register([{ id: 'profile', label: 'Show profile' }])
See Security model.