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.

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).

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.

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.

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.

External URLs and URI links are kept as href links:

markdown
[DocInsight](https://docinsight.dev)
[Email support](mailto:[email protected])

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

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.