Skip to content

Latest commit

 

History

History

docs

fluidframework-docs

This is the code and content for https://fluidframework.com.

The site is generated using Hugo.

Website quick start

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.

API documentation and Playground

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.

Building the documentation

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

Building the documentation locally

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.

Drafts

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.

Previewing drafts locally

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

Future Content

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.

Previewing future content locally

To build content and preview future content locally, you can run the build with the --buildFuture flag.

npm run build -- --buildFuture

API documentation

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

Understanding the API documentation build pipeline

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:

  1. Root: build:fast
    1. Compile the code, generating TypeScript definitions, etc.
  2. Root: build:docs
    1. 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.
    2. The JSON is also copied from each package up to a shared _api-extractor-temp directory under the repository root.
  3. /docs: build
    1. Run markdown-magic to update some shared content in the source Markdown files (both in the docs directory and throughout the rest of the repo).
    2. Run api-documenter to transform JSON-formatted API reports generated by API-Extractor into Markdown-formatted documentation.
      • The generated Markdown is placed under /docs/content/apis.
    3. Run Hugo to build the site itself. The generated output is placed at /docs/public/apis.
  4. /docs: start
    1. Run the Hugo server to host the site at http://localhost:1313.

To investigate incorrect output, you can check the intermediate outputs (JSON, Markdown, HTML) at these locations to narrow down where the error is occurring.

Tools

The following are tools used by this package.

Markdown Magic

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.

API-Markdown-Documenter

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.

Creating new content

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

Content guidelines

Try to use Markdown as much as possible. You can embed HTML in Markdown, but we recommended sticking to Markdown and shortcodes/partials.

Menus

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

Main menu (top menu)

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

Docs menu

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

API menu

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.

Concepts

  • FluidFramework: The core uber package with sub-categories like Audience, Container, and DDSes. Each containing the APIs which should be exposed for that concept.
  • Service Clients: Packages connecting with FluidFramework (e.g., @fluidframework/azure-client).

Structure

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

Table of Contents

Some template pages include a table of contents (TOC) of the page. This is generated automatically by reading the headers.

Social action

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.

Writing Markdown content

Please refer to the following guidelines when writing new Markdown content for the website.

Remember that we prefer Markdown over HTML contents whenever possible, but you may embed HTML in your Markdown contents as needed.

Linking to other documents

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

Shortcodes are custom functions that can be called from within the Markdown or HTML to insert specific content.

Built-in shortcode templates

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.

relref

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 over ref, as ref 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.

relref example

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

Custom shortcode templates

We have a series of premade shortcode templates that we use throughout our website content. These can be found under layouts/shortcodes.

apiref

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:

  1. The shortcode is configured to understand our API documentation configuration, so it is better equipped to deal with file paths, etc.
  2. The generated link is formatted as a <code> block automatically.
  3. 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, and namespace/module items, as they are the only items for which individual .md files are generated for. Contents like parameters, methods, etc. are rendered as sub-headings in their parent item's documents.

This shortcode can be found in layouts/shortcodes/apiref.html.

apiref example

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

Working on the template

The site theme/template lives in themes/thxvscode.

Scripts

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