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 install
Then, start the server.
npm start
Open 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:api
Alternatively, you can skip the complete repo build by downloading the latest API docs and Playground files with the download
script.
npm run download
Note that the
download
script 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 build
To strictly build the website (and omit documentation generation steps elsewhere in the repo), you can instead run the build:website
script.
npm run build:website
To 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-docs
To 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 build
Once the local api docs is generated, run the build:local
script.
The output will be in the public/
folder.
npm run build:local
Note 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 -- --buildDrafts
Hugo 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 -- --buildFuture
Building 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 --all
If 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
JSON
format.- The output is placed in a folder
_api-extractor-temp
in each package's directory.
- The output is placed in a folder
- The
JSON
is also copied from each package up to a shared_api-extractor-temp
directory 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
Markdown
files (both in thedocs
directory and throughout the rest of the repo). - Run api-documenter to transform
JSON
-formatted API reports generated byAPI-Extractor
intoMarkdown
-formatted documentation.- The generated
Markdown
is placed under/docs/content/apis
.
- The generated
- Run
Hugo
to 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
Hugo
server 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
Markdown
document: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: -50
The 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: -100
Those 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
Markdown
overHTML
contents whenever possible, but you may embedHTML
in yourMarkdown
contents 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
relref
overref
, asref
will 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
/module
items, as they are the only items for which individual.md
files 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 |
Build the site, including repo-local API documentation. Outputs to public/ by default. |
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: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 |
start-with-azure-emulation |
swa start public --api-location api |