Overview
The Vertical Tabs plugin emits several workspace events that your plugin can listen to. These events notify you of plugin lifecycle changes, metadata updates, and workspace refresh operations.
Plugin lifecycle
Load event
Fired when the Vertical Tabs plugin loads and the API becomes available:
this.registerEvent(
this.app.workspace.on("vertical-tabs:load", () => {
console.log("Vertical Tabs is ready");
const vtPlugin = this.app.plugins.getPlugin("vertical-tabs");
// API is now available
})
);Unload event
Fired when the Vertical Tabs plugin is about to unload:
this.registerEvent(
this.app.workspace.on("vertical-tabs:unload", () => {
console.log("Vertical Tabs is unloading");
// Clean up any references to the API
})
);Important: For robust integration that handles load and unload correctly, see Safe API Access.
Metadata changes
Fired when tab or group metadata is changed through the API:
this.registerEvent(
this.app.workspace.on("vertical-tabs:metadata-changed", (event) => {
console.log("Type:", event.type); // "tab" or "group"
console.log("ID:", event.id); // Identifier
console.log("Source:", event.source); // Optional plugin identifier
console.log("Metadata:", event.metadata);
})
);Event data:
interface MetadataChangeEvent {
type: "tab" | "group";
id: string;
metadata: APITabMetadata | APIGroupMetadata;
source?: string;
}Preventing infinite loops:
When listening to metadata changes and making changes in response, always check the source parameter to avoid infinite loops:
this.registerEvent(
this.app.workspace.on("vertical-tabs:metadata-changed", (event) => {
// Ignore changes made by this plugin
if (event.source === "my-plugin") return;
// React to changes from other sources
if (event.type === "tab") {
console.log("Tab metadata changed:", event.id);
}
})
);
// When making changes, provide source identifier
await api.setTabIcon(leaf.id, "star", "my-plugin");Workspace refresh
Fired when tabs or groups are opened or closed. The event provides details about which tabs and groups were added or removed:
this.registerEvent(
this.app.workspace.on("vertical-tabs:refresh", (event) => {
console.log("New tabs:", event.newTabs);
console.log("Closed tabs:", event.closedTabs);
console.log("New groups:", event.newGroups);
console.log("Closed groups:", event.closedGroups);
})
);Event data:
interface RefreshEvent {
newTabs: string[]; // IDs of newly opened tabs
newGroups: string[]; // IDs of newly created groups
closedTabs: string[]; // IDs of closed tabs
closedGroups: string[]; // IDs of closed groups
}Important: This event only fires when changes are detected. If no tabs or groups were opened or closed during a refresh operation, the event will not fire.
Use cases:
- Track workspace state changes
- React to new tabs being opened
- Clean up when tabs are closed
- Monitor group creation and deletion
this.registerEvent(
this.app.workspace.on("vertical-tabs:refresh", (event) => {
// Initialize metadata for new tabs
for (const tabId of event.newTabs) {
await api.setTabIcon(tabId, "file-text", "my-plugin");
}
// Clean up data for closed tabs
for (const tabId of event.closedTabs) {
this.cleanupTabData(tabId);
}
})
);Event registration
Always use registerEvent to ensure events are properly cleaned up when your plugin unloads:
export default class MyPlugin extends Plugin {
async onload() {
// Register all events using this.registerEvent
this.registerEvent(
this.app.workspace.on("vertical-tabs:load", () => {
// Handle load
})
);
}
// Events are automatically cleaned up on unload
}