---
title: "Markdown links to other files and local files"
slug: markdown-links-to-local-files
excerpt: "Link one Markdown file to another with a relative path, point at a heading or image, handle spaces in names, and find links that broke."
quickAnswer: "To link one Markdown file to another, write an inline link with a relative path as the target, like [Plan](notes/plan.md). Add # and a heading id to land on a section, like [Setup](notes/plan.md#setup). Use ../ to step up one folder. CommonMark won't read a bare target that has a space in it as a link, so wrap it in angle brackets, like [Notes](<my notes.md>), or write %20 for each space. In most viewers, relative paths keep working when you move the whole folder, because the files keep the same places relative to each other. Absolute paths and file:// links tie the file to one computer. Whether a viewer opens a linked .md file when you click it depends on the viewer."
keyTakeaways:
  - "A link to another file is an ordinary inline link whose target is a path, such as [Plan](notes/plan.md)."
  - "Put # and a heading id after the file name to point at a section. The id itself comes from your viewer, not from CommonMark."
  - "A target with a space needs angle brackets or %20. Without them, CommonMark leaves the line as plain text."
  - "In most viewers, relative paths survive a folder move. Absolute paths and file:// links tend to break on the next machine."
  - "Wikilinks are an extension, not CommonMark. Sashmark, still unreleased, plans to let you click a wikilink to open its file."
publishedDate: 2026-10-20
dateModified: 2026-10-20
author: Bobby Huang
cluster: B
role: post
status: published
faq:
  - q: Why does my link to another .md file show as plain text?
    a: "The most common cause is a space in the path. CommonMark only accepts spaces in a link target when the target sits inside angle brackets, so [Notes](my notes.md) stays as text. Write [Notes](<my notes.md>) or [Notes](my%20notes.md) instead, or give the file a name with no spaces."
  - q: Do relative links work if I move the folder?
    a: "Yes, as long as the files move together. Most viewers resolve a relative link like notes/plan.md against the folder of the linking file, so the pair keeps working wherever the folder lands. Moving only one of the two files is what breaks it."
  - q: Are [[wikilinks]] part of Markdown?
    a: "No. CommonMark defines no double-bracket link. Some note tools and converters add wikilinks as an extension, and pandoc can read them when you turn that extension on. In a viewer without wikilink support, a file full of them may show raw brackets."
related:
  - markdown-headings-anchor-links
  - markdown-images
  - organize-agent-written-docs-folders-front-matter-handoffs
---

Agent work leaves a trail of files that point at each other. A handoff names the plan it follows, the plan names a receipt, and the receipt names the screenshot that proves the step ran. Those pointers only help if a reader can follow them.

Below are the link forms that hold up when a folder moves to a new machine, plus a short pass to catch the ones that don't. The [syntax guide](markdown-syntax-guide.md) handles every other element.

## 1. Write a link to another file

A link to a file uses the same inline syntax as a link to a web page. Square brackets hold the text, and the path goes in the parentheses.

```markdown
Next steps are in [the plan](notes/plan.md).
```

CommonMark parses this into one link. Its text is "the plan" and its destination is `notes/plan.md`. The spec doesn't check that the file exists. It only records the target.

An optional title may follow the path in quotes, with a space before it, like `[the plan](notes/plan.md "Release plan")`. Many viewers display that title when you hover.

## 2. Point at a heading in that file

Add `#` and the heading's id after the file name.

```markdown
Read [the setup steps](notes/plan.md#setup) first.
```

To the parser, the whole string `notes/plan.md#setup` is one destination. Heading ids are not defined by the spec, so the part after `#` has to match whatever id your viewer builds. The post on [heading ids and anchor links](markdown-headings-anchor-links.md) explains how viewers build those ids and how to read the one yours made.

## 3. Climb up with ../

In most viewers, a relative path starts from the folder of the file that holds the link. `../` steps up one level.

```markdown
docs/
  handoff.md
  notes/
    plan.md
    receipts/
      step-2.md
```

From `notes/receipts/step-2.md`, a link back to the plan is `[plan](../plan.md)`. A link to the handoff climbs two levels: `[handoff](../../handoff.md)`. From `handoff.md` going down, it's `[receipt](notes/receipts/step-2.md)`.

Images work the same way, with a `!` in front, since the spec builds image syntax on link syntax. The [image paths guide](markdown-images.md) covers alt text and the reasons a local image fails to show.

## 4. Link to a folder

A target can be a folder, like `[done work](done/)`. CommonMark treats it like any other destination. Each viewer decides what a click does: some show a file list, some open the folder in your system's file browser, and some do nothing. If a reader needs one file, link that file.

## 5. Handle spaces in file names

A space in a file name is an easy way to break a link. CommonMark only allows a space in a link target when the target sits inside angle brackets.

