Overview
The API allows you to customize tabs and groups with custom icons, colors, and titles. All customization methods are asynchronous and return promises.
Tab customization
Setting tab icon
Set a custom icon for a tab. You can use built-in Lucide icon names or register custom icons:
Using built-in icons
const leaf = api.getActiveLeaf();
if (leaf) {
await api.setTabIcon(leaf.id, "star", "my-plugin");
}Using custom icons
To use a custom icon, first register it with Obsidian using addIcon, then reference it by its ID:
import { addIcon } from "obsidian";
// Register a custom icon (do this once during plugin load)
addIcon("my-custom-icon", '<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100"><circle cx="50" cy="50" r="40"/></svg>');
// Use the custom icon on a tab
const leaf = api.getActiveLeaf();
if (leaf) {
await api.setTabIcon(leaf.id, "my-custom-icon", "my-plugin");
}Setting tab color
Set a custom color for a tab using any valid CSS color:
await api.setTabColor(leaf.id, "#ff0000", "my-plugin");
await api.setTabColor(leaf.id, "red", "my-plugin");
await api.setTabColor(leaf.id, "rgb(255, 0, 0)", "my-plugin");Setting tab title
Override the tab’s display title:
await api.setTabTitle(leaf.id, "Custom Title", "my-plugin");Setting ephemeral status
VERSION
Available since: API v1.1.0, Vertical Tabs v0.22.0
Set whether a tab should be ephemeral. Ephemeral tabs are automatically closed when they become inactive and another tab is opened, similar to preview tabs in VSCode:
// Make a tab ephemeral
await api.setTabEphemeral(leaf.id, true, "my-plugin");
// Make a tab non-ephemeral
await api.setTabEphemeral(leaf.id, false, "my-plugin");Getting tab metadata
Retrieve current metadata for a tab:
const metadata = await api.getTabMetadata(leaf.id);
if (metadata) {
console.log("Icon:", metadata.icon);
console.log("Color:", metadata.color);
console.log("Title:", metadata.title);
console.log("Ephemeral:", metadata.isEphemeral);
}Clearing tab metadata
Remove all custom metadata from a tab:
await api.clearTabMetadata(leaf.id, "my-plugin");Group customization
Group customization works identically to tab customization, using group IDs instead of leaf IDs:
const group = api.getActiveGroup();
if (group) {
await api.setGroupIcon(group.id, "folder", "my-plugin");
await api.setGroupColor(group.id, "#00ff00", "my-plugin");
await api.setGroupTitle(group.id, "My Group", "my-plugin");
}
// Get group metadata
const metadata = await api.getGroupMetadata(group.id);
// Clear group metadata
await api.clearGroupMetadata(group.id, "my-plugin");Setting group view type
VERSION
Available since: API v1.2.0, Vertical Tabs v0.24.0
Set how tabs are displayed within a group using one of the four view types:
import { GroupViewType } from "obsidian-vertical-tabs-api";
const group = api.getActiveGroup();
if (group) {
// Standard stacked/tab view (default)
await api.setGroupViewType(group.id, GroupViewType.Default, "my-plugin");
// All tab contents in a continuous scroll
await api.setGroupViewType(group.id, GroupViewType.ContinuousView, "my-plugin");
// Tabs displayed side-by-side
await api.setGroupViewType(group.id, GroupViewType.ColumnView, "my-plugin");
// Fullscreen thumbnail grid of all tabs
await api.setGroupViewType(group.id, GroupViewType.MissionControlView, "my-plugin");
}The view type is persisted to the database and restored when Obsidian restarts. The current viewType is also available in getGroupMetadata:
const metadata = await api.getGroupMetadata(group.id);
console.log("View type:", metadata?.viewType);Setting group hidden state
VERSION
Available since: API v1.2.0, Vertical Tabs v0.24.0
Hide or show a group in the workspace. Hidden groups remain open with all their tabs intact but are not visible. The hidden state is persisted.
const group = api.getActiveGroup();
if (group) {
// Hide the group
await api.setGroupHidden(group.id, true, "my-plugin");
// Show the group again
await api.setGroupHidden(group.id, false, "my-plugin");
}Check the current hidden state via getGroupMetadata:
const metadata = await api.getGroupMetadata(group.id);
console.log("Hidden:", metadata?.isHidden);Setting group collapsed state
VERSION
Available since: API v1.2.0, Vertical Tabs v0.24.0
Collapse or expand a group in the Vertical Tabs sidebar. A collapsed group shows only its header row, hiding the tab list. The tabs remain open. The collapsed state is persisted.
const group = api.getActiveGroup();
if (group) {
// Collapse the group in the sidebar
await api.setGroupCollapsed(group.id, true, "my-plugin");
// Expand the group
await api.setGroupCollapsed(group.id, false, "my-plugin");
}Check the current collapsed state via getGroupMetadata:
const metadata = await api.getGroupMetadata(group.id);
console.log("Collapsed:", metadata?.isCollapsed);Source parameter
The optional source parameter identifies which plugin made the change. This is important for preventing infinite loops when listening to metadata change events:
// Listen to metadata changes
this.registerEvent(
this.app.workspace.on("vertical-tabs:metadata-changed", (event) => {
// Ignore changes made by this plugin
if (event.source === "my-plugin") return;
// Handle changes from other sources
console.log(`${event.type} ${event.id} changed`);
})
);
// Make changes with source identifier
await api.setTabIcon(leaf.id, "star", "my-plugin");Always provide a source parameter when making changes in response to events to prevent infinite loops.
Icon reference
Built-in icons
See the Lucide icon library for the complete list of available built-in icons.
Custom icons
To register custom SVG icons with Obsidian:
import { addIcon } from "obsidian";
addIcon("icon-id", '<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100"><!-- SVG content --></svg>');The icon ID must be unique. Once registered, custom icons can be used with setTabIcon and setGroupIcon just like built-in icons.