Render Emacs org-roam nodes on your Obsidian Canvas!
This is the Obsidian canvas, showing a single markdown file (yellow) and five Emacs Orgmode / Org-roam nodes:
This is a FastAPI server which talks to a running Emacs process via emacsclient
and offers the following endpoints:
- http://localhost:3813/select/ - pop up Emacs so that user can select org-roam node, then show the node detail (HTML) link which user can drag-and-drop onto the obsidian canvas
- http://localhost:3813/node/?id=NODE_ID - abovementioned node detail link which returns HTML version of the org-roam node. This is embedded by Obsidian
- http://localhost:3813/orc-files/FULL_FILE_PATH - links are rewritten so that rendered and embedded HTML nodes can load attachments
- http://localhost:3813/os-open/?filename=FULL_FILE_PATH - so that embedded HTML nodes can link back to the source files. When clicked, system will open org file with registered app, which should be Emacs
You will typically only interact with the first /select/
endpoint, the rest are used by Obsidian.
Ensure you have pipx installed, and then:
# install org-roam-canvas (once)
pipx install git+https://github.com/cpbotha/org-roam-canvas.git
# now start the server
orserve
Ensure that you have poetry installed, and then:
- Get the source code:
git clone https://github.com/cpbotha/org-roam-canvas.git
- Create venv, install deps:
cd org-roam-canvas && poetry install
- Start the server:
poetry run orserve
- Click on the select link above
- Select and org-roam node
- Drag and drop the offered link onto the Obsidian canvas and see the rendered note
... alternatively, use the ors-get-link
method from the next section.
Instead of using the select
link above, you can also just add the following function to your init.el
and invoke it with the org-roam node open that you would like to embed. If successful, it will copy the link to your clipboard so that you can Ctrl/Cmd-V on the Obsidian Canvas.
This works for file and heading nodes.
(defun ors-get-link()
"Get org-roam-canvas link to org-roam node containing point. After invoking this, Ctrl-V on the Obsidian Canvas."
(interactive)
(let ((node (org-roam-node-at-point)))
(if node
(progn
(message "Placed org-roam-canvas link on clipboard for node: %s" (org-roam-node-title node))
(kill-new (url-encode-url (format "http://localhost:3813/node/?id=%s" (org-roam-node-id node)))))
(message "No org-roam node found."))))
The following screen capture shows ors-get-link
in action:
20231119-org-roam-canvas-ors-get-link.mp4
Click on the [name_of_file.org]
link at the top of the embedded page:
This started as a half-working prototype for serving HTML exports of org-roam nodes so that the frontend can show them on an infinite canvas.
What worked:
- fastapi backend talking to emacs via emacsclient
- frontend to render HTML versions of org-roam nodes on an infinite canvas
During development, we
fnm use 18
cd fe
pnpm install
pnpm run dev
# in another terminal
poetry run uvicorn serve:app --reload