Skip to main content
The Workspace class manages the workspace layout, including splits, leaves, and views. It is the central component for managing the UI layout of Obsidian.

Properties

leftSplit
WorkspaceSidedock | WorkspaceMobileDrawer
The left sidebar split.Since: 0.9.7
rightSplit
WorkspaceSidedock | WorkspaceMobileDrawer
The right sidebar split.Since: 0.9.7
leftRibbon
WorkspaceRibbon
The left ribbon (sidebar icons).Since: 0.9.7
rightRibbon
WorkspaceRibbon
The right ribbon.Deprecated: No longer used
rootSplit
WorkspaceRoot
The root split containing the main workspace area.Since: 0.9.7
activeLeaf
WorkspaceLeaf | null
Indicates the currently focused leaf, if one exists.
The use of this field is discouraged. The recommended alternatives are:
  • If you need information about the current view, use getActiveViewOfType()
  • If you need to open a new file or navigate a view, use getLeaf()
Since: 0.9.7Deprecated: Use alternatives mentioned above
containerEl
HTMLElement
The container element for the workspace.Since: 0.9.7
layoutReady
boolean
Whether the layout of the app has been successfully initialized.To react to the layout becoming ready, use onLayoutReady().Since: 0.9.7
requestSaveLayout
Debouncer<[], Promise<void>>
Save the state of the current workspace layout.Since: 0.16.0
activeEditor
MarkdownFileInfo | null
A component managing the current editor. This can be null if the active view has no editor.

Methods

onLayoutReady()

Runs the callback function right away if layout is already ready, or pushes it to a queue to be called later when layout is ready.
onLayoutReady(callback: () => any): void
callback
() => any
required
Function to call when layout is ready
Since: 0.11.0

Example

this.app.workspace.onLayoutReady(() => {
  console.log('Workspace layout is ready!');
});

changeLayout()

Changes the workspace layout.
changeLayout(workspace: any): Promise<void>
workspace
any
required
The workspace layout configuration
return
Promise<void>
Promise that resolves when the layout change is complete
Since: 0.9.7

getLayout()

Gets the current workspace layout configuration.
getLayout(): Record<string, unknown>
return
Record<string, unknown>
The current layout configuration
Since: 0.9.7

createLeafInParent()

Creates a new leaf inside a parent split at a specific index.
createLeafInParent(parent: WorkspaceSplit, index: number): WorkspaceLeaf
parent
WorkspaceSplit
required
The parent split to create the leaf in
index
number
required
The index position for the new leaf
return
WorkspaceLeaf
The newly created leaf
Since: 0.9.11

createLeafBySplit()

Creates a new leaf by splitting an existing leaf.
createLeafBySplit(
  leaf: WorkspaceLeaf,
  direction?: SplitDirection,
  before?: boolean
): WorkspaceLeaf
leaf
WorkspaceLeaf
required
The leaf to split
direction
SplitDirection
Direction to split (‘vertical’ or ‘horizontal’)
before
boolean
Whether to create the new leaf before or after the existing leaf
return
WorkspaceLeaf
The newly created leaf
Since: 0.9.7

getLeaf()

Gets or creates a leaf for opening content.
// Get an existing navigable leaf or create a new one
getLeaf(newLeaf?: PaneType | boolean): WorkspaceLeaf

// Create a new leaf by splitting
getLeaf(newLeaf: 'split', direction?: SplitDirection): WorkspaceLeaf
newLeaf
PaneType | boolean
  • false or not set: Return an existing leaf or create a new one
  • true or 'tab': Create a new leaf in the preferred location
  • 'split': Create a new leaf adjacent to the active leaf
  • 'window': Create a popout window with a new leaf
direction
SplitDirection
When newLeaf is 'split':
  • 'vertical': New leaf appears to the right
  • 'horizontal': New leaf appears below
return
WorkspaceLeaf
The leaf to use
Since: 0.16.0

Example

// Get any available leaf
const leaf = this.app.workspace.getLeaf(false);

