For a Markdown note you edit in Obsidian on a Mac and read on GitHub, use standard Markdown links and unique, lowercase heading names. Single words such as setup give both renderers the same target; headings with spaces need closer attention.

This guide focuses on navigation within a note and between two Markdown files. The practical goal is to maintain one readable document without assuming that every Markdown renderer interprets heading destinations identically.

Why can a valid Markdown link miss its heading?

A heading link has two separate requirements: the Markdown parser must recognize the link, and the renderer must resolve its destination. A clickable link demonstrates the first requirement. Landing at the intended section demonstrates the second.

CommonMark defines heading syntax and links containing fragments, including [link](#fragment). Its heading examples do not establish a universal heading-ID generation algorithm. That distinction explains why valid Markdown syntax alone cannot guarantee matching section navigation across applications. See the CommonMark heading specification and link specification.

GitHub generates heading anchors by lowercasing letters, replacing spaces with hyphens, removing other punctuation and formatting, and disambiguating repeated anchors with numeric suffixes. Obsidian documents heading links using the heading text after #. These are different destination conventions. See GitHub’s section-link rules and Obsidian’s internal-link documentation.

Obsidian supports CommonMark and GitHub Flavored Markdown alongside its own extensions. That support does not make every application-specific link interchangeable: Obsidian explicitly warns that some extensions may appear as plain text in other apps. Its Markdown compatibility documentation describes this boundary.

Which heading convention gives both renderers the same target?

For a new shared note, choose unique heading names made from lowercase ASCII letters, using a single word where practical. For longer names, a form such as desk-layout is a useful option: the visible heading text already matches the GitHub-style fragment.

This is a convention derived from the documented rules, rather than a separate compatibility feature. With setup, there are no spaces, uppercase letters, or formatting for either renderer to interpret differently. The visible heading and the destination remain easy to compare.

Heading in the file Obsidian heading-text destination, URL-encoded GitHub-generated destination
## setup #setup #setup
## desk-layout #desk-layout #desk-layout
## Desk Layout #Desk%20Layout #desk-layout

The table applies the Obsidian heading-text and URL-encoding guidance and GitHub anchor rules. It deliberately avoids assuming that Obsidian accepts every GitHub-normalized fragment.

There is a visible tradeoff: desk-layout reads more like an identifier than a conventional section title. If natural titles matter more, retain them and verify the resulting links in both applications. Do not rename a whole document before deciding which tradeoff suits its readers.

A complete note to try

Create a note named desk-notes.md and paste the following Markdown into it. This is a complete sample document, using synthetic content; the fence is only there to show the source.

Desk notes

Jump to [setup](#setup), [materials](#materials), or
[desk layout](#desk-layout).

## setup

Place the notebook beside the keyboard.

## materials

Use a notebook, a pencil, and a desk tray.

## desk-layout

Keep the tray beside the notebook.

Return to [setup](#setup).

Notice that the link label can use ordinary spacing: [desk layout](#desk-layout) displays readable text while preserving the destination. You do not need to make every navigation label look like the heading identifier.

For a real note, give sections enough content to make navigation visible. In a very short document, a successful jump may produce little movement because the entire note already fits in the window.

How should you configure and test Obsidian on a Mac?

Start with the note itself, then adjust how Obsidian generates future links. These are separate checks: changing a link-generation preference is not a substitute for inspecting the Markdown already present.

  1. Open Settings from the sidebar.
  2. Under Files and links, disable Use Wikilinks so generated links use Markdown syntax.
  3. Set New link format to Relative path to file for links between shared files.
  4. Inspect existing destinations before relying on the new settings.

Obsidian documents the desktop settings entry point and both link-generation preferences in Settings. Relative paths are a useful choice here because the shared folder structure becomes explicit.

Switch the sample note to Reading view with Command+E, then click each navigation link. Obsidian documents that shortcut for macOS and explains that reading view hides Markdown syntax. Use the same view for repeatable checks instead of mixing editing gestures with navigation tests. See Views and editing mode.

Next, inspect the rendered file on GitHub. Hover over a heading and click its link icon to inspect the actual fragment. Compare that fragment with the text after # in your source link. GitHub documents this inspection method in Section links.

Use a small acceptance checklist: the link appears as a link, selects the intended file, and reaches the intended heading. Record failures by destination rather than changing several headings at once. That makes it easier to tell whether a correction addressed a filename, a path, or a fragment.

How do you link to a heading in another file?

Keep the first example simple: put two files beside each other. Create index.md in the same folder as desk-notes.md, then give it this complete content:

Desk index

Read the [setup notes](desk-notes.md#setup).

Review the [desk layout](desk-notes.md#desk-layout).

The destination has two parts: desk-notes.md selects the file, and #setup selects the section. GitHub resolves relative file links from the current file; Obsidian provides a relative-path generation setting. Those documented behaviors support this same-folder arrangement. See GitHub relative links and Obsidian link settings.

Preserve the same relative arrangement wherever you read these documents. If you move only index.md into a subfolder, its existing sibling-file destination no longer describes the arrangement you started with. Recalculate the path before investigating the heading.

Keep the .md extension explicit in shared file links. For filenames containing spaces, use %20 in Markdown destinations, following Obsidian’s URL-encoding guidance. Encoding a space preserves a space; it does not turn a heading into GitHub’s hyphenated anchor.

What should you do with existing headings and broken links?

Use this diagnostic sequence before introducing plugins or extra anchor mechanisms. It isolates the smallest failing part of the document.

  1. Check the heading source. Confirm that the target is an actual Markdown heading, such as ## setup, with a space after the opening hashes. CommonMark requires that separation for a heading containing text. See ATX headings.
  2. Check the link syntax. Use [setup](#setup). Keep the closing bracket adjacent to the opening parenthesis; [setup] (#setup) is not an inline link under the CommonMark link rules.
  3. Separate file resolution from section resolution. For a cross-file failure, temporarily test a link to the file without the fragment. If that fails, correct the path first.
  4. Compare heading text with the fragment. For a natural title such as Desk Layout, return to the renderer comparison above. Changing %20 to - changes the target convention.
  5. Check for repeated targets. Prefer distinct names such as notebook-setup and tray-setup. GitHub’s numeric suffixes depend on duplicate-anchor order, so rearrangement can change destinations. See GitHub section links.

When a document already uses natural section titles, start by fixing its most useful navigation link. If matching fragments would make the headings awkward, maintain renderer-specific destinations where necessary rather than describing an unverified spelling as portable. Test the exact source you intend to keep.

Recheck incoming section links whenever you rename a heading. Obsidian’s Automatically update internal links setting documents updates when a file is renamed; that description alone is insufficient evidence that every heading edit will repair its incoming links. See Obsidian’s setting description.

For a small shared note, the most maintainable result is usually explicit Markdown file links, unique heading targets, and a brief check in each renderer after structural edits. Start with the sample convention, preserve the file arrangement, and only add complexity when a concrete navigation requirement calls for it.

Sources