Anki Card Link

approved

by 王若冰

Open Anki searches from Obsidian using note IDs, card IDs, text, or custom queries across desktop and mobile. - This plugin has not been manually reviewed by Obsidian staff.

1 stars28 downloadsUpdated 2d agoMIT

Anki Card Link

English | 简体中文

Complete setup guide | 中文完整教程 | Download the optional Anki note types

Anki Card Link is an Obsidian community plugin for portable Obsidian-to-Anki search links, desktop Markdown-to-Anki synchronization, and plugin-owned Anki-to-Obsidian source navigation. It supports Basic, Cloze, and dedicated single-choice/multiple-choice Markdown cards. Version 1.2.0 no longer requires Advanced URI for newly synchronized cards and no longer writes a visible ^acl-xxxxxxxx block ID.

Version 1.4.0 also adds an optional reading-mode review mask for tagged notes. It hides Basic backs, Cloze answers, choice answer markers, and choice explanations without changing Markdown or synchronized Anki fields.

Platform scope

FeatureWindows/macOS/LinuxAndroidiOS/iPadOS
Obsidian → Anki navigationAnki Desktop + AnkiConnectAnkiDroid deep linkAnkiMobile deep link
Obsidian → Anki content syncSupportedNot supportedNot supported
Anki → Obsidian source navigationSupported when this plugin is enabledSupported when this plugin is enabledSupported when this plugin is enabled
Reading-mode review masksSupportedSupportedSupported

Mobile behavior still depends on the installed Anki app and its URI support. isDesktopOnly: false is not evidence that every mobile combination has been physically tested.

Desktop requirement

Desktop synchronization and Anki search opening require Anki Desktop and AnkiConnect, add-on code 2055492159, normally at http://127.0.0.1:8765. The configurable endpoint is restricted to HTTP/HTTPS loopback addresses. Advanced URI is not required for newly synchronized cards in version 1.2.0 and later.

Card format

What is the JVM?::The Java Virtual Machine.

