README file from
GithubBookmark API
An Obsidian plugin that exposes global functions for programmatically managing bookmarks. Designed for use with Templater, Dataview, or any script that runs inside Obsidian.
Requirements
- Obsidian's built-in Bookmarks core plugin must be enabled (Settings → Core Plugins → Bookmarks)
Building
npm install
npm run build
This produces main.js in the project root.
Installation
Copy main.js and manifest.json into your vault's plugin directory:
VAULT/.obsidian/plugins/bookmark-api/
├── main.js
└── manifest.json
Then enable Bookmark API in Obsidian's Community Plugins settings.
API
All functions are registered on window when the plugin loads and can be called directly by name. Every filePath parameter is optional — if omitted, the currently active file is used. Paths without a .md extension are normalized automatically.
| Function | Description |
|---|---|
addBookmark(groupName, filePath?, title?) |
Add a file to a group (creates group if needed) |
removeBookmark(groupName, filePath?) |
Remove a file from a group |
moveBookmark(fromGroup, toGroup, filePath?) |
Move a file between groups |
removeBookmarkGroup(groupName, deleteFiles?) |
Delete a group and optionally trash its files |
addBookmark(groupName, filePath?, title?)
Add a file to a bookmark group. Creates the group if it doesn't exist. Duplicates are skipped.
The optional title parameter sets a custom display name for the bookmark (instead of showing the filename).
await addBookmark("Research", "Notes/Quantum Computing.md");
// Bookmark the active file
await addBookmark("Research");
// Bookmark with a custom display title
await addBookmark("Reading List", "Books/Deep Work.md", "Deep Work by Cal Newport");
removeBookmark(groupName, filePath?)
Remove a file from a bookmark group.
await removeBookmark("Research", "Notes/Quantum Computing.md");
// Remove the active file
await removeBookmark("Research");
moveBookmark(fromGroup, toGroup, filePath?)
Move a file from one bookmark group to another. The destination group is created if it doesn't exist. The bookmark entry (including any custom title) is preserved.
await moveBookmark("Research", "Archive", "Notes/Quantum Computing.md");
// Move the active file
await moveBookmark("Research", "Archive");
removeBookmarkGroup(groupName, deleteFiles?)
Delete an entire bookmark group and all its entries. If deleteFiles is true, the actual files are also sent to Obsidian's trash (.trash/ folder), so they remain recoverable. Defaults to false.
// Remove the group, keep the files
await removeBookmarkGroup("Old Notes");
// Remove the group AND trash all the files in it
await removeBookmarkGroup("Old Notes", true);
Usage with Templater
Templater lets you run JavaScript inside <%* %> blocks. Because the Bookmark API functions are registered on window, you can call them directly.
Bookmark the current file when the template runs
<%* await addBookmark("Inbox") %>
Prompt for a group name, then bookmark
<%*
const group = await tp.system.prompt("Bookmark group:");
if (group) await addBookmark(group);
%>
Add with a custom display title
<%*
const title = await tp.system.prompt("Display title:");
await addBookmark("Reading List", tp.file.path(true), title);
%>
Move the current file between groups
<%* await moveBookmark("Inbox", "Reviewed") %>
Remove the current file from a group
<%* await removeBookmark("Inbox") %>
Tip: Templater's
tp.file.path(true)returns the full vault-relative path of the current file. You only need to pass it explicitly when calling the API from a different context than the active file.
Usage with DataviewJS
Dataview provides dataviewjs code blocks for inline scripting. The Bookmark API functions are available on window just like in Templater, and top-level await works inside dataviewjs blocks.
Bookmark the current file
```dataviewjs
await addBookmark("Favorites", dv.current().file.path);
```
List files in a folder, then bookmark all of them
```dataviewjs
const pages = dv.pages('"Projects/Active"');
for (const page of pages) {
await addBookmark("Active Projects", page.file.path, page.file.name);
}
```
Remove a specific file from a group
```dataviewjs
await removeBookmark("Archive", "Notes/Old Note.md");
```
Conditionally bookmark based on tags
```dataviewjs
const page = dv.current();
if (page.tags?.includes("important")) {
await addBookmark("Important", page.file.path);
}
```
Note: In DataviewJS, use
dv.current().file.pathto reference the file containing the code block. IffilePathis omitted, the API falls back to the active file, which may differ from the file the code block lives in.
Key differences
| Templater | DataviewJS | |
|---|---|---|
| Syntax | <%* await addBookmark("Group") %> |
`dataviewjs` code block |
| Current file | Omit filePath (uses active file) or use tp.file.path(true) |
Use dv.current().file.path for the note containing the block |
| When it runs | On template insertion or Templater command | Every time the note is opened/rendered |
| Best for | One-time actions (bookmark on creation, move on review) | Dynamic/conditional logic tied to note metadata |
Commands
Two commands are available from the command palette:
- Add file to bookmark group -- opens a searchable modal of existing groups (or type a new name) and adds the active file.
- Remove file from bookmark group -- opens a searchable modal and removes the active file from the selected group.