// Create a new tab
const newTab = this.app.workspace.getLeaf('tab');

// Split vertically
const splitLeaf = this.app.workspace.getLeaf('split', 'vertical');

moveLeafToPopout()

Migrates a leaf to a new popout window. Only works on desktop.
moveLeafToPopout(
  leaf: WorkspaceLeaf,
  data?: WorkspaceWindowInitData
): WorkspaceWindow
leaf
WorkspaceLeaf
required
The leaf to move to a popout window
data
WorkspaceWindowInitData
Optional window initialization data (position and size)
return
WorkspaceWindow
The created workspace window
Since: 0.15.4 Throws: Error if the app does not support popout windows (mobile or old Electron version)

openPopoutLeaf()

Opens a new popout window with a single new leaf. Only works on desktop.
openPopoutLeaf(data?: WorkspaceWindowInitData): WorkspaceLeaf
data
WorkspaceWindowInitData
Optional window initialization data (position and size)
return
WorkspaceLeaf
The newly created leaf in the popout window
Since: 0.15.4

openLinkText()

Opens a link in the workspace.
openLinkText(
  linktext: string,
  sourcePath: string,
  newLeaf?: PaneType | boolean,
  openViewState?: OpenViewState
): Promise<void>
linktext
string
required
The link text to open
sourcePath
string
required
The path of the source file (for resolving relative links)
newLeaf
PaneType | boolean
Where to open the link (see getLeaf() for options)
openViewState
OpenViewState
Additional view state options
return
Promise<void>
Promise that resolves when the link is opened
Since: 0.16.0

setActiveLeaf()

Sets the active leaf in the workspace.
setActiveLeaf(
  leaf: WorkspaceLeaf,
  params?: { focus?: boolean }
): void
leaf
WorkspaceLeaf
required
The leaf to make active
params
object
Parameter object
  • focus: Whether to focus the leaf (default: true)
Since: 0.16.3

Example

const leaf = this.app.workspace.getLeaf(false);
this.app.workspace.setActiveLeaf(leaf, { focus: true });

getLeafById()

Retrieves a leaf by its ID.
getLeafById(id: string): WorkspaceLeaf | null
id
string
required
ID of the leaf to retrieve
return
WorkspaceLeaf | null
The leaf with the given ID, or null if not found
Since: 1.5.1

getGroupLeaves()

Gets all leaves that belong to a group.
getGroupLeaves(group: string): WorkspaceLeaf[]
group
string
required
Group ID
return
WorkspaceLeaf[]
Array of leaves in the group
Since: 0.9.7

getMostRecentLeaf()

Gets the most recently active leaf in a given workspace root.
getMostRecentLeaf(root?: WorkspaceParent): WorkspaceLeaf | null
root
WorkspaceParent
Root for the leaves to search. If not provided, searches rootSplit and pop-out windows
return
WorkspaceLeaf | null
The most recently active leaf, or null if none found
Since: 0.15.4

getLeftLeaf()

Creates a new leaf inside the left sidebar.
getLeftLeaf(split: boolean): WorkspaceLeaf | null
split
boolean
required
Whether to split the existing sidebar
return
WorkspaceLeaf | null
The created leaf, or null if failed
Since: 0.9.7

getRightLeaf()

Creates a new leaf inside the right sidebar.
getRightLeaf(split: boolean): WorkspaceLeaf | null
split
boolean
required
Whether to split the existing sidebar
return
WorkspaceLeaf | null
The created leaf, or null if failed
Since: 0.9.7

ensureSideLeaf()

Gets a side leaf or creates one if it does not exist.
ensureSideLeaf(
  type: string,
  side: Side,
  options?: {
    active?: boolean;
    split?: boolean;
    reveal?: boolean;
    state?: any;
  }
): Promise<WorkspaceLeaf>
type
string
required
The view type to ensure exists
side
Side
required
Which side (‘left’ or ‘right’)
options
object
  • active: Whether to make the leaf active
  • split: Whether to split if creating a new leaf
  • reveal: Whether to reveal the leaf
  • state: Initial state for the view
