Kerekes Stefan82 downloadsCitation-map canvas export for Zotero: pick items, collections or authors and get a drag-and-drop .canvas literature map — papers as nodes, citations as edges, collections as containers, colored by unread / read / annotated.
Citation-map canvas export for Zotero inside Obsidian.
Pick Zotero items, a collection, or an author — Citation Atlas writes a
.canvas file into your vault that is a drag-and-drop visual literature map:
dc:relation data citation-graph tools read) become connecting lines; when
both papers have a year the arrow points from the newer paper to the older,
cited one.




Citation Atlas talks to the Zotero Local API on localhost:23119
(http://127.0.0.1:23119/api/users/0/...). It is a read-only, unauthenticated,
offline endpoint that serves your local library — no API key, no sync, no
touching the SQLite file while Zotero runs. See the
Zotero Local API documentation.
403).Development / BRAT install: copy main.js, manifest.json, styles.css into
<vault>/.obsidian/plugins/citation-atlas/ and enable “Citation Atlas” in
Settings → Community plugins.
Run one of the commands (or the ribbon icon):
| Command | What it does |
|---|---|
| Export a Zotero collection to a citation-map canvas | pick one or more collections (searchable); sub-collections become nested groups when enabled |
| Export picked Zotero items to a citation-map canvas | search the whole library and pick individual papers |
| Export an author's Zotero papers to a citation-map canvas | pick authors, one group per author with all their papers |
After export the canvas opens automatically. The generated map has:
Zotero has no built-in read/unread flag, so Citation Atlas derives the status from signals that really exist in your library (all configurable in settings):
| Status | Detected when |
|---|---|
| Annotated | the paper has PDF/EPUB annotation child items in Zotero (automatic), or carries an “annotated” tag |
| Read | the paper carries a read tag — e.g. Read, or the Read 2026-01-02 style used by zotero-actions-tags (prefix matching) |
| Unread | the paper carries an unread tag (e.g. Unread), otherwise the fallback status (default: unread) |
If you don't tag anything, papers you annotated in Zotero still show up red and everything else stays unread-colored — then start tagging and re-export to watch the map “turn green”.
Citation Key: in the Extra field) and/or exact note title — matching cards
become [[note]] links in the canvas.{mode}, {date}, {time}, {count}
(default: Citation Atlas - {mode} - {date}). Collisions get a numeric suffix.npm install # installs build tooling
npm run build # typecheck + bundle -> main.js
npm run typecheck # tsc only
npx tsc -p tsconfig.test.json && node build-test/test/fixture.js
# offline fixture test of the export pipeline (fake Zotero)
Layout of the code:
src/main.ts plugin entry: commands, ribbon, export orchestration
src/settings.ts settings tab + defaults
src/ui/exportModal.ts pick collections/items/authors dialog
src/lib/zoteroClient.ts read-only Zotero Local API client (pure, injected HTTP)
src/lib/exporter.ts mode resolution → atlas model (papers/containers/edges)
src/lib/reading.ts annotated/read/unread resolver
src/lib/canvas.ts JSON Canvas 1.0 layout + writer (pure)
src/lib/display.ts card text, author index, citekey parsing
test/fixture.ts offline assertions over a fake library
examples/ sample .canvas produced by the fixture test
The core (src/lib/*) has no Obsidian imports, so it is testable under plain
Node. Only main.ts, settings.ts and ui/ touch the Obsidian API.
“Empty response” / nothing loads.
ERR_EMPTY_RESPONSE). The Local API only serves non-browser local
clients (curl, desktop apps, this plugin via Obsidian's main process). See the
Zotero team's answer on the forum.curl -i "http://127.0.0.1:23119/api/users/0/collections?format=json"
— you should see HTTP/1.1 200 and JSON.extensions.zotero.httpServer.enabled = true, port
extensions.zotero.httpServer.port = 23119) and restart Zotero. Make sure nothing
else occupies port 23119 (netstat -ano | findstr 23119).users/0); group
libraries are not yet surfaced.MIT © 2026 Kerekes Stefan