[Open corresponding Anki card](obsidian://anki-card-link?type=nid&value=1754000000000&uid=acl-d5c044bd&v=2)

Single-line cards support both :: and :: by default, without requiring spaces. Multi-line basic cards use a line containing only ? or . Both separator lists are configurable, one value per line. Cloze cards use {{c1::text}} or {{c1::text::hint}}. The card and button are separated by one blank line. The button label may be customized because recognition is based on the URL, not fixed text. The button is excluded from Anki Front, Back, and Content fields.

Multiple-choice cards use a level-three heading followed by 2–7 consecutive one-line list items:

## Data structures

### Which statements are correct【A,C,D】?
- Option A
- Option B
- Option C
- Option D
**Explanation:**
A, C, and D are correct.

Use 【B】 for single choice and forms such as 【A,C,D】, 【ACD】, 【A C D】, or 【A、C、D】 for multiple choice. The question and options may have at most one blank line between them; options cannot span multiple lines. Back starts immediately after the final option and stops at the first blank line. Back may be empty. The answer marker is replaced with 【 】 in Anki Front, while the original OptionA–OptionG order is preserved. Anki templates, not this plugin, are responsible for shuffling and answer feedback.

The synchronized title is the vault-relative Markdown file path without .md, for example test/Calculation.md becomes test/Calculation. Inline Markdown formatting is converted to Anki HTML: **bold** remains bold, while backticks around inline code are removed and the code style is preserved.

The stable UID is stored only in the button URL, the Anki ObsidianURI field, and the plugin's local location index. It is not derived from the file path, title, content, line number, noteId, or cardId.

Reading-mode review masks

Enable Settings → Anki Card Link → Reading review → Hide answers in reading mode. The feature only processes Markdown notes whose MetadataCache contains the anki-card-link tag, whether the tag comes from YAML or inline #anki-card-link syntax. It runs only in reading mode; source mode, live preview, and normal editing continue to show the original Markdown.

  • Basic: Front and the configured separator remain visible; the complete Back is one reveal group and keeps its rendered layout, code blocks, and images.
  • Cloze: each {{cN::answer}} token becomes an independent clickable blank. A {{cN::answer::hint}} blank may show the hint while the answer stays hidden.
  • Choice: the content inside 【】 is one cloze-style blank, while the optional explanation after the options is one Back reveal group.
  • Click or focus a mask and press Enter/Space to reveal it. Reopening or rerendering the reading view resets all masks to hidden.
  • The four reading-review commands operate only on the active tagged reading view. Configure optional shortcuts under Settings → Hotkeys, search for Anki Card Link. Suggested keys are J, Shift+J, N, and Shift+N; the plugin does not bind them automatically.
  • On mobile, direct taps work normally. Optional left/right edge gestures are disabled by default; when enabled, the left 11% reveals the next cloze and the right 11% reveals the next Back. Scrolling, text selection, links, controls, code, and existing masks are excluded from edge handling.

This is a visual review aid, not encryption. Answers remain visible in editing modes and in the Markdown source.

Synchronization

Use Sync current card to Anki or Sync all cards in current file to Anki. On first sync, the plugin generates a UID in memory, creates the Anki note, then writes exactly one v2 button after Anki returns a noteId. An Anki failure leaves Markdown unchanged. A Markdown write failure reports the noteId and UID and does not delete the Anki note.

After at least one card in the current Markdown file synchronizes successfully, the plugin adds the Obsidian note tag anki-card-link without duplicating an existing tag.

For an existing v2 button, synchronization first calls notesInfo for its noteId. Only a missing note or UID mismatch triggers fallback matching through the legacy UID tag, the new uid URI parameter, and the old Advanced URI block parameter. Duplicate UIDs stop the update.

Synchronization is manual and one-way. The plugin does not sync Anki edits back to Obsidian, delete Anki notes, run in real time, scan the entire vault, modify templates, or read the Anki database directly.

Anki → Obsidian navigation

The ObsidianURI field now contains:

obsidian://anki-card-link-open?v=2&vault=My%20Vault&filePath=cards%2Fjava.md&uid=acl-d5c044bd

The plugin validates the request, opens the URI path directly, falls back to its incremental UID-to-path index if the file moved, reads only that target Markdown file, and positions the editor at the card's first content line. It never scans the whole vault for each click. Cold-start requests wait for the workspace layout. If no editor is available, the correct file is still opened and a notice explains that precise positioning was unavailable.

The URI keeps Obsidian's vault parameter so the correct vault can open during a cold start, but stores the vault-relative Markdown path in the plugin-specific filePath parameter. Obsidian's reserved path parameter cannot be used because the main process treats it as an absolute filesystem path and may report Vault not found before the plugin handler runs.

The index is only a cache. It is updated after successful synchronization and on file/folder rename, move, and delete events. If both the URI path and index are stale, synchronize the card again.

Gradual legacy migration

Legacy standalone and inline block IDs, old obsidian://anki-card-link note links, legacy UID tags, and Advanced URI block fields remain readable. The plugin does not rewrite the vault at startup. A card is migrated only after its explicit synchronization succeeds; failed or untouched cards keep their old format.

Anki fields and template

Default basic fields are 标题, Front, Back, 提示, and ObsidianURI. Default Cloze fields are Content, Note, and ObsidianURI.

Choice cards use the existing Multiple Choice note type with these exact fields: CardID, Title, Front, Back, ObsidianURL, OptionA, OptionB, OptionC, OptionD, OptionE, OptionF, OptionG, and CorrectAnswer. CardID stores the stable acl-xxxxxxxx UID, and CorrectAnswer stores original option IDs such as B or A,C,D. The plugin always writes all seven option fields so removed options are cleared. It never creates or modifies note types, templates, or CSS.

The optional ready-to-import package is assets/anki/anki-card-link-note-types.apkg. It contains Anki Card Link Basic, Enhanced Cloze 2.1 v2, Multiple Choice, _jquery.min.js, and four disposable demonstration notes. Back up Anki before importing. See the complete setup guide for exact mappings, custom-template instructions, and precautions.

Recommended front/back or Cloze template fragment:

{{#ObsidianURI}}
<div class="acl-source-link">
    <a href="{{ObsidianURI}}">Open the corresponding Obsidian note</a>
</div>
{{/ObsidianURI}}
.acl-source-link {
    margin-top: 18px;
    text-align: center;
}

.acl-source-link a {
    display: inline-block;
    padding: 6px 12px;
    border: 1px solid currentColor;
    border-radius: 6px;
    text-decoration: none;
    font-size: 14px;
    opacity: 0.8;
}

Do not render {{ObsidianURI}} directly because that exposes the full URI, path, and UID.

Existing features

  • Validated nid, cid, text, and custom-query links
  • Folder-path to Anki :: deck mapping
  • Obsidian Wiki-image upload to Anki media
  • Cloze next/current-number commands
  • English and Simplified Chinese UI, debug logging, and clipboard fallback

Installation and development

Copy main.js, manifest.json, and styles.css from a release into <vault>/.obsidian/plugins/anki-card-link/, reload Obsidian, and enable the plugin.

npm install
npm run lint
npm test
npm run build

Complete docs/manual-test-checklist.md before publishing. MIT licensed.

For plugin developers

Search results and similarity scores are powered by semantic analysis of your plugin's README. If your plugin isn't appearing for searches you'd expect, try updating your README to clearly describe your plugin's purpose, features, and use cases.