# Add links and cross-references

Use the narrowest link type that matches the target:

Target | Use
--- | ---
Topic with a stable source path | Relative or root-relative Markdown link
Topic whose stable identity matters | Cross-reference (Xref)
Generated API reference topic | Cross-reference (Xref)
External page | URL link
Download, sample, or other project asset | Path beginning with `/`

Cross-references use stable identities instead of physical source paths or generated output paths. They are preferred when content may move or when a mount, target, or reference structure can change its output path.

## Link to another topic

Use normal Markdown links when a topic has a stable source path:

markdown

    See [Installation](installation.md).

The target may belong to the current content entry or another declared content entry selected by the output target. Use an Xref when you want the link to survive a source-file move.

Relative paths are resolved from the source topic directory:

text

    docs/
    |-- getting-started/
    |   |-- overview.md
    |   `-- installation.md
    `-- markdown/
        `-- topics.md

From `docs/markdown/topics.md`, link back to the getting started topic like this:

markdown

    See [Overview](../getting-started/overview.md).

## Link to a section

Add a heading anchor after the topic path:

markdown

    See [Install the CLI](installation.md#install-the-cli).

The heading anchor should match the generated anchor for the heading text. Keep headings stable when other topics link to them.

## Link to an index topic

A directory link resolves to `index.md` when that topic exists:

markdown

    See [Markdown](markdown/).

Use a directory link when the target is the landing topic for that folder. Use the explicit file path when linking to a specific topic:

markdown

    See [Topics](markdown/topics.md).

## Resolve across content owners

Relative paths first resolve inside the source topic's content entry. If a topic is not owned there, DocInsight can resolve it through `project.reference_root` to another declared Markdown content entry. For example, a topic in `docs` can link to a topic owned by `internals`:

markdown

    [Internal design](../internals/design.md)

The output target must select both content entries. The path does not select or publish `internals` automatically. If multiple entries own portable-equivalent paths, the reference is ambiguous. Generated content without an authored file path should be linked by Xref.

## Cross-reference another content entry

An Xref can resolve only when the selected output target publishes both the source content entry and the content entry that exports the target:

json

    {
      "output": {
        "targets": {
          "site": {
            "type": "html",
            "path": "dist/site",
            "content": ["docs", "api"]
          }
        }
      }
    }

A provider-qualified Xref address has a namespace followed by the target identity:

text

    namespace/id

Markdown topics use the content entry name as the namespace. Delphi API topics instead use the effective namespace for their Delphi project. By default, that namespace is the DocInsight project name. For example:

Target | Namespace
--- | ---
Markdown content entry `docs` | `docs`
Delphi API project in project `MyLibrary` | `mylibrary`
Delphi project `MyLibrary.Tests` with an override | `mylibrary.tests`

Configure Delphi API namespaces with `sources.<name>.xref.namespace` and exact project overrides under `sources.<name>.xref.projects`. See Configure Xref namespaces.

Markdown topics use their topic IDs as identities. Delphi API topics use source-owned structural identities and accept case-insensitive Pascal declaration spelling in authored Xrefs. Generated paths and mounts do not change these identities.

Use a Markdown link whose target is `xref:namespace/id`:

markdown

    See [Installation](xref:docs/guide/install).

    See [IList<T>](xref:mylibrary/MyLibrary.Collections/IList{T}).

Use an Xref autolink when the target's display name is the appropriate link text:

markdown

    See <xref:mylibrary/MyLibrary.Collections/TCollections>.

An Xref autolink does not need a separate link label.

An Xref can also include a heading anchor:

markdown

    See [List methods](xref:mylibrary/MyLibrary.Collections/IList{T}#methods).

### Configure a document Xref scope

Every Markdown topic has its own Xref scope. Use the optional front matter `xref.base` for its default binding and `xref.aliases` for document-local named bindings:

markdown

    ---
    xref:
      base: mylibrary/MyLibrary.Collections
      aliases:
        list: mylibrary/MyLibrary.Collections/IList{T}
        add: mylibrary/MyLibrary.Collections/IList{T}.Add
    ---

Base and alias values are absolute bindings without a leading `/`. Alias names are case-insensitive and cannot contain `/`.

Use these address forms with the example above:

Address | Meaning
--- | ---
`/mylibrary/MyLibrary.Collections/IList{T}.Add` | Start from the root Xref scope
`.` | Reference the configured base itself
`./IList{T}.Add` | Start explicitly from the configured base, bypassing aliases
`IList{T}.Add` | Try an alias, then the effective base
`list` | Reference the `list` alias itself
`list/Add` | Continue with `Add` from the `list` alias

For an ordinary unrooted address, DocInsight tries a document alias first, then the effective base: `xref.base` when configured, otherwise the root Xref scope. A leading `/` skips the document scope and starts from the root.

`.` and `./...` require `xref.base`; without it, references such as `[[.]]` and `<xref:.>` are unresolved. `.` also requires the base itself to identify an entity. After DocInsight selects a binding, a failed continuation does not fall back elsewhere. When a base is configured, use `/` for an absolute provider Xref.

The leading `/` in an Xref address is unrelated to the leading `/` in a Markdown topic or asset path. Xrefs use the root Xref scope; Markdown paths use `project.reference_root`.

### Use WikiLinks as Xref shorthand

WikiLinks are shorthand for Xrefs:

WikiLink | Equivalent Xref
--- | ---
`[[IList{T}.Add]]` | `<xref:IList{T}.Add>`
`[[list/Add|Add an item]]` | `[Add an item](xref:list/Add)`

They use the same lookup rules as other Xrefs. WikiLinks are not recognized inside code, raw HTML, or another link's label. Escape the first bracket as `\[[` to keep the text literal.

Document bases, aliases, and WikiLinks apply to Markdown topics. They do not change how an `xref` attribute in Delphi XML documentation is resolved.

Use a normal relative or root-relative Markdown link when the target's source path is the contract you want to preserve.

## Cross-reference from API comments

Use `cref` for a Delphi symbol in the analyzed compilation environment:

pascal

    /// <summary>
    ///   Creates a list. See <see cref="IList{T}" />.
    /// </summary>
    class function CreateList<T>: IList<T>; static;

Use `xref` for an explicit DocInsight Xref, including a link to a Markdown topic:

pascal

    /// <seealso xref="docs/guide/install">
    ///   Installation guide
    /// </seealso>

Use `href` for an external URL. For more examples, see Link API symbols and topics.

## Keep cross-references stable

When other content links to a Markdown topic by Xref, keep its topic ID stable. Set an explicit `id` if the topic may move:

markdown

    ---
    id: guide/install
    ---

    # Installation

When an Xref does not resolve, check that:

- The selected output target publishes the target content entry.

- The namespace matches the Markdown content entry name or the Delphi project's effective Xref namespace.

- The target identity exists and is not a draft.

- The selected anchor exists in the target.

## Link to external pages

External URLs and URI links are kept as href links:

markdown

    [DocInsight](https://docinsight.dev)
    [Email support](mailto:support@example.com)

Links that start with `#` or `?` are also kept as raw href links.

## Link to project assets

Use a root-relative path for a download, sample, or other file published by a project asset set:

markdown

    [Download the sample project](/downloads/sample-project.zip)
    [Download the starter sample](/downloads/starter.zip)

DocInsight resolves the path against `project.reference_root`. The file must be included by one project asset set, and every output target that publishes the topic must select that set. See Markdown path compatibility and Assets for configuration and selection rules.

Use a relative Markdown path for a nearby file. DocInsight first looks for a resource owned by the current content entry, then may resolve another declared content or asset-set owner through `project.reference_root`. The output target must select the final owner.

For images, use image syntax and the guidance in Add images and assets.