Creating Content

The "fsdocs" tool allows documentation for a site to be built from content in a docs directory. The expected structure for a docs directory is

docs/**/*.md                  -- markdown with embedded code, converted to html and optionally tex/ipynb
docs/**/*.fsx                 -- fsx scripts converted to html and optionally tex/ipynb
docs/**/*                     -- other content, copied over
docs/**/_template.html        -- optional template, specifies the HTML template for this directory and its contents
docs/**/_template.tex         -- optionally indicates Latex files should be generated
docs/**/_template.ipynb       -- optionally indicates F# ipynb files should be generated
docs/**/_template.fsx         -- optionally indicates F# fsx files should be generated (even from markdown)
docs/reference/_template.html -- optionally specifies the default template for reference docs

Processing is by these two commands:

dotnet fsdocs build
dotnet fsdocs watch

The output goes in output/ by default. Processing is recursive, making this a form of static site generation.

Literate Scripts and Markdown Content

The input directory may contain literate scripts and markdown content.

Other Content

Content that is not *.fsx or *.md is copied across.

Default Styling Content

By default additional content such as fsdocs-search.js, fsdocs-tips.js and fsdocs-styles.css are included in the the content directory of the output. This can be suppressed with --nodefaultcontent or by having your own copy of this content in your content directory.

Ignored Content

Any file or directory beginning with . is ignored.

Front matter

Each content file can have optional frontmatter. This determines the navigation bar title, categorization and ordering.

For markdown, the format is:

title: Some Title
category: Some Category
categoryindex: 2
index: 3

For F# scripts the frontmatter is in this form:

title: A Literate Script
category: Examples
categoryindex: 2
index: 1

All entries are optional. The categoryindex determines the ordering of categories. The index determines the ordering of within each category. The title is used in the navigation bar instead of any title inferred from the document.

Multi-language Content

Versions of content in other languages should go in two-letter coded sub-directories, e.g.


These will be elided from the main table-of-contents and search indexes. (Currently no language-specific table of contents is built, nor language-specific site search indexes).

Templates and Substitutions

Templates are used for HTML (_template.html), LaTeX (_template.tex), Notebooks (_template.ipynb) and F# script outputs (_template.fsx).

The following substitutions determine the primary (non-styling) content of your site. For example {{fsdocs-content}} is replaced with the generated content in each file.

Substitutions are applied when generating content from HTML templates, IPYNB templates, FSX templates. They are also applied to content apart from Markdown inline code `...`, Markdown LaTeX and generated outputs.

See Styling for information about template parameters and styling beyond the default template.

Substitution name

Generated content


<PackageProjectUrl> else / followed by fsdocs-collection-name


Name of .sln, single .fsproj or containing directory


Main page content


HTML <li> list of namespaces with links


HTML <li> list of documents with titles and links


First h1 heading in literate file. Generated for API docs


Original literate script or markdown source


Name of original input source, relative to the docs root


Name of original input source, excluding its extensions, relative to the docs root


Generated hidden div elements for tooltips


The websocket script used in watch mode to trigger hot reload

The following substitutions are extracted from your project files and may or may not be used by the default template:

Substitution name












For the fsdocs tool, additional substitutions can be specified using --parameters.

Cross References to API Docs

Markdown content can contain cross-references to API Docs. Use inline markdown code snippets of the special form `cref:T:MyNamespace.MyType` where T:MyNamespace.MyType is a method, property or type xml doc sig reference, see API Docs. This can include any cross-references resolved by fsdocs.

The generated API documentation includes buttons to copy the XML and Markdown forms of API doc references.

For example, within this project,

NOTE: These cases act as tests - if the links above do not work, then that indicates a bug or a change in the external link. Please report it.

Determining xmldoc sig references is not simple. The API doc generated pages come with buttons to copy out the XmlDoc signature.

Generating HTML Output

HTML is generated by default. You can also add a _template.html. This should contain {{fsdocs-content}}, {{fsdocs-tooltips}} and other placeholders. Substitutions are applied to this template. If a file _template.html exists then is used as the template for HTML generation for that directory and all sub-content.

Generating LaTeX output

To generate .tex output for each script and markdown file, add a _template.tex. Substitutions are applied to this template. The file is either empty of contains {{fsdocs-content}} as the key where the body of the document is placed.

Generating iPython Notebook output

To generate .ipynb output for each script and markdown file, add a _template.ipynb, usually empty. Substitutions are applied to this template.

To add a mybinder badge to your generated notebook, ensure you have a Dockerfile and NuGet.config in your docs directory and use text like this:


Generating Script outputs

To generate .fsx output for each script and markdown file, add a _template.fsx, usually empty. Substitutions are applied to this template. It is either empty of contains {{fsdocs-content}} as the key where the body of the script is placed.

union case Option.Some: Value: 'T -> Option<'T>