Links and Cross References
Markdown provides a syntax to create hyperlinks. For example, the following syntax:
[bing](http://www.bing.com)
Will render to:
<a href="http://www.bing.com">bing</a>
Here the url in the link could be either absolute url pointing to another website (www.bing.com
in the above example),
or a relative url pointing to a local resource on the same server (for example, about.html
).
When working with large documentation project that contains multiple files, it is often needed to link to another Markdown file using the relative path in the source directory.
Markdown spec doesn't have a clear definition of how this should be supported.
What's more, there is also a common need to link to another file using a "semantic" name instead of its file path.
This is especially common in API reference docs, for example, you may want to use System.String
to link to the topic of String
class, without knowing it's actually located in api/system/string.html
, which is auto generated.
In this document, you'll learn the functionalities DocFX provides for resolving file links and cross reference, which will help you to reference other files in an efficient way.
Link to a file using relative path
In DocFX, you can link to a file using its relative path in the source directory. For example,
You have a file1.md
under root and a file2.md
under subfolder/
:
/
|- subfolder/
| \- file2.md
\- file1.md
You can use relative path to reference file2.md
in file1.md
:
[file2](subfolder/file2.md)
DocFX converts it to a relative path in output folder structure:
<a href="subfolder/file2.html">file2</a>
You can see the source file name (.md
) is replaced with output file name (.html
).
Note
DocFX does not simply replace the file extension here (.md
to .html
), it also tracks the mapping between input and
output files to make sure source file path will resolve to correct output path. For example, if in the above case,
subfolder
is renamed to subfolder2
using file mapping in
docfx.json
, in output html, the link url will also resolve to subfolder2/file2.html
.
Relative path vs. absolute path
It's recommended to always use relative path to reference another file in the same project. Relative path will be resolved during build and produce build warning if the target file does not exist.
Tip
File must be included in docfx.json
to be processed by DocFX, so if you see a build warning about broken link but the file
actually exists in your file system, go and check whether this file is included in docfx.json
.
You can also use absolute path (path starts with /
) to link to another file, but DocFX won't check its correctness for you and will keep it as-is in the output HTML.
That means you should use the output file path as absolute path. For example, in the above case, you can also write the link as follows:
[file2](/subfolder/file2.html)
Sometimes you may find it's complicated to calculate relative path between two files.
DocFX also supports path starts with ~
to represent path relative to the root directory of your project (i.e. where docfx.json
is located).
This kind of path will also be validated and resolved during build. For example, in the above case, you can write the following links in file2.md
:
[file1](~/file1.md)
[file1](../file1.md)
Both will resolve to ../file1.html
in output html.
Warning
Automatic link doesn't support relative path.
If you write something like <file.md>
, it will be treated as an HTML tag rather than a link.
Links in file includes
If you use file include to include another file, the links in included file is relative to the included file. For example, if file1.md
includes file2.md
:
[!include[file2](subfolder/file2.md)]
All links in file2.md
are relative to the file2.md
itself, even when it's included by file1.md
.
Note
Please note that the file path in include syntax is handled differently than Markdown link.
You can only use relative path to specify location of the included file.
And DocFX doesn't require included file to be included in docfx.json
.
Tip
Each file in docfx.json
will build into an output file. But included files usually don't need to build into individual
topics. So it's not recommended to include them in docfx.json
.
Links in inline HTML
Markdown supports inline HTML. DocFX also supports to use relative path in inline HTML. Path in HTML link (<a>
), image (<img>
), script (<script>
) and css (<link>
) will also be resolved if they're relative path.
Using cross reference
Besides using file path to link to another file, DocFX also allows you to give a file a unique identifier so that you can reference this file using that identifier instead of its file path. This is useful in the following cases:
- Path to file is long and difficult to memorize or changes frequently.
- API reference documentation is usually auto generated so it's difficult to find its file path.
- You want to reference to files in another project without need to know its file structure.
The basic syntax for cross referencing a file is:
<xref:id_of_another_file>
This is similar to automatic link syntax in Markdown but with a xref
scheme. This link will build into:
<a href="path_of_another_file">title_of_another_file</a>
As you can see, one benefit of using cross reference is that you don't need to specify the link text and DocFX will automatically resolve it for you.
Note
Title is extracted from the first heading of the Markdown file. Or you can also specify title using title metadata.
Define UID
The unique identifier of a file is called UID (stands for unique identifier) in DocFX. For Markdown file, you can specify its UID by adding a UID metadata in YAML header. For example, the following Markdown defined a UID "fileA".
---
uid: fileA
---
# This is fileA
...
Note
UID is supposed to be unique inside a project. If you define duplicate UID for two files, the resolve result is undetermined.
For API reference files, UID is auto generated by mangling API's signature. For example, System.String class's UID is System.String
. You can open the generated YAML files to lookup the value of UID.
Note
Conceptual Markdown file doesn't have UID generated by default. So it cannot be cross referenced unless you give it a UID.
Different syntax of cross reference
Besides the auto link, we also support some other ways to use cross references:
Markdown link
In Markdown link, you can also use xref
in link url:
[link_text](xref:uid_of_another_file)
This will resolve to:
<a href="path_of_another_file">link_text</a>
In this case, we won't resolve the link text for you because you already specified it, unless the link_text
is empty.
Shorthand form
You can also use @uid_to_another_file
to quickly reference another file. There are some rules for DocFX to determine whether a string following @
are UID:
- The string after
@
must start with[A-Za-z]
, and end with:
- Whitespace or line end
- Punctuation (
[.,;:!?`~]
) followed by whitespace or line end - Two or more punctuations (
[.,;:!?`~]
)
- A string enclosed by a pair of quotes (
'
or"
)
The render result of @
form is same as auto link form. For example, @System.String
is same as <xref:System.String>
.
Warning
Since @
is a common character in a document, DocFX doesn't show a warning if UID isn't found for a shorthand form xref link.
Warnings for missing links are shown for auto links and Markdown links.
Using hashtag in cross reference
Sometimes you need to link to the middle of a file (an anchor) rather than jump to the beginning of a file. DocFX also allows you to do that.
In Markdown link or auto link, you can add a hashtag (#
) followed by the anchor name after UID. For example:
<xref:uid_to_file#anchor_name>
[link_text](xref:uid_to_file#anchor_name]
@uid_to_file#anchor_name
Will all resolve to url_to_file#anchor_name
in output HTML.
The link text still resolves to the title of the whole file. If it's not what you need, you can specify your own link text.
Note
Hashtag in xref
is always treated as separator between file name and anchor name. That means if you have #
in UID, it has
to be encoded to %23
.
Actually xref
format follows URI standard so all reserved characters should be encoded.
Link to overwrite files
Overwrite file itself doesn't build into individual output file. It's merged with the API reference item model to build into a single file. If you want to link to the content inside an overwrite file (for example, an anchor), you cannot use the path to the overwrite file. Instead, you should either cross reference its UID, or link to the YAML file that contains the API.
For example, you have String class which is generated from system.string.yml
, then you have a string.md
that overwrites its conceptual part which contains a compare-strings
section. You can use one of the following syntax to link to this section:
[compare strings](xref:System.String#compare-strings)
[compare strings](system.string.yml#compare-strings)
Both will render to:
<a href="system.string.html#compare-strings">compare strings</a>
Cross reference between projects
Another common need is to reference topics from an external project. For example, when you're writing the documentation for your own .NET library, you'll want to add some links that point to types in .NET base class library. DocFX gives you this functionality by exporting all UIDs in a project into a map file and you can import it in another project to use them.
Cross reference map file
When building a DocFX project, there will be an xrefmap.yml
generated under output folder. This file contains information for all topics that have UID defined and their corresponding urls. The format of xrefmap.yml
looks like this:
references:
- uid: uid_of_topic
name: title_of_topic
href: url_of_topic.html
fullName: full_title_of_topic
- ...
It's a YAML object that contains following properties:
references
: a list of topic information, each item contains following properties:
uid
: UID to a conceptual topic or API referencename
: title of the topichref
: url to the topic, which is an absolute url or relative path to current file (xrefmap.yml
)fullName
: doesn't apply to conceptual, means the fully qualified name of API. For example, for String class, its name isString
and fully qualified name isSystem.String
. This property is not used in link title resolve for now but reserved for future use.
Tip
Topic is not necessarily to be a file, it can also be a section inside a file. For example, a method in a class. In this case its url could be an anchor in a file.
Using cross reference map
You can import a cross reference map file in your DocFX then all UIDs defined that file can be cross referenced.
To use a cross reference map, add a xref
config to build
section of docfx.json
:
{
"build": {
"xref": [
"<path_to_xrefmap>"
],
...
}
}
The value of xref
could be a string or a list of strings that contain the path/url to cross reference maps.
Note
DocFX supports reading cross reference map from a local file or a web location. It's recommended to deploy xrefmap.yml
to
the website together with topic files so that others can directly use its url in docfx.json
instead of downloading it to
local.
Then you can use any cross reference syntax in your Markdown file, DocFX will be able to resolve it to the right target url.
Cross reference .NET BCL types
When creating documentation for your own .NET library, it is needed to link to the types in .NET base class library. The .NET Framework reference documentation is not generated by DocFX, so we created a cross reference map for you so that you can use it in your project to reference .NET BCL types.
This can be downloaded on nuget.
Tip
You can also manually create xrefmap.yml
for project that is not generated by DocFX to be able to cross reference topics in
it.
Advanced: more options for cross reference
You can create a cross link with following options:
text
: the display text when the cross reference has been resolved correctly.e.g.:
@"System.String?text=string"
will be resolved as @"System.String?text=string".alt
: the display text when the cross reference does not have ahref
property.e.g.:
<xref href="System.Collections.Immutable.ImmutableArray`1?alt=ImmutableArray"/>
will be resolved as ImmutableArray.displayProperty
: the property of display text when the cross reference is has resolved correctly.e.g.:
<a href="xref:System.String?displayProperty=fullName"/>
will be resolved as .altProperty
: the property of display text when the cross reference does not have ahref
property.e.g.:
<xref href="System.Collections.Immutable.ImmutableArray`1" altProperty="name"/>
will be resolved as System.Collections.Immutable.ImmutableArray`1.title
: the title of link.e.g.:
[](xref:System.String?title=String+Class)
will be resolved as .