return
Promise<WorkspaceLeaf>
The existing or newly created leaf
Since: 1.7.2

getActiveViewOfType()

Gets the currently active view of a given type.
getActiveViewOfType<T extends View>(type: Constructor<T>): T | null
type
Constructor<T>
required
The constructor of the view type to retrieve
return
T | null
The active view of the specified type, or null if none
Since: 0.9.16

Example

import { MarkdownView } from 'obsidian';

const view = this.app.workspace.getActiveViewOfType(MarkdownView);
if (view) {
  const editor = view.editor;
  console.log(editor.getValue());
}

getActiveFile()

Returns the file for the current view if it’s a FileView. Otherwise, returns the most recently active file.
getActiveFile(): TFile | null
return
TFile | null
The active file, or null if none

Example

const file = this.app.workspace.getActiveFile();
if (file) {
  console.log('Active file:', file.path);
}

iterateRootLeaves()

Iterates through all leaves in the main area of the workspace.
iterateRootLeaves(callback: (leaf: WorkspaceLeaf) => any): void
callback
(leaf: WorkspaceLeaf) => any
required
Function to call for each leaf
Since: 0.9.7

Example

this.app.workspace.iterateRootLeaves((leaf) => {
  console.log('Leaf type:', leaf.view.getViewType());
});

iterateAllLeaves()

Iterates through all leaves, including main area leaves, floating leaves, and sidebar leaves.
iterateAllLeaves(callback: (leaf: WorkspaceLeaf) => any): void
callback
(leaf: WorkspaceLeaf) => any
required
Function to call for each leaf
Since: 0.9.7

getLeavesOfType()

Gets all leaves of a given type.
getLeavesOfType(viewType: string): WorkspaceLeaf[]
viewType
string
required
The view type to search for
return
WorkspaceLeaf[]
Array of leaves with the specified view type
Since: 0.9.7

detachLeavesOfType()

Removes all leaves of the given type.
detachLeavesOfType(viewType: string): void
viewType
string
required
The view type to remove
Since: 0.9.7

revealLeaf()

Brings a given leaf to the foreground. If the leaf is in a sidebar, the sidebar will be uncollapsed.
revealLeaf(leaf: WorkspaceLeaf): Promise<void>
leaf
WorkspaceLeaf
required
The leaf to reveal
return
Promise<void>
Promise that resolves when the leaf is fully loaded and revealed
Await this function to ensure your view has been fully loaded and is not deferred.
Since: 1.7.2

getLastOpenFiles()

Gets the filenames of the 10 most recently opened files.
getLastOpenFiles(): string[]
return
string[]
Array of file paths (up to 10)
Since: 0.9.7

updateOptions()

Updates/reconfigures the options of all Markdown views.
This is fairly expensive and should not be called frequently.
updateOptions(): void
Since: 0.13.21

handleLinkContextMenu()

Adds a context menu to internal file links.
handleLinkContextMenu(
  menu: Menu,
  linktext: string,
  sourcePath: string,
  leaf?: WorkspaceLeaf
): boolean
menu
Menu
required
The menu to add items to
linktext
string
required
The link text
sourcePath
string
required
The source file path
leaf
WorkspaceLeaf
Optional leaf context
return
boolean
Whether the menu was handled
Since: 0.12.10

Events

The Workspace class extends Events and provides several events you can listen to:

quick-preview

Triggered when the active Markdown file is modified. React to file changes before they are saved to disk.
this.registerEvent(
  this.app.workspace.on('quick-preview', (file: TFile, data: string) => {
    console.log('File modified:', file.path);
  })
);
Since: 0.9.7

resize

Triggered when a WorkspaceItem is resized or the workspace layout has changed.
this.registerEvent(
  this.app.workspace.on('resize', () => {
    console.log('Workspace resized');
  })
);
Since: 0.9.7

active-leaf-change

Triggered when the active leaf changes.
this.registerEvent(
  this.app.workspace.on('active-leaf-change', (leaf: WorkspaceLeaf | null) => {
    console.log('Active leaf changed');
  })
);
Since: 0.10.9

file-open

Triggered when the active file changes. The file could be in a new leaf, an existing leaf, or an embed.
this.registerEvent(
  this.app.workspace.on('file-open', (file: TFile | null) => {
    if (file) {
      console.log('Opened file:', file.path);
    }
  })
);
Since: 0.10.9

layout-change

Triggered when the workspace layout changes.
this.registerEvent(
  this.app.workspace.on('layout-change', () => {
    console.log('Layout changed');
  })
);
Since: 0.9.20

window-open

Triggered when a new popout window is created.
this.registerEvent(
  this.app.workspace.on('window-open', (win: WorkspaceWindow, window: Window) => {
    console.log('Window opened');
  })
);
Since: 0.15.3

window-close

Triggered when a popout window is closed.
this.registerEvent(
  this.app.workspace.on('window-close', (win: WorkspaceWindow, window: Window) => {
    console.log('Window closed');
  })
);
Since: 0.15.3

css-change

Triggered when the CSS of the app has changed.
this.registerEvent(
  this.app.workspace.on('css-change', () => {
    console.log('CSS changed');
  })
);
Since: 0.9.7

file-menu

Triggered when the user opens the context menu on a file.
this.registerEvent(
  this.app.workspace.on('file-menu', (menu, file, source, leaf) => {
    menu.addItem((item) => {
      item.setTitle('My custom action').onClick(() => {
        console.log('Action on:', file.path);
      });
    });
  })
);
Since: 0.9.12

files-menu

Triggered when the user opens the context menu with multiple files selected in the File Explorer.
this.registerEvent(
  this.app.workspace.on('files-menu', (menu, files, source, leaf) => {
    menu.addItem((item) => {
      item.setTitle(`Process ${files.length} files`).onClick(() => {
        // Process multiple files
      });
    });
  })
);
Since: 1.4.10

url-menu

Triggered when the user opens the context menu on an external URL.
this.registerEvent(
  this.app.workspace.on('url-menu', (menu, url) => {
    menu.addItem((item) => {
      item.setTitle('Copy URL').onClick(() => {
        navigator.clipboard.writeText(url);
      });
    });
  })
);
Since: 1.5.1

editor-menu

Triggered when the user opens the context menu on an editor.
this.registerEvent(
  this.app.workspace.on('editor-menu', (menu, editor, info) => {
    menu.addItem((item) => {
      item.setTitle('Insert text').onClick(() => {
        editor.replaceSelection('Hello!');
      });
    });
  })
);
Since: 1.1.0

editor-change

Triggered when changes to an editor have been applied, either programmatically or from a user event.
this.registerEvent(
  this.app.workspace.on('editor-change', (editor, info) => {
    console.log('Editor content changed');
  })
);
Since: 1.1.1

editor-paste

Triggered when the editor receives a paste event.
Check for evt.defaultPrevented before handling, and use evt.preventDefault() to indicate that you’ve handled the event.
this.registerEvent(
  this.app.workspace.on('editor-paste', (evt, editor, info) => {
    if (evt.defaultPrevented) return;
    
    // Handle paste
    evt.preventDefault();
  })
);
Since: 1.1.0

editor-drop

Triggered when the editor receives a drop event.
Check for evt.defaultPrevented before handling, and use evt.preventDefault() to indicate that you’ve handled the event.
this.registerEvent(
  this.app.workspace.on('editor-drop', (evt, editor, info) => {
    if (evt.defaultPrevented) return;
    
    // Handle drop
    evt.preventDefault();
  })
);
Since: 1.1.0

quit

Triggered when the app is about to quit. Not guaranteed to actually run. Perform best effort cleanup here.
this.registerEvent(
  this.app.workspace.on('quit', (tasks) => {
    // Cleanup
  })
);
Since: 0.10.2

Build docs developers (and LLMs) love