```markdown
[Meeting notes](meeting notes.md)
[Meeting notes](<meeting notes.md>)
[Meeting notes](meeting%20notes.md)
```

The first line isn't a link at all. It stays as text with the brackets showing. Line two is a link. The third is too, because `%20` is not a space character, and the spec keeps codes like `%20` as written in the target.

Whether a viewer turns `%20` back into a space when it looks for the file varies. Angle brackets keep the source closer to the real name. The simplest fix is a file name with hyphens instead of spaces, which also makes the shell loop below easier to trust.

## 6. Use reference-style links for long paths

Long paths make a paragraph hard to read. A reference link moves the path to a separate line.

```markdown
The rollback is in [the runbook][rb], and the last run is in [step 2][].

[rb]: ops/runbooks/rollback-for-release.md#before-you-start
[step 2]: notes/receipts/step-2.md
```

The definition lines don't show in the output. They may appear before or after the links that use them, and labels match without regard to case, so `[RB]` finds `[rb]`. If two definitions share a label, the first one wins. The `[step 2][]` form uses its own text as the label.

One upside for agent files: when a file moves, you fix one definition line instead of every link that uses it.

## 7. Avoid absolute paths and file:// links

An agent working on your machine may write a full path, for example `/Users/janedoe/projects/docs/plan.md`, or a `file:///` address. Both name a spot on one computer. On a teammate's laptop, in a fresh clone or in a renamed folder, that spot may not exist.

Some viewers also block `file://` links for safety, so they may fail even on the machine that wrote them. Relative paths have neither problem.

## 8. Know why links break after an agent moves files

A relative link describes where one file sits compared to another. It breaks when that relationship changes:

- The agent moves a finished plan into a `done/` folder, but the handoff still points at the old spot.
- A file gets renamed for a date prefix, and nothing updates the links to it.
- A file moves one level deeper, so its own `../` links now land one level short.
- A heading is reworded, so `plan.md#setup` points at a heading id that is gone.

Many viewers give no warning for a dead link. You find out when a click goes nowhere. A tidy folder plan, like the one in [organizing agent docs into folders](organize-agent-written-docs-folders-front-matter-handoffs.md), cuts down on moves in the first place.

## 9. Check and fix every local link

Run this pass after any agent session that moved or renamed files.

1. **Open a terminal in the docs folder.** The paths in the loop are read from there.
2. **Run the check.** This works in the default shell on macOS and Linux. It prints each link whose target file is missing.

```sh
find . -name '*.md' | while IFS= read -r f; do
  dir=$(dirname "$f")
  grep -oE '\]\([^)]+\)' "$f" |
    sed -E 's/^\]\(//; s/\)$//; s/#.*//; s/^<//; s/>$//' |
    while IFS= read -r t; do
      case "$t" in ''|*:*) continue ;; esac
      [ -e "$dir/$t" ] || echo "$f -> $t"
    done
done
```

3. **Read the limits.** The loop skips web links and same-page `#` links. It doesn't check heading ids, decode `%20`, read reference definitions, or handle a target followed by a title. It also checks link examples inside code blocks, so ignore hits from samples. Treat a clean run as a good sign, not proof.
4. **Find where the file went.** For each line printed, search by name with `find . -name 'plan.md'`. If you use git and know the new path, `git log --stat --follow -- new/path.md` shows the rename that brought it there.
5. **Fix the path.** Rewrite it relative to the file that holds the link. For a reference link, edit the one definition line.
6. **Run the check again.** Stop when it prints nothing.
7. **Spot-check headings by hand.** Click a few `file.md#id` links in the viewer your team reads in.

So the fix sticks, add a line like this to the agent's project notes:

> When you move or rename a Markdown file, update every relative link to it in this folder in the same change. Use relative paths only. Never write absolute paths or file:// links. Use hyphens, not spaces, in new file names.

## 10. Treat wikilinks as an extension

Some note tools link files with double brackets, like `[[plan]]`. That's not CommonMark. The spec has no such form, and with no matching reference definition, a CommonMark parser leaves the brackets as written. Pandoc can read them through a wikilink extension that you name in its options, such as `--from=markdown+wikilinks_title_after_pipe`.

If the files need to read well in many tools, standard relative links are the safer default. If your team's tool supports wikilinks, they're shorter to type, but they may not survive a move to a viewer that lacks the extension.

## Where Sashmark fits

For people whose agents keep rewriting their .md files, Sashmark is being made as a desktop app to view and edit Markdown. It is in development and has not been released. Rendered links are part of the v1 plan, and so is clicking a wikilink to open the file it names. The app itself has no AI features. Our [roadmap](/roadmap), [help pages](/help) and [planned features](/features) list what is planned and what is further out.

Keep up with the project at [sashmark.com](https://www.sashmark.com/).
