Block reference to allow ((page-name#block-ref-name)) not just UUID

Per discord discussion, I request for block reference to allow ((page-name#block-ref-name)) not just UUID.

That ((page-name#block-ref-name)) is also globally unique, since page-name is globally unique and block-ref-name can easily be maintained as unique (even as just simple numeric sequence 1,2,3,…). The block-ref-name can also be automatically generated to be globally unique by using current unix timestamp in milliseconds such as 1632789645123. Hence the full block reference looking like ((page-name#1632789645123))

This would make recovery from broken block reference (for whatever reason) to be possible since page-name is manually recognizable and block-ref-name can be chosen to be recognizable or have timedate info in it.

The semantics/usage of the block reference could also be more similar to HTML id global attributes.


  1. In current Logseq v0.4.0, typing (( will automatically inserts closing )), as you continue typing text within the brackets such as “pennsylvania”, logseq will search the local graph for all blocks containing that word, and display them in a list.
  2. When you select one of the blocks, Logseq will generate a globally unique UUID of the format like 614800f3-e336-45e5-849e-fe64ea361d35.
  3. Then the code ((614800f3-e336-45e5-849e-fe64ea361d35)) will be inserted in the current block.
  4. And the code/attribude id:: 614800f3-e336-45e5-849e-fe64ea361d35 will be inserted in the target block.
  5. And Logseq will render the contents of the target block, embedded in the current block.
  6. According to uuidtools that UUID 614800f3-e336-45e5-849e-fe64ea361d35 is version 4 (random data based) and variant DCE 1.1, ISO/IEC 11578:1996

I agree. This is crucial also for interoperability with other applications, to make each reference recognizable by Obsidian etc.

Obsidian allows page-name#^block-ref-name inside [[]] . It requires ^ for some reason.

I tried inserting id:: my-custom-id in a block, just to see what happens. The text disappeared after exiting the edit, leaving the block empty, and wasn’t there when re-entering the edit. Upon searching for it with (()) in another block, it showed up as #{'my-custom-id'}, but clicking on it would return the UUID, and the block wouldn’t be rendered by {{embed}}. Then my-custom-id stopped showing up in the search.


Improving the interoperability issue mentioned above would be a big win. Allowing for custom block references would also allow users to treat blocks more like first class citizens. Instead, currently, if I want to have a link that is human readable in the markdown file, I’m required to make that a link to a page instead of a block.

One solution to this could be to allow aliases to function for blocks as well as pages. So any block that contains alias:: my-custom-block-id could be referenced with ((my-custom-block-id)), or even better, [[page-title#my-custom-unique-block-id]].

Not sure yet if allowing “block aliases” instead of allowing for custom block IDs feels like a hack, but it’s worth considering.

1 Like

This is similar to thoughts I’ve had as well.

In my ideal note-taking environment, the note-to-note boundary should be allowed to be fluid, with the note-taking system not enforcing such boundaries. Especially, the file boundary should be abstracted away as far as possible. (The note <-> file-on-disk connection, for interoperability and future-proofing, could still be maintained.) Handling pages and blocks as similarly as possible would be a step in that direction.

What I write below is similar to what others have suggested above, but I’m taking the chance to present an overview and lay out the arguments.


Currently, LogSeq operates with a tree-structured hierarchy[1] with

  • pages for level 1, and
  • blocks for level 2…N.


* page A             1
  * block A-1        2
    * block A-1-I    3
    * block A-1-II   3
  * block A-2        2
* page B             1
  * block B-1        2

Linking to pages vs. blocks:

entity    level   referenced as
------    -----   -------------
page      1       [[title:: property of the page]]
block     2-N     ((block UUID))


This difference is, conceptually, somewhat arbitrary to me. I’d prefer to treat blocks and pages as similarly as possible. This is in line with @deniz notion of treating the blocks as first-class citizens.

Hence, ideally:

entity    level   can be referenced as
------    -----   --------------------
page      1       [[title:: property of the page]]
block     2-N     [[title:: property of the block]]


The link reference for pages is already kind of (allowed to be) separate from the page file name through the title:: and alias:: page properties. The same could be used for blocks - i.e., allowing reference by a title:: (or alias::) block property.


<page A file:>
title:: page A
* title:: block A-1
  some text of block A-1
<page B file:>
title:: page B
* first block of page B
* here, we could e.g. link to [[page A]] and [[block A-1]]

(The user has the option to define a title:: property for a block - UUIDs could also be used, as now.)

This would be the blank-slate ideal implementation. There’s probably aspects I haven’t thought of.

Also, I’m not sure how to handle title collisions, i.e. assuring titles for blocks and pages being globally unique. I guesse LogSeq already has to handle this for collisions on page titles, if defined with the title:: page property, or in any case for an alias:: colliding with another alias:: or page title. Some unified way of avoiding or handling such collissions could be used.

In practice, interoperability with Obsidian weighs heavily as well, and could be a strong reason to choose the Obsidian course rather than my ideal blank-slate suggestion.


  • All existing editors, even the web-based ones, have some hangover from file-based content management. Even with ability to cross-link to nodes inside a tree structure within files, the rigidity of file boundaries is still over-constraining, especially when one is trying to grapple with unfamiliar concepts during which the structure and links are constantly shifting.
  • It should take the concept of knowledge graph as far as possible. The foremost thing is to do away with files, and promote vertices (nodes) and links (relationships) to first-class status.

(from I actually grew really frustrated with existing solutions for organising notes: ... | Hacker News)

[1] a tree-structured hierarchy is defined as

every node is connected to
( (<= 1 parent node) AND
  (>= 0 child nodes)

Great write up. Agree that abstracting the file away and treating everything as blocks is an important step for this type of note taking. My one caveat is to work to keep the md files human readable in plain text, otherwise you might as well be using a standard database.

Re: title collisions, namespacing the title of every block by the parent block (i.e. page for top level blocks) seems to be the way that makes the most sense to me. This also fits well with those who suggest the [[page-a#block-1]] block linking syntax.

1 Like

I am too new to Logseq to understand all the details in this conversation, but I strongly urge allowing the [[page#block]] notation for block references. I already have a page for an online course I’m taking, but my notes so far have been in the Journal. I want to move my lecture notes to the course page, but know that a block named “Lecture 3” will not be unique forever. Furthermore, I want the Course name with the block reference for context clarity. Placing two references, one to the page, one to the block in the referring context is redundant, cumbersome and error prone.

My one caveat is to work to keep the md files human readable in plain text, otherwise you might as well be using a standard database.

Agree - being able to reference by user-named block titles, rather than generated UUIDs, seems like a step in that direction.

(On a side note, I am not personally totally convinced that text files rather than a database is the optimal data store for an ideal note-taking system - but that’s another question, and the LogSeq forum is probably not the right place for me to raise such ideas.)

Re: title collisions, namespacing the title of every block by the parent block (i.e. page for top level blocks) seems to be the way that makes the most sense to me.

Really? Why name-space with parent block rather than parent page? The full block hierarchy string could get very long.

Another aspect is moving blocks around over different pages. Cut-paste of a block to a new page would require LogSeq to re-write any references to custom-named blocks (if name-spaced with parent page or blocks). This won’t be an issue with UUIDs of course since they are always unique.

I would lean towards not namespace-ing block titles with parent page/block, but rather to require block names to be unique, just as is the case for page titles and aliases now. It seems cleaner and more general to me.

This seems a reasonable compromise to eliminate the obfuscation of UUIDs. This could easily be enforced at block naming time. I had not considered the issue of moving blocks from one page to another.

1 Like

Fair. One way to think of Logseq is as a three way relationship between the md files, the interface, and the application database. The interface is used to modify the md files, and the database is updated at some frequency from those md files (sometimes requiring a reindex). But all the richer actions, like querying and searching, require the database. Just a relationship your comment made me think about.

True names would get long, but I am thinking of it as an “under the hood” namespacing to allow reusing block names in the same page (imagine a page with multiple lists where the user wants to name their blocks the number of the item).

Perhaps the best way to access a block’s full reference name would be by searching for it anyways, rather than having to type out its parent and path (thinking about how Obsidian does something like this, search for a block by using the [[^^ syntax, iirc).

But yea, page namespacing also makes some intuitive sense, especially since users won’t name all their blocks. Considering that, simply a better automatic naming by Logseq could be a good middle ground. Maybe a shorter page specific unique ID for each block with the option to rename? This is essentially how Obsidian does it last I checked over a year ago.

One way to think of Logseq is as a three way relationship between the md files, the interface, and the application database. The interface is used to modify the md files, and the database is updated at some frequency from those md files (sometimes requiring a reindex).

Yes - and this is exactly my reason for doubting this model. The md files<->application database relationship is preferrably the identity relationship at every point in time. Which is against the DRY/Don’t repeat yourself/Single-point-of-truth principle.

Which seem to be the culprit for several of the main drawbacks I see with LogSeq:

  • data corruption
  • data store-related bugs, e.g. when moving bullets with drag-and-drop
  • buggy multiple main-window experience
  • namespace feature is buggy
  • weak scalability for a large number of notes
  • weak query performance for large number of notes/queries
  • opaque data model <=> queries seem to be buggy and not well documented
  • weak structure semantics (for things like templates, attributes and more)

To that, I’ll add that the list of the benefits with LogSeq is a long list as well :smiley:

I would feel a lot more safe with a well-designed database for the back-end datastore. It could (perhaps as an option) mirror to generated .md files, continously or at request.

The data store question is a tangent, but an interesting one.

1 Like

I think a reference format based on block-names rather than UUID could unlock a host of other natural features in Logseq.

Right now, as far as I know, you can’t :

In other words, at the moment “everything is a block in Logseq” except pages, which are more much central than blocks but are also less flexible in other respects.

The way I see it, a [[page-name#block-name]] format would make it easier to integrate in favorites and graph, as well as any other features where pages refs show up but block refs don’t. Inter-operability with other markdown editors is a welcomed bonus.

Extending that idea the other way around, you could also have a ((page-name)) reference format that inserts the (editable) contents of the pages seamlessly in the document you’re working on.

This to me is an important step towards making references as easy as possible. As @and_yet_it_moves mentioned, page vs block is mostly a file system distinction & there’s no reason to force our thinking to adhere to it, rather it should be the opposite.

1 Like

Yes - and just like you seem to do, I note that your three points are more about getting rid of the page<->block distinction rather than referencing blocks with something else than UUIDs.

The announced Tana outliner, which seems to be a main talking point in the PKM community at the moment, takes this route: everything is a block (but they call it node) - the “pages” are gone. I’d guess it will give the other outliners like LogSeq and Roam quite a competition.

That’s where I’m getting at, indeed. It just seems to me that having a standardized reference syntax is the biggest thing that’s missing for Logseq to get there.

I know, I’m in the Tana beta :sweat_smile:. And obviously I love that aspect of the tool, but the always-online aspect is more of a bother than I thought and I’m trying to figure out if Logseq could fill in most of my needs. (Logseq seems to be working on unified types too)

Good point. What about some middle-ground, which focuses on searching blocks via path argument like with page namespaces [[parent/child]], but inserts UUID in the end?
So page name is typed out first via some name part: ((/Log)) and autocompleted to ((/Logseq)). Leading or trailing slash (/) or some other user interface toggle could be used to make editor aware, we are doing path and not full content search. Auto-complete then suggests all top-level blocks ((/Logseq/features)), ((/Logseq/versions)) etc., which are narrowed down to your typed pattern like ((/Logseq/feat))((/Logseq/features)). Further traversing and auto-completing in deeper block levels leads to desired block ((/Logseq/features/namespace)) and UUID is then inserted as usual.

Hi Logseq team! I created an account just to upvote and add a voice to this request. Please make block references readable outside of Logseq, it is crucial for the long-term usability of Logseq’s notes. I chose Logseq over something like Tana because I own my data in local markdown files, and I would like to make more use of block references, but the fact that they are generated as ((UUID)) makes me unable to realistically do so.

For example, every week I do a weekly review where I look over my last week’s worth of journals, and I’d like to make block references to significant events and interesting thoughts that I had. However, if I look at my Markdown file outside of Logseq, my weekly review looks like a string of unintelligible ((UUID)). I am hesitant to use any feature that makes my Markdown files unreadable outside of Logseq, and it’s a pity that this is such a core feature.

Right now I’m getting round this by doing links instead, so if I wanted to reference e.g. “Attended a concert” I would type this in my weekly review as [Attended a concert](((UUID))), but it would be so much better if block references were simply readable.


There was a block aliases feature at the past!
Related task: regression to block alias feature ? · Issue #3915 · logseq/logseq · GitHub

1 Like