Logseq Block Ref Enhancer
unlistedby msjsc001
View Logseq-style block references and block embeds inside Obsidian.
Block Reference Enhancer
简体中文版文档见 README.zh-CN.md。
Render, navigate, and manage Logseq-style UUID block references and embeds directly in Obsidian, while preserving the original Markdown.
The plugin renders ((uuid)) as readable summaries and {{embed ((uuid))}} as complete, foldable outlines. A local index tracks source blocks and references without depending on Obsidian's search index.
✨ What It Does
If your notes already use UUID-style blocks, this plugin makes them readable inside Obsidian without forcing you to rewrite your notes.
You get:
- Complete first-line summaries for
((uuid)) - Full embeds for
{{embed ((uuid))}}with foldable outline nodes - A hover-only
Backbutton that jumps references and embeds to their source blocks - Reference-count badges next to source blocks
- A compact popover that shows where a block is referenced
- Block autocomplete when typing
(( - Commands and editor context menu actions to copy the current block reference or block embed
- A selection context-menu action that copies rendered UUID references and embeds as readable Markdown outline text
- Hidden Logseq-style outline property lines such as
id::,collapsed::, andhl-*:: - Right-click outline enhancements for unordered-list blocks
- Experimental whitelist-based synchronization between Logseq page properties and Obsidian YAML frontmatter
- Saved source-block edits automatically refresh existing references and embeds
- Dense pages reuse layout measurements and continue rendering through a bounded queue, avoiding repeated full-page scans during scrolling and tab switches
- A local cache and block index for large vaults
👀 Best For
- Users migrating from Logseq-style UUID notes
- Outline-heavy Markdown vaults
- Large vaults where source blocks and references need stable rendering
- Users who want block references and embeds to stay readable in both Live Preview and Reading Mode
🚀 Install
Community plugin install
- Open
Settings->Community plugins. - Search for
Block Reference Enhancer. - Install it.
- Enable it.
Manual install
- Download
main.js,manifest.json, andstyles.cssfrom the latest GitHub release. - Open your vault folder.
- Go to
.obsidian/plugins/. - Create a folder named
block-reference-enhancer. - Copy the three files into that folder.
- Enable
Block Reference Enhancerin Obsidian.
Compatibility and interface languages
[!NOTE] Plugin ID and install folder:
block-reference-enhancer
The GitHub repository keeps theobsidian-prefix only as a repository name.
The Obsidian default theme and Minimal are the actively maintained compatibility baselines. Other themes are not guaranteed to render or behave correctly.
The plugin follows Obsidian's interface language automatically. English and Simplified Chinese are included. Chinese locales, including zh-TW, use the Simplified Chinese interface; unsupported languages fall back to English.
📝 Raw Syntax Used in Notes
Source block
- Opportunity cost
id:: 68a92328-da50-46cc-aa45-73dec00ca8ce
Empty list items can also be source blocks. Their inline reference summary is shown as [Empty source block] while embeds can still render their continuation text and children:
-
id:: 699c3044-2c70-4199-9115-de5460941dd5
> Continuation content remains part of the embed.
IDs created by the plugin use the list item's existing leading indentation plus two spaces. Nested list levels are left unchanged. Older notes whose id:: lines use wider indentation remain supported and are not rewritten.
Inline block reference
((68a92328-da50-46cc-aa45-73dec00ca8ce))
Block embed
{{embed ((68a92328-da50-46cc-aa45-73dec00ca8ce))}}
🎯 Effects After Enabling the Plugin
Inline references
((uuid)) is rendered as the complete first line of the target block. Long first lines wrap instead of being shortened with an ellipsis.
Hover, focus, or click the rendered reference to keep a small Back button visible and jump to the source block.
If the cursor leaves that reference again, the inline reference automatically returns to its rendered state shortly after.
Dense pages with many rendered references reuse horizontal layout measurements and continue pending work through a bounded render queue instead of rescanning the page for every batch. Vertical reflow caused by rendered widgets no longer invalidates every cached width; theme, font, list-indent, and editor-width changes still refresh measurements when needed. This reduces CPU and layout pressure during scrolling, tab switching, and rapid focus changes while keeping list indentation stable in both the Obsidian default theme and Minimal.
Block embeds
{{embed ((uuid))}} is rendered as the target block plus its children.
The embed root and every embedded outline item with children use a compact circular triangle in place of an extra list bullet. The control collapses or expands that node's children. Fold state is independent for each embed occurrence, stays synchronized when switching between Live Preview and Reading Mode, and is saved across restarts. Deleting or changing that embed occurrence removes its obsolete saved state; deleting plugin data resets all embedded outlines to expanded.
Folding is view-only. Source-block edits still refresh every reference and embed with the newest indexed content, including content inside a currently collapsed branch.
Hover, focus, or click the rendered embed to keep the same Back button visible and jump to the source block.
The Back, Delete, and source-badge controls use a single Obsidian-style hover tooltip without a duplicate browser tooltip.
Source badges
When a source block is referenced, the plugin shows a numeric badge beside the source block in:
- Live Preview
- Reading Mode
Clicking the badge opens a compact reference popover with:
- file name
- line number
- reference type
- parent, current, and child context previews with UUID syntax resolved to readable source summaries
- a header toggle that collapses the list to reference type and file name only
If the same UUID exists as an active source block in multiple files, each active source location shows the same reference-count badge.
After a source block is saved, existing references and embeds automatically refresh to the newest source content. If the same UUID exists in multiple active source blocks, the plugin uses the most recently modified active source as the canonical rendered content.
🧭 Useful Commands
(( autocomplete
Type:
((
This opens block autocomplete. Select a result or press Enter to insert ((uuid)). Hover a result and click Go to to remove the current (( query and jump directly to that source block.
If Obsidian has already inserted a closing )), autocomplete reuses or removes that pair as appropriate instead of creating duplicate parentheses.
It only searches blocks that have already been established as source blocks. This restriction is intentional for long-term vault performance.
If a needed block has not been established as a source block yet, you can first use normal Obsidian search to find the right place, then add a source block in the expected outline form.
Open the Obsidian command palette with:
Ctrl/Cmd + P
Copy current block reference
Place the cursor on an outline block and run the command.
If the block does not already have id:: uuid, the plugin adds one and copies ((uuid)) to the clipboard. If the block already has id:: uuid, the plugin reuses the existing ID instead of generating a new one.
You can also right-click the current outline block in the editor and use:
Copy block reference
Copy current block embed
Place the cursor on an outline block and run the command.
If the block does not already have id:: uuid, the plugin adds one and copies {{embed ((uuid))}} to the clipboard. If the block already has id:: uuid, the plugin reuses the existing ID instead of generating a new one.
You can also right-click the current outline block in the editor and use:
Copy block embed
Copy selection (UUID blocks as text)
Select text in the Markdown editor that contains rendered UUID block references or block embeds, then right-click and use:
Copy selection (UUID blocks as text)
This copies readable Markdown text instead of the selected ((uuid)) and {{embed ((uuid))}} source syntax:
- block references use the same summary shown in Live Preview
- standalone block embeds include the full source block and its child outline
- an embed root gets exactly one
-marker, even when the selected host line already contains its own list marker - ordinary selected Markdown remains unchanged
- incomplete UUID syntax and UUID-like text inside inline or fenced code remain unchanged
Normal Ctrl/Cmd + C is not modified and still copies the original Markdown source. The conversion action is available only for one non-empty editor selection containing complete UUID block syntax.
Rebuild block reference index
Use this when:
- many Markdown files changed outside Obsidian
- some references render as
[missing block] - some embeds render as
Missing block
Review missing source blocks
Use this when a source block disappeared but references still exist.
The review dialog lets you:
- restore the cached source to the recovery page
- confirm deletion
- ignore it for now
Default recovery page:
pages/Block Recovery.md
⚙️ Property Hiding Settings
The plugin now includes a setting to hide Logseq-style property lines. It is on by default for new installs, while existing users keep their saved preference.
You can change it in:
Settings -> Community plugins -> Block Reference Enhancer
Rule notes:
- Use
\\as the separator between rules in the setting box - In notes,
hl:: valuemeans the exact keyhl - In notes,
hl-*:: valuemeans any key that starts withhl- - In the setting box, write only the key rules themselves, for example
collapsed\\id\\hl-*
The default rule set already includes common properties such as id, collapsed, hl-*, and ls-type.
This feature hides matching property-line display under unordered-list blocks, including the same properties inside rendered block embeds, and does not modify the original Markdown.
When this option is enabled, pressing Enter on a non-empty outline block in Live Preview behaves like this:
- If the current block already has direct child list items, a new first child block is created.
- If the current block does not have direct child list items yet, a new same-level sibling block is created.
In both cases, hidden property lines and continuation lines stay attached to the original parent block instead of being migrated into the new block.
🧩 Outline Enhancements
The plugin also includes an outline enhancement setting:
Settings -> Community plugins -> Block Reference Enhancer -> Outline enhancements -> Convert pasted content to outline
It is off by default.
When enabled, any unordered-list block in the editor, including empty list items, gets right-click actions:
Paste clipboard as outlineCopy current level and children
Behavior:
- It only runs when you explicitly click that menu item
- It only works on unordered-list blocks
- Empty unordered-list items such as
-or-are also supported - Normal
Ctrl/Cmd + Vpaste is not intercepted or modified - HTML and plain text are converted into child outline blocks when the structure is reliable
- Structured web / ChatGPT content is reconstructed more carefully when a paragraph introduces a following list cluster
- Blank separator lines are removed so generated unordered-list blocks stay continuous
- Clipboard spaces are used only to detect source hierarchy; every generated child level is normalized to exactly one
Tabfollowed by- - Blank lines inside fenced code blocks are preserved to avoid changing pasted code
Copy current level and childrencopies the current level and its full subtree as raw Markdown text- Large but safely bounded clipboard content asks only
ProcessorCancel, then converts in short time slices with progress shown in the top-right notice - The original file and outline location are captured before processing; switching pages does not redirect the final insertion
- If the original target is deleted or becomes ambiguous while processing, insertion is cancelled instead of writing to the wrong place
- Content beyond the hard safety limits is rejected without inserting partial output
🔄 Logseq ↔ Obsidian Page Properties (Experimental)
The settings page includes an isolated experimental section:
Logseq ↔ Obsidian page properties (Experimental)Keep Logseq and Obsidian page properties in syncis off by default
It can maintain both physical page-property formats in the same Markdown file:
---
aliases:
- Example alias
---
alias:: Example alias
The whitelist is the only mutation boundary. Its default rule is:
alias<->aliases
Rules:
- Write one rule per line
alias<->aliasesmaps Logseqaliasto YAMLaliases- A single key such as
tagsuses the same name on both sides - The built-in alias mapping supports string lists; custom mappings support one-line strings only
- Block-level keys including
id,collapsed,created-at, andupdated-atare protected - Logseq and YAML properties outside the whitelist are left unchanged
Actions:
Sync current fileonly processes the active Markdown fileSelected foldersaccepts one vault-relative folder per line;.means the whole vaultScan and sync selected folders…scans and shows a summary before any batch write- Batch work can be cancelled; completed files stay changed and remaining files are not written
When both formats changed and their order cannot be determined reliably, the plugin does not overwrite either side silently. It asks for one of:
Use Obsidian YAMLUse Logseq propertiesSkip
If Logseq turns top-of-file YAML into an unordered-list block, enabling this feature allows strict event-driven repair inside selected folders. Repair only runs when the candidate YAML parses safely, contains whitelisted evidence, and leaves the body unchanged. Ambiguous files are skipped.
The danger zone provides Remove safe YAML and disable sync…:
- YAML is removed only when all of it is represented equivalently by Logseq page properties
- Files with YAML-only keys, complex values, parse errors, or conflicts stay unchanged and appear in the report
- Sync is disabled afterward, and the latest three safe-cleanup recovery records are retained
This experimental feature modifies Markdown source. Back up the vault before the first batch run. Version 1 does not support wildcards, nested YAML, automatic two-way sync on every save, or forced deletion of unsafe YAML.
📦 First Launch and Indexing
The plugin builds and maintains its own block index. This is separate from Obsidian's built-in search index.
On first launch, watch the bottom-right status bar for Block index: .... The General -> Show block index status setting controls this display and is enabled by default; hiding it does not stop indexing.
Common states:
loading cache...means the plugin is reading its local cache.no cache found, building full index...means a first full build is running.cache outdated, rebuilding full index...means an older cache format or parser result was detected and a full rebuild is running automatically.cache loaded, checking vault changes...means cached data was found and is being validated.reconciling X/Y files ...means changed or removed files are being compared against the cache.ready | F files | B blocks | R refsmeans startup indexing is complete.
Normal create, modify, delete, and rename updates after startup are incremental and usually happen silently.
Source-block text changes are also handled incrementally after save. The plugin does not wait for a full rebuild, and it does not try to mirror every keystroke across the vault while you are still editing.
When parser capabilities change and older cached results are no longer trustworthy, the plugin now invalidates that cache automatically on first launch and performs one full rebuild. Users do not need to delete data.json or manually run Rebuild block reference index first.
🛟 Safety: What Happens When a Source Block Goes Missing
If a source block disappears but references still exist:
- inline references keep showing the last cached summary
- embeds keep showing the last cached content
- the plugin marks the content as stale
Recovery is intentionally sent to the recovery page instead of trying to reinsert the block back into its old file path and old line number. That default is safer and more predictable in large vaults.
🔎 Troubleshooting
If you see [missing block] or Missing block:
- wait until the status bar reaches
Block index: ready - run
Rebuild block reference index - check whether the source block follows the expected outline syntax
- use
Review missing source blocksif the source content was actually removed
If you changed many files through Logseq, sync tools, git, or external editors while the plugin was not running, a manual rebuild is recommended.
📐 Parsing Rules
The plugin is intentionally strict about what counts as a source block.
A block is indexed as a source block when:
- the source line starts with an outline list marker such as
-; an empty-or bare-is also valid - the block has an indented property line containing
id:: uuid
The id:: line may use the current two-space continuation style or wider legacy indentation. When the plugin creates a new ID, it writes exactly two spaces after the list item's existing leading indentation.
This strictness is deliberate. It keeps UUID-based outline notes predictable and prevents loose Markdown from being indexed as the wrong block.
🆘 Get Help
If you run into a problem:
- read SUPPORT.md
- search existing GitHub issues first
- use the
Bug reportform for reproducible problems - use the
Feature requestform for improvement ideas - include plugin version, Obsidian version, mode, reproduction steps, console errors, and a minimal Markdown sample
🧩 Recommended Companion Plugins
Outline / Hierarchy Editing
- 🔴
OutlinerFeature: improves list, outline, indent, moving, and hierarchy editing. Use: makes Obsidian feel closer to Logseq / Workflowy / Roam style outlining. Useful detail:Ctrl + Shift + Up/Downmoves outline blocks; in Logseq a common shortcut isAlt + Shift + Up/Down. - 🔴
ZoomFeature: focuses on a heading or list level. Use: lets you isolate one section or one hierarchy level in a long note and reduce distraction.
Search / Navigation / Quick Location
- 🔴
Better Search ViewsFeature: improves how search, backlinks, and embedded query results are displayed. Use: makes results feel more like outline breadcrumbs with clearer context. - 🔴
Recent FilesFeature: shows recently opened files. Use: helps you jump back to notes you just edited or reviewed.
Image Handling And Reading
-
🔴
Image ConverterFeature: handles image paste, drag-in, format conversion, compression, renaming, and link formatting. Use: helps normalize pasted images into a more portable format such as:
Visual Thinking / PDF Reading
- 🔴
PDF++Feature: improves PDF reading, annotation, citation, and linking. Use: connects PDF source material more tightly with your Obsidian notes; with the right setup it also works well alongside Logseq-style workflows. ExcalidrawFeature: draws diagrams, whiteboards, flowcharts, and sketches inside Obsidian. Use: useful for structure diagrams, mind maps, process charts, and visual notes.
Editing And Reading Experience
- 🔴
Codeblock CustomizerFeature: improves code block presentation. Use: makes code blocks, config blocks, and long text blocks easier to read inside outline notes. - 🔴
Toggle Readable line lengthFeature: quickly toggles Obsidian's readable line width. Use: switches between narrow reading mode and wide-screen editing. Useful detail:Ctrl + Shift + E Simplified Chinese Word SplittingFeature: improves Chinese word splitting. Use: improves cursor movement, word selection, and deletion behavior while editing Chinese text.
Tag Management
- 🔴
Tag WranglerFeature: renames, merges, and organizes tags. Use: helps keep tag structures maintainable over time. Useful detail: you can continue tag management from a right-click action on tags.
⚠️ Known Limitations
- This plugin is a UUID block reference and block embed syntax enhancer, not a Logseq replacement.
- The Obsidian default theme and Minimal are the recommended themes and actively maintained compatibility baselines for this plugin. Other themes are not guaranteed to render or behave correctly.
- Live Preview can still show small visual differences in very complex lists or under heavily customized themes.
- When a source block is missing, recovery defaults to the recovery page instead of restoring the block back into its original file and line position.
- 2026-07-03 — Obsidian folding issue: This issue has been reported to Obsidian on the official forum. Obsidian can leave list content incorrectly folded after using
Fold all headings and lists, especially when switching between Reading Mode and Live Preview. It is reproducible with all community plugins disabled and is not caused by Block Reference Enhancer. Until Obsidian fixes it, users are advised not to useFold all headings and lists; if it occurs, runUnfold all headings and liststo restore the hidden content.
🛠 Development
npm install
npm run build
Build artifacts:
main.jsmanifest.jsonstyles.css
Community review compatibility:
- invisible source-anchor widgets are styled through CSS classes instead of inline style assignment
- editor DOM checks prefer cross-window-safe helpers for menu targeting and outline paste parsing
- the TypeScript standard-library declarations target ES2020 so modern built-ins retain correct static types during community review
Release notes:
- GitHub releases should attach
main.js,manifest.json, andstyles.css. - Community-plugin releases should use an exact numeric tag such as
1.1.3, without avprefix. - Release notes should be written for each GitHub release.
🔒 Privacy
- The plugin runs locally inside Obsidian.
- It does not send your notes, UUIDs, or index data over the network.
- It does not include telemetry, ads, or account-gated behavior.
- Its block index cache is stored through Obsidian's plugin data storage.
🗺 Roadmap
Planned directions include:
- refine outline interactions so Enter, Delete, and related editing behaviors feel closer to dedicated professional outliner software
- more block-oriented workflows built on the current index and cache foundation
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.