Creating a new filetype in Obsidian
When building plugins for Obsidian, something you may find yourself wanting to add is the ability for your plugin to have it’s own filetype. So that Obsidian will show that file in the file browser and allow your plugin to be responsible for opening and viewing it.
This article steps through that setup at a very high level.
A basic plugin needs a main.js file. So we’ll put any code in this article directly in there with a basic plugin definition. We’ll put our code directly in the onload method so that it runs as soon as Obsidian loads.
// main.js:
import { Plugin } from "obsidian";
export default class ExamplePlugin extends Plugin {
async onload() {
// The below code goes here.
}
}
If you’re completely new to Obsidian plugin development, you probably don’t know what to do with that. You can learn how to get this working by following their official documentation.
What type of file do you need?
While you want a new file type, that doesn’t mean it needs to be a completely new format of view. Obsidian already has some inbuilt view types that define how it displays data in various files.
If it’s markdown
If you’d like to support markdown editing on your new file format, you can rely on Obsidian’s inbuilt markdown view type even though it will show as a different file type in the file browser.
Perhaps you want a PHD file format because you’re creating a plugin tailored for PhD students? You’ll want a standard Markdown editor for the most part, so here we register the new extension for the file format, but we specify it is the existing a ‘markdown’ view type — Which Obsidian already knows how to handle.
this.registerExtensions(['phd'], 'markdown');
Because this code is placed inside the plugin class (In the onload method), ‘this’ refers to your plugin.
If it’s a custom format
If what you want to implement is different to any type of view Obsidian already supports, then you’ll need to specify a new view type and define how it works.
In this example, I’m creating a file extension of ‘handwriting’ and linking it to a new view type.
plugin.registerExtensions(['handwriting'], HANDWRITING_VIEW_TYPE);
The view type is defined in another file and has a structure like the below example. You can learn about it in more detail on the official documentation page.
export const HANDWRITING_VIEW_TYPE = "handwriting-view";
export class HandwritingView extends ItemView {
constructor(leaf: WorkspaceLeaf) {
super(leaf);
}
getViewType() {
return HANDWRITING_VIEW_TYPE;
}
getDisplayText() {
return "Handwriting";
}
async onOpen() {
const container = this.containerEl.children[1];
container.empty();
container.createEl("h4", { text: "This is a handwriting view" });
}
async onClose() {
// Nothing to clean up.
}
}
Lastly, you need to link the view type to the view itself. By registering this link in the onload method.
this.registerView( HANDWRITING_VIEW_TYPE, (leaf) => new HandwritingView(leaf) );
Now, we’re told the plugin that files with the extension ‘handwriting’ open a view of type HANDWRITING_VIEW_TYPE, and the way to open that type of view, start a new HandwritingView in the current interface leaf.
Note:
When creating a new view type, I’ve found that I need to restart Obsidian entirely for it to work. Not just “force reload”, but actually restart. This is a gotcha that has cost me some time in the past, so hopefully this saves you a little.
Test your file type
We haven’t actually built anything novel into the example in this article as it’s just about the high level implementation and the difference between view types, however, you probably want to test if it’s working.
You can create a file to test by manually creating a basic text file in your vault and rename the extension appropriately. (e.g. test.handwriting or test.phd).
That’s it!
I’d suggest start with the phd markdown example first and test it, then try the custom view type once you know that’s working.
Feel free to drop a comment or get in touch on social media if you hit any roadblocks.
Thanks…
I also dissect and speculate on design and development.
Digging into subtle details and implications, and exploring broad perspectives and potential paradigm shifts.
Check out my conceptual articles on Substack or find my latest below.
You can also find me on Threads, Bluesky, Mastodon, or X for more diverse posts about ongoing projects.