This is the code and content for https://fluidframework.com.
The site is generated using Hugo.
To quickly get started previewing the website's contents locally, open the docs folder in a terminal and install the dependencies using npm.
npm i -g pnpm
cd docs
pnpm installThen, start the server.
npm startOpen http://localhost:1313 to preview the site.
The steps above won't include API documentation (the TSDoc JSON files) by default.
To include generated API documentation in your local preview, you can run a complete build from the repo root.
Then run the build:api script from this directory.
npm run build:apiAlternatively, you can skip the complete repo build by downloading the latest API docs and Playground files with the download script.
npm run downloadNote that the
downloadscript will overwrite any locally built API docs.
To build the website and run other repo-wide documentation generation, run the build script.
The output will be in the public/ folder.
npm run buildTo strictly build the website (and omit documentation generation steps elsewhere in the repo), you can instead run the build:website script.
npm run build:websiteTo strictly run documentation generation for the remainder of the repo (everything not under /docs), you can instead run the build:repo-docs script.
npm run build:repo-docsTo build the website and run other repo-wide documentation generation, first run the build script in the root of the repo.
This will generate local api docs in the _api-extractor-temp directory.
npm run buildOnce the local api docs is generated, run the build:local script.
The output will be in the public/ folder.
npm run build:localNote that this calls the local-api-rollup script which simulates the download process in the regular build.
However, instead of downloading the api content, the _doc-models directory is populated by copying the models from _api-extractor-temp.
The local api content from _api-extractor-temp is copied to _doc-models/local.
Work-in-progress documents that are not ready for public consumption can be safely added by annotating them with the draft flag in their frontmatter.
Example:
---
title: "Foo"
draft: true
---Such documents will be disregarded by the build (by default) and will not be published.
Drafts are a good option for making incremental progress on a document via pull requests before being ready to actually publish for the world to see.
For more documentation on this Hugo feature, see here.
As noted above, the build script won't build draft content.
To build this content and preview it locally, you can run the build with the --buildDrafts flag.
npm run build -- --buildDraftsHugo also supports creating content to be published at some future, pre-defined date and time.
Note: we currently do not have a workflow for pre-publishing website content. These docs are here as a placeholder until we enable such functionality.
For more documentation on this Hugo feature, see here.
To build content and preview future content locally, you can run the build with the --buildFuture flag.
npm run build -- --buildFutureBuilding API documentation locally requires an extra step to generate the content from the source.
To build everything, you can use fluid-build from the repository root, and specify -s build:docs.
E.g.
fluid-build -t build -t build:docs --allIf you encounter problems updating or building the API docs, it can be helpful to have a high-level understanding of how it gets built. The steps are as follows:
- Root:
build:fast- Compile the code, generating TypeScript definitions, etc.
- Root:
build:docs- Run API-Extractor in each package to extract documentation info in a
JSONformat.- The output is placed in a folder
_api-extractor-tempin each package's directory.
- The output is placed in a folder
- The
JSONis also copied from each package up to a shared_api-extractor-tempdirectory under the repository root.
- Run API-Extractor in each package to extract documentation info in a
/docs:build- Run markdown-magic to update some shared content in the source
Markdownfiles (both in thedocsdirectory and throughout the rest of the repo). - Run api-documenter to transform
JSON-formatted API reports generated byAPI-ExtractorintoMarkdown-formatted documentation.- The generated
Markdownis placed under/docs/content/apis.
- The generated
- Run
Hugoto build the site itself. The generated output is placed at/docs/public/apis.
- Run markdown-magic to update some shared content in the source
/docs:start- Run the
Hugoserver to host the site at http://localhost:1313.
- Run the
To investigate incorrect output, you can check the intermediate outputs (JSON, Markdown, HTML) at these locations to narrow down where the error is occurring.
The following are tools used by this package.
We use a tool called markdown-magic to generate and embed contents in Markdown content throughout our repo.
This includes website contents, package READMEs, etc.
This tool is highly extensible, and new functionality can be added pretty simply by modifying ./md-magic.config.js.
We use an internal tool, @fluid-tools/api-markdown-documenter, to process API reports generated by API Extractor and generate Markdown-formatted API documentation.
The invocation script for this tool is ./api-markdown-documenter.js.
In order to create new documentation content, you will need to either generate new content manually by creating new files, or by generating them using the hugo command as shown below:
- Static
Markdowndocument:npm run hugo -- new docs/concepts/flux-capacitor.md - Blog post:
npm run hugo -- new posts/fluid-everywhere.md
Try to use Markdown as much as possible.
You can embed HTML in Markdown, but we recommended sticking to Markdown and shortcodes/partials.
Menus are mainly managed in config.yml but depending on the menu, the sub headers might be driven by the content in the repo (pages or data files).
The top menu is configured in the config.yml file and can look like this:
menu:
main:
- name: "Docs"
url: "/docs/"
weight: -90
- name: "API"
url: "/apis/"
weight: -80
- name: "Blog"
url: "/posts/"
weight: -50The docs menu is implemented in the theme's _partial/docNav.html and is using the config.yml to find the headers and then uses the area attribute of each sub section (sub folders in the content folder) to populate the pages displayed in the menu.
Here is an example of what config.yml could contain:
menu:
docs:
- identifier: "get-started"
name: "Get Started"
weight: -500
- identifier: "concepts"
name: "Main concepts"
weight: -300
- identifier: "faq"
name: "FAQ"
url: "/docs/faq/"
weight: -100Those are headers for the Docs menu, they each have a name field which is used to display the header in the menu.
They also have an identifier key which is used to map content with matching area field (often set to cascade within a sub folder).
Finally, you have a weight field that is used to decide the positioning of each item in the menu.
The lighter an item is, the higher it goes in order (closer to the top).
FluidFramework.com's Logical Hierarchy is defined in packages.json within the data folder. It's structured around two main concepts; FluidFramework and Service Clients.
- FluidFramework: The core uber package with sub-categories like
Audience,Container, andDDSes. Each containing the APIs which should be exposed for that concept. - Service Clients: Packages connecting with FluidFramework (e.g.,
@fluidframework/azure-client).
- FluidFramework: FluidFramework is split up into groupings which is then divided into the sub-categories; Classes, Enums, Interfaces and Types. The sub-categories contain the APIs that should be exposed in the Logical Hierarchy.
- Service Clients: Lists integration packages for the framework.
Some template pages include a table of contents (TOC) of the page. This is generated automatically by reading the headers.
There is a menu with actions such as tweeting the page, subscribing to the feed, asking questions etc... This is driven from the theme and the information for the accounts should be in the config.
Please refer to the following guidelines when writing new Markdown content for the website.
Remember that we prefer
MarkdownoverHTMLcontents whenever possible, but you may embedHTMLin yourMarkdowncontents as needed.
Standard Markdown links are supported in our Hugo ecosystem.
When linking to external webpages, this is the syntax we recommend.
When linking to other documents on the website, however, we recommend either using the built-in relref shortcode, or one of our custom shortcode templates.
These are designed to reduce boilerplate and be more tolerant to future changes to the website.
Shortcodes are custom functions that can be called from within the Markdown or HTML to insert specific content.
Hugo comes with a large suite of built-in shortcode templates that can be used when writing documentation.
The complete list can be found here.
We will call out a few here in more detail because we recommend using them, and expect them to be used frequently.
The relref shortcode is useful for linking to other pages on the website.
It accepts a file-name / partial file-path (and optional heading ID), and generates a relative path link to that document.
Note: we recommend using
relrefoverref, asrefwill generate an absolute url link, and won't work nicely when previewing the site locally.
Using relref is a great option when adding links between documents on the website, as it is more tolerant of file-wise changes made over time.
Markdown like the following:
https://fluidframework.com/docs/build/containers/
For more details, see [Creating a container]({{< relref "containers.md#creating-a-container" >}}).will generate something like:
For more details, see <a href="/docs/build/containers/#creating-a-container">Creating a container</a>.We have a series of premade shortcode templates that we use throughout our website content.
These can be found under layouts/shortcodes.
When linking to the API docs for a class, interface, etc., we recommend using our apiref shortcode, rather than writing a manual link.
This has a few of benefits:
- The shortcode is configured to understand our API documentation configuration, so it is better equipped to deal with file paths, etc.
- The generated link is formatted as a
<code>block automatically. - It reduces boilerplate.
The shortcode accepts a single argument: the name of the API item being referenced.
Note that this will only work correctly for
package,class,interface, andnamespace/moduleitems, as they are the only items for which individual.mdfiles are generated for. Contents likeparameters,methods, etc. are rendered as sub-headings in their parent item's documents.
This shortcode can be found in layouts/shortcodes/apiref.html.
Markdown like the following:
The {{< apiref "fluid-static" "FluidContainer" "class" >}} class can be used to...will generate something like:
The <a href="{{ relref /docs/apis/fluid-static/ifluidcontainer-interface.md }}"><code>FluidContainer</code></a> class can be used to...The site theme/template lives in themes/thxvscode.
The following npm scripts are supported in this directory:
| Script | Description |
|---|---|
build |
Build the site; outputs to public/ by default. |
build:api |
npm run build:api-documentation |
build:api-documentation |
Convert package API reports (.api.json files) into Markdown. |
build:local |
concurrently npm:build:local:api npm:build:md-magic && npm run hugo |
build:local:api |
npm run download:api && npm run build:local:rollup && npm run build:local:api-documentation && npm run build:redirects |
build:local:api-documentation |
node ./api-markdown-documenter/index.js true |
build:local:rollup |
node ./local-api-rollup.js |
build:md-magic |
Updates generated content in Markdown files. |
build:md-magic:code |
node markdown-magic-code.js |
build:redirects |
Copies the versions file from Hugo's data directory, so the redirection azure function has access to it. |
build:repo-docs |
npm run build:md-magic:code |
ci:build |
npm run download && npm run build |
ci:linkcheck |
start-server-and-test ci:start http://localhost:1313 linkcheck:full |
ci:start |
http-server ./public --port 1313 --silent |
clean |
Remove all generated files. |
download:api |
Download the latest API JSON files from main locally. |
format |
npm run prettier:fix |
hugo |
Run the local copy of Hugo. |
linkcheck |
Starts a local webserver and runs linkcheck:full against it. |
linkcheck:fast |
Checks all internal site links and reports the results to the terminal. |
linkcheck:full |
Checks all internal and external site links and reports the results to the terminal. |
lint |
npm run markdownlint && npm run prettier |
lint:fix |
npm run markdownlint:fix && npm run prettier:fix |
markdownlint |
markdownlint-cli2 |
markdownlint:fix |
markdownlint-cli2-fix |
prettier |
prettier --check . --ignore-path ../.prettierignore |
prettier:fix |
prettier --write . --ignore-path ../.prettierignore |
start |
Start a local webserver to preview the built site on http://localhost:1313 |