Skip to content

feat(desktop): add trilium:// URL protocol support#9707

Closed
Nelson1312-dak wants to merge 3 commits into
TriliumNext:mainfrom
Nelson1312-dak:main
Closed

feat(desktop): add trilium:// URL protocol support#9707
Nelson1312-dak wants to merge 3 commits into
TriliumNext:mainfrom
Nelson1312-dak:main

Conversation

@Nelson1312-dak
Copy link
Copy Markdown

@Nelson1312-dak Nelson1312-dak commented May 12, 2026

Closes #649

Changes

  • Register trilium:// as default protocol client on app startup
  • Extract extractNoteIdFromArgs() helper to avoid duplicated URL parsing logic
  • Use module-level pendingNoteId variable instead of global for type safety
  • Replace hardcoded setTimeout with webContents.once("did-finish-load") to eliminate race condition
  • Remove duplicate requestSingleInstanceLock() call
  • Handle second-instance protocol URLs by sending IPC to focused window
  • Add open-note-by-id IPC listener in renderer to open note by ID

Fixes from previous attempt (#9248)

  • No hardcoded timeouts
  • URL parsing via new URL() — handles trilium:///noteId correctly
  • No global object usage
  • DRY: single parse function used in both launch and second-instance paths

IssueHunt Summary

Referenced issues

This pull request has been submitted to:


@dosubot dosubot Bot added the size:M This PR changes 30-99 lines, ignoring generated files. label May 12, 2026
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces support for the trilium:// protocol, allowing the desktop application to open specific notes via external links. The implementation includes logic for registering the protocol handler, parsing note IDs from command-line arguments, and handling both initial application launches and subsequent instances. A logic issue was identified in the second-instance handler where notes would incorrectly open in the previously focused window even when the --new-window flag was provided; a code suggestion was offered to ensure the note is correctly routed to the new window via a URL hash.

Comment thread apps/desktop/src/main.ts
Comment on lines 85 to 100
app.on("second-instance", (event, commandLine) => {
const noteId = extractNoteIdFromArgs(commandLine);
const lastFocusedWindow = windowService.getLastFocusedWindow();

if (commandLine.includes("--new-window")) {
windowService.createExtraWindow("");
} else if (lastFocusedWindow) {
if (lastFocusedWindow.isMinimized()) {
lastFocusedWindow.restore();
}
if (lastFocusedWindow.isMinimized()) lastFocusedWindow.restore();
lastFocusedWindow.show();
lastFocusedWindow.focus();
}

if (noteId && lastFocusedWindow) {
lastFocusedWindow.webContents.send("open-note-by-id", noteId);
}
});
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

There's a logic issue in how a second instance with a protocol URL and the --new-window flag is handled. The current implementation creates a new window but then opens the note from the URL in the previously focused window, which is likely not the desired behavior.

The note should be opened in the new window. This can be achieved by passing the note ID in the URL hash when creating the new window, as the logic to open a note from a hash on window creation already exists.

Here is a suggested improvement to handle this case correctly:

Suggested change
app.on("second-instance", (event, commandLine) => {
const noteId = extractNoteIdFromArgs(commandLine);
const lastFocusedWindow = windowService.getLastFocusedWindow();
if (commandLine.includes("--new-window")) {
windowService.createExtraWindow("");
} else if (lastFocusedWindow) {
if (lastFocusedWindow.isMinimized()) {
lastFocusedWindow.restore();
}
if (lastFocusedWindow.isMinimized()) lastFocusedWindow.restore();
lastFocusedWindow.show();
lastFocusedWindow.focus();
}
if (noteId && lastFocusedWindow) {
lastFocusedWindow.webContents.send("open-note-by-id", noteId);
}
});
app.on("second-instance", (event, commandLine) => {
const noteId = extractNoteIdFromArgs(commandLine);
if (commandLine.includes("--new-window")) {
const hash = noteId ? `#/notes/${noteId}` : "";
windowService.createExtraWindow(hash);
} else {
const lastFocusedWindow = windowService.getLastFocusedWindow();
if (lastFocusedWindow) {
if (lastFocusedWindow.isMinimized()) lastFocusedWindow.restore();
lastFocusedWindow.show();
lastFocusedWindow.focus();
if (noteId) {
lastFocusedWindow.webContents.send("open-note-by-id", noteId);
}
}
}
});

@eliandoran
Copy link
Copy Markdown
Contributor

Hi,

Thank you for the contribution but we'd like to implement this feature on our own since it needs to be done on an agreed-upon plan.

@eliandoran eliandoran closed this May 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge-conflicts size:M This PR changes 30-99 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Open/focus a note from command line / desktop URL handler (Trilium URL protocol)

2 participants