Skip to main content
The FileView class extends ItemView and is designed for views that display or edit files. It handles file loading, unloading, and state management.

Properties

allowNoFile
boolean
Whether this view can exist without a file.
file
TFile | null
The file currently displayed in this view, or null if no file is loaded.
navigation
boolean
File views can be navigated by default.Default: true

Inherited Properties

FileView inherits properties from ItemView and View:
  • contentEl: HTMLElement
  • app: App
  • icon: IconName
  • leaf: WorkspaceLeaf
  • containerEl: HTMLElement
  • scope: Scope | null

Constructor

constructor(leaf: WorkspaceLeaf)
leaf
WorkspaceLeaf
required
The workspace leaf this view will be attached to

Methods

getDisplayText()

Gets the display text for this view. By default, returns the file basename.
getDisplayText(): string
return
string
The display text (file name or custom text)

onload()

Called when the view is loaded.
onload(): void

getState()

Gets the current state of this view, including the file path.
getState(): Record<string, unknown>
return
Record<string, unknown>
The current view state including file path
Since: 0.9.7

setState()

Sets the state of this view, loading the specified file.
setState(state: any, result: ViewStateResult): Promise<void>
state
any
required
The state to set, typically includes a file property with the file path
result
ViewStateResult
required
Result object to indicate if state change should be recorded in history
return
Promise<void>
Promise that resolves when state is set
Since: 0.9.7

onLoadFile()

Called when a file is loaded into this view. Override this to handle file loading.
onLoadFile(file: TFile): Promise<void>
file
TFile
required
The file being loaded
return
Promise<void>
Promise that resolves when file is loaded

onUnloadFile()

Called when a file is unloaded from this view. Override this to handle cleanup.
onUnloadFile(file: TFile): Promise<void>
file
TFile
required
The file being unloaded
return
Promise<void>
Promise that resolves when file is unloaded

onRename()

Called when the file is renamed. Override this to handle file renames.
onRename(file: TFile): Promise<void>
file
TFile
required
The renamed file
return
Promise<void>
Promise that resolves when rename is handled

canAcceptExtension()

Determines whether this view can display files with the given extension.
canAcceptExtension(extension: string): boolean
extension
string
required
The file extension (without the dot)
return
boolean
Whether this view can display files with the given extension
Since: 0.9.7

Creating a Custom FileView

Here’s an example of creating a custom file view for a specific file type:
import { FileView, TFile, WorkspaceLeaf } from 'obsidian';

const VIEW_TYPE_JSON = 'json-view';

class JsonView extends FileView {
  data: any;

  constructor(leaf: WorkspaceLeaf) {
    super(leaf);
  }

  getViewType() {
    return VIEW_TYPE_JSON;
  }

  getDisplayText() {
    return this.file?.basename ?? 'JSON View';
  }

  async onLoadFile(file: TFile) {
    // Read and parse the JSON file
    const content = await this.app.vault.read(file);
    try {
      this.data = JSON.parse(content);
      this.renderData();
    } catch (e) {
      this.contentEl.setText('Invalid JSON: ' + e.message);
    }
  }

  async onUnloadFile(file: TFile) {
    // Clean up
    this.data = null;
    this.contentEl.empty();
  }

  renderData() {
    const container = this.contentEl;
    container.empty();

    container.createEl('h4', { text: 'JSON Data' });
    container.createEl('pre', {
      text: JSON.stringify(this.data, null, 2)
    });
  }

  canAcceptExtension(extension: string) {
    return extension === 'json';
  }

  async onClose() {
    this.data = null;
  }
}

Registering a FileView

import { Plugin } from 'obsidian';

export default class JsonViewPlugin extends Plugin {
  async onload() {
    // Register the view
    this.registerView(
      VIEW_TYPE_JSON,
      (leaf) => new JsonView(leaf)
    );

    // Register the view for .json files
    this.registerExtensions(['json'], VIEW_TYPE_JSON);

    // Add command to open JSON files in this view
    this.addCommand({
      id: 'open-as-json',
      name: 'Open as JSON view',
      callback: () => {
        const file = this.app.workspace.getActiveFile();
        if (file && file.extension === 'json') {
          const leaf = this.app.workspace.getLeaf(false);
          leaf.setViewState({
            type: VIEW_TYPE_JSON,
            state: { file: file.path }
          });
        }
      }
    });
  }

  async onunload() {
    this.app.workspace.detachLeavesOfType(VIEW_TYPE_JSON);
  }
}

Handling File Changes

You can listen to file changes and update your view:
class MyFileView extends FileView {
  async onLoadFile(file: TFile) {
    // Initial load
    await this.loadAndRender(file);

    // Listen for changes
    this.registerEvent(
      this.app.vault.on('modify', (modifiedFile) => {
        if (modifiedFile === this.file) {
          this.loadAndRender(modifiedFile);
        }
      })
    );
  }

  async loadAndRender(file: TFile) {
    const content = await this.app.vault.read(file);
    // Render content
    this.contentEl.empty();
    this.contentEl.setText(content);
  }
}

State Management

class MyFileView extends FileView {
  scrollPosition: number = 0;

  getState() {
    const state = super.getState();
    state.scrollPosition = this.scrollPosition;
    return state;
  }

  async setState(state: any, result: ViewStateResult) {
    await super.setState(state, result);
    this.scrollPosition = state.scrollPosition || 0;
    
    // Restore scroll position after render
    this.contentEl.scrollTop = this.scrollPosition;
  }

  onResize() {
    // Save scroll position
    this.scrollPosition = this.contentEl.scrollTop;
  }
}

Best Practices

1. Always check if file exists

async onLoadFile(file: TFile) {
  if (!file) return;
  
  const exists = await this.app.vault.adapter.exists(file.path);
  if (!exists) {
    this.contentEl.setText('File not found');
    return;
  }
  
  // Load file...
}

2. Handle errors gracefully

async onLoadFile(file: TFile) {
  try {
    const content = await this.app.vault.read(file);
    this.renderContent(content);
  } catch (error) {
    this.contentEl.setText(`Error loading file: ${error.message}`);
  }
}

3. Clean up resources

async onUnloadFile(file: TFile) {
  // Cancel any pending operations
  this.cancelPendingOperations();
  
  // Clear data
  this.data = null;
  
  // Clear UI
  this.contentEl.empty();
}

4. Update display text on rename

async onRename(file: TFile) {
  // The leaf will automatically update the tab title
  // You may want to update internal references
  this.file = file;
}

See Also

Build docs developers (and LLMs) love