Support Named Anchors or Heading IDs

Use case or problem

Link to a particular part of a target page while either:

  • Not having nearby header
  • Not having to put the same name as the header into the link

The general use case is just being able to navigate around documents without messing up the outline view with headings everywhere.

I also have a specific situation where I web clip sites and rewrite absolute URLs into wikilinks, but the anchor tags are ignored inside documents so internal links are all semi-broken. Sometimes hundreds of them.

Proposed solution

Support XHTML self-closing anchor tags using the name or id attributes.

[to foo](#foo)
[[#foo|to foo]]

<a name="foo" />
It was the best of foo it was the worst of foo.

I specify self-closing tags, because Obsidian currently highlights the contents of any a tag, even if it doesn’t have an href and is not a link. This seems like it might have less of an impact.

Alternatively (or in addition), support heading IDs and linking to them.

[to foo](#foo)
[[#foo|to foo]]

# This is my Foo {#foo}
It was the best of foo it was the worst of foo.

Current workaround

I m considering writing a script that extracts anchor tags from files and matches them to the nearest heading to rewrite all the links to anchors. This is extremely suboptimal.

Another DIY development option would be writing a plugin which detects that you clicked on a link where the heading was missing and then looks for similar headings or text matches.

Related feature requests

1 Like

An example of the kind of situation I have ended up having to figure out without the ability to use anchors or heading ID links.

This is from some documentation which is packed with links, not just this ToC but it also has over a hundred internal links between multiple documents in this same format.

I also like to pair a simple word with a description to the right, and put all that into every link is non-ideal.

I bet link rewriting would get extra FUN after supporting these features though. :grimacing:

This does work already.

Otherwise, have you tried block references?

I haven’t gotten internal links to work with anchor tags like <a name="foo" />.

What are you seeing that works on your end?

I guess I don’t understand your request. The following works fine:

[to foo](#foo)
[[#foo|to foo]]


# Foo

And again, have you tried block links?

The request is not about linking to headings by name. It is about linking to arbitrary locations. Headings are just one location to jump to.

Use Case 1

Speaking of which, today I realized that Obsidian doesn’t update links when headings change, which makes this an even bigger priority for me.

In long_document.md:

# This is a long heading that I might rename and not want to break every link to it when I do so. {#long-heading}

Later in other_document.md:

[[long_document#long-heading]]

So when I change the heading text it doesn’t break all my links and table of contents. It would also mean I could at least programmatically generate links to headings with different names.

Use Case 2

Here’s some real HTML I would like to convert in my script, for example (there are dozens or more of these entries):

<P><TABLE BORDER="1" CELLPADDING="0" CELLSPACING="0" WIDTH="450">
  <TR>
    <TD WIDTH="7%" HEIGHT="25">
      <P><CENTER><A HREF="#ADC">ADC</A></CENTER></TD>
    <TD WIDTH="7%">

...

<H3><A NAME="ADC"></A>ADC - Add with Carry</H3>

Note that the anchor and the contents of the heading are different. All links point to that anchor, not the heading.

If we had Heading IDs or anchor support I could easily do this. These name anchors are used within a single document as well as between documents, so they’re canonical. Without such ability, I will have to rewrite every heading to be just the contents of the name and move the rest of the heading into a paragraph below, or rewrite all links based on the parsed document’s current heading text - and since those links are fragile, they’re kinda pointless if I do update the headings (see use case 1)

BlockIDs

BlockIDs are really cool, and kinda gets you something similar, but you can’t generate them from plain text, only Obsidian can generate them. And that requires a lot of manual work or writing a fragile plugin that would hook into Obsidian’s internal code in order to generate them.

The above use case 2 example cannot be automatically converted to use BlockIDs without writing an Obsidian plugin. And it doesn’t really solve for use case 1.

The Case for Something Different

Anchors are just plain HTML and supported everywhere, and heading IDs are clean and supported by at least some other markdown viewers/editors.

Both allow anyone to write a simple script to convert them from HTML or inject them into files as needed or go through and clean them up automatically. I can’t do any of that with BlockIDs.

Both allow anyone to change heading text without worrying about fixing wikilinks. And it means the Obsidian team doesn’t have to worry about writing code to track down all those links and fix them since they become more resilient.

No, you can write your own. ^thisblockwouldwork

[[#^thisblockwouldwork]]

Well hell. I was reading some old issues on Github about them and I must have misunderstood what they were saying about how they worked.

Looks like it is setting the data-heading attribute on headings and wrapping the ID’s text in a span.cm-blockid tag for lookups.

You can also create human-readable block identifiers by adding ^quote-of-the-day at the end of a block. Note the blank space before the caret. Now you can instead link to the block by typing [[2023-01-01#^quote-of-the-day]].

Totally didn’t get what it was saying. It was so obvious I missed it.

Thanks for taking the time to point me in the right direction!

1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.