# Contributing docs and examples
> This bundle contains all pages in the Contributing docs and examples section.
> Source: https://www.union.ai/docs/latest/flyte/community/contributing-docs/

=== PAGE: https://www.union.ai/docs/latest/flyte/community/contributing-docs ===

# Contributing docs and examples

> **📝 Note**
>
> An LLM-optimized bundle of this entire section is available at [`section.md`](section.md).
> This single file contains all pages in this section, optimized for AI coding agent context.

We welcome contributions to the docs and examples for both Flyte and Union.
This section explains how the docs site works and walks you through setting it up, authoring content, and submitting your changes.

## Where to start

* **Contributing docs and examples > Set up a local docs dev environment**: clone the repository, initialize the submodules, and run the live preview.
* **Contributing docs and examples > Authoring**: write pages with Markdown, shortcodes, and variants.
* **Contributing docs and examples > Writing guidelines**: the editorial conventions the site follows.
* **Contributing docs and examples > Submit a contribution**: open a pull request and get it merged.

The rest of this section is reference material: **Contributing docs and examples > Variants**, **Contributing docs and examples > Versions**, **Contributing docs and examples > Shortcodes**, **Contributing docs and examples > API docs**, **Contributing docs and examples > LLM-optimized documentation**, **Contributing docs and examples > Redirects**, and **Contributing docs and examples > Production builds and troubleshooting**.

## How the docs site works

As the primary maintainer and contributor of the open-source Flyte project, Union.ai hosts the Flyte documentation.
Union.ai is also the company behind the commercial Union.ai product, which is built on Flyte.

Because Flyte and Union.ai share much of their functionality, most of the documentation content is common between them.
There are, however, significant differences between Flyte and Union.ai and among the Union.ai deployment options (BYOC and Self-managed).

To maintain the documentation for all of these variants efficiently, we use a single-source-of-truth approach:

* All content is stored in a single GitHub repository, [`unionai/unionai-docs`](https://github.com/unionai/unionai-docs).
* All content is published on a single website, [`www.union.ai/docs`](/docs/v2/root/).
* A variant selector at the top of each page lets you choose which variant to view: Flyte OSS or Union.ai (which covers both BYOC and Self-managed deployments).
* A version selector lets you choose between v1 (Flyte/Union 1.x) and v2 (Flyte/Union 2.0, which you are viewing now).

### Versions

The two versions of the docs are stored in separate branches of the repository:

* The [`v1` branch](https://github.com/unionai/unionai-docs/tree/v1) holds the v1 docs.
* The [`main` branch](https://github.com/unionai/unionai-docs) holds the v2 docs.

See **Contributing docs and examples > Versions** for details.

### Common build infrastructure

The build infrastructure (Hugo configuration, layouts, themes, build scripts, and Python tools) lives in a separate repository, [`unionai/unionai-docs-infra`](https://github.com/unionai/unionai-docs-infra), imported as a [Git submodule](https://git-scm.com/book/en/v2/Git-Tools-Submodules) at `unionai-docs-infra/`.

Both the `main` (v2) and `v1` content branches share this infrastructure.
Changes to the build system are made once in `unionai-docs-infra` and picked up by both branches, keeping them in sync without duplicating build logic.

### Variants

Within each branch, the variants are supported by conditional rendering:

* Each page declares which variants it applies to in its `variants` frontmatter field.
* Within a page, rendering logic includes or excludes content based on the selected variant.

The result is that content common to all variants is authored once, while variant-specific content is rendered conditionally.
See **Contributing docs and examples > Variants** for details.

### Both Flyte and Union docs are open source

Because the docs are combined in one repository and the Flyte docs are open source, the Union docs are open source too.
Everyone can contribute: Flyte contributors, Union customers, and Union employees.

If you are a Flyte contributor, you contribute docs related to Flyte features, and in many cases those features are also available in Union.
Because the docs site is a single source for all the documentation, when you make a change related to Flyte that is also valid for Union, you do it in the same place.
This is by design and is a key feature of the docs site.

=== PAGE: https://www.union.ai/docs/latest/flyte/community/contributing-docs/quick-start ===

# Set up a local docs dev environment

Follow these steps to build and preview the docs site on your own machine.
Once it is running, you can edit content and see your changes live.

## Prerequisites

The site is built with the [Hugo](https://gohugo.io/) static site generator.
Install Hugo version 0.145.0 or later:

```bash
brew install hugo
```

For other platforms, see [Hugo installation](https://gohugo.io/getting-started/installing/).
You also need `git` and `make`.

## Clone the repository

Clone [`unionai/unionai-docs`](https://github.com/unionai/unionai-docs) to your machine:

```bash
git clone https://github.com/unionai/unionai-docs.git
cd unionai-docs
```

Content lives in the `content/` folder as Markdown files.
The hierarchy of files and folders under `content/` maps directly to the URL and navigation structure of the site.

## Initialize the submodules

The docs repository uses two Git submodules that you must initialize before the first build:

* `unionai-docs-infra/` holds the shared build infrastructure (Hugo configuration, layouts, themes, and build tools).
* `unionai-examples/` holds the runnable example code that pages embed.

Initialize the build infrastructure:

```bash
make init-infra
```

Then initialize the examples:

```bash
make init-examples
```

To update the examples submodule to its latest `main` later, run `make update-examples`.

## Configure the live preview

Copy the sample local configuration file at the root of the repository to `hugo.local.toml`:

```bash
cp hugo.local.toml~sample hugo.local.toml
```

This file controls the development preview and is not committed.
By default it displays the `flyte` variant with the `show_inactive`, `highlight_active`, and `highlight_keys` flags enabled.

## Start the live preview

Start the development server:

```bash
make dev
```

This builds the site and launches a local server at `http://localhost:1313`.
Open that URL in your browser and leave the server running.
As you edit content, the preview reloads automatically to reflect your changes.

## Development settings

Adjust the preview by editing `hugo.local.toml`. Save the file and the browser refreshes automatically.

| Setting | Effect |
| --- | --- |
| `variant` | The variant to display (`flyte` or `union`). This is the "active" variant. |
| `show_inactive` | If `true`, also shows content that does not match the active variant, so you can see every variant at once. |
| `highlight_active` | If `true`, highlights the active variant's content to distinguish it from content common to all variants. |
| `highlight_keys` | If `true`, highlights [key](./shortcodes#key) replacements and their values. |

For more on variants, see [Variants](./variants).

## Build the production site

To build the site the way the production pipeline does, run:

```bash
make dist
```

This builds every variant and writes the result to the `dist/` folder.
To build and validate a single variant, run `make variant VARIANT=union` (or `VARIANT=flyte`).

Serve the production build locally to check it:

```bash
make serve
```

This serves the `dist/` folder at `http://localhost:9000`.
To use a different port, pass `PORT`:

```bash
make serve PORT=4444
```

For production build details and troubleshooting, see [Production builds and troubleshooting](./publishing).

## Next steps

* [Author content](./authoring) with Markdown, shortcodes, and variants.
* Follow the [writing guidelines](./writing-guidelines) so your docs match the rest of the site.
* [Submit your contribution](./submitting-contributions) as a pull request.

=== PAGE: https://www.union.ai/docs/latest/flyte/community/contributing-docs/authoring ===

# Authoring

This page covers how to write and structure docs pages: creating files, controlling page visibility, linking, notices, and generating content from Python or Jupyter.
Before you start, [set up a local docs dev environment](./quick-start) so you can preview your changes.
For the editorial conventions to follow, see the [writing guidelines](./writing-guidelines); when you are ready to open a pull request, see [Submit a contribution](./submitting-contributions).

## Getting started

Content is located in the `content` folder.

To create a new page, create a new Markdown file in the appropriate folder and start writing.

## Live preview

While editing, use Hugo's live preview: run `make dev` and open `http://localhost:1313`.
The preview updates automatically as you edit.
See [Set up a local docs dev environment](./quick-start) for the full setup.

## Page visibility

This site uses variants, which means different "flavors" of the content.
For a given page, its variant visibility is governed by the `variants:` field in the front matter of the page source.
For each variant you specify `+<variant>` to include or `-<variant>` to exclude it.
For example:

```markdown
---
title: My Page
variants: -flyte +union
---
```

In this example the page will be:

* Included in Serverless and BYOC.
* Excluded from Flyte and Self-managed.

> [!NOTE]
> All variants must be explicitly listed in the `variants` field.
> This helps avoid missing or extraneous pages.

## Page order

Pages are ordered by the value of `weight` field (an integer >= 0) in the frontmatter of the page,

1. The higher the weight the lower the page sits in navigation ordering among its peers in the same folder.
2. Pages with no weight field (or `weight = 0`) will be ordered last.
3. Pages of the same weight will be sorted alphabetically by their title.
4. Folders are ordered among their peers (other folders and pages at the same level of the hierarchy) by the weight of their `_index.md` page.

For example:

```markdown
---
title: My Page
weight: 3
---
```

## Page settings

| Setting            | Type | Description                                                                       |
| ------------------ | ---- | --------------------------------------------------------------------------------- |
| `top_menu`         | bool | If `true` the item becomes a tab at the top and its hierarchy goes to the sidebar |
| `sidebar_expanded` | bool | If `true`, force this section to render expanded in the sidebar even when it is not on the active path. Use sparingly. By default, sections collapse and only the active path expands automatically. |
| `site_root`        | bool | If `true` indicates that the page is the site landing page                        |
| `toc_max`          | int  | Maximum heading to incorporate in the right navigation table of contents.         |
| `llm_readable_bundle` | bool | If `true`, generates a `section.md` bundle for this section. Requires `{{</* llm-bundle-note */>}}` shortcode. See [LLM-optimized documentation](./llm-docs). |

## Conditional content

The site has "flavors" of the documentation. We use the `{{</* variant */>}}` tag to control
which content is rendered on which flavor.

Refer to [**Variants**](./shortcodes#variants) for detailed explanation.

## Linking to the API reference

API identifiers and methods that you mention in prose or in Python code blocks are linked to the API reference automatically. You don't need to write explicit Markdown links for them.

```markdown
✅  A `flyte.io.File` is a reference to an offloaded file.
✅  A `Trigger` defines when an environment's tasks should run.
✅  Call `flyte.init()` before submitting a run.

❌  A [`flyte.io.File`](https://www.union.ai/docs/latest/flyte/api-reference/flyte-sdk/flyte.io/file) …
❌  Call [`flyte.init()`](https://www.union.ai/docs/latest/flyte/community/api-reference/flyte-sdk/flyte/_index) …
```

What gets linked:

- **Class names** in inline code, in either fully-qualified or short form: `` `flyte.io.File` ``, `` `File` ``, `` `flyte.Trigger` ``, `` `Trigger` ``.
- **Method names** in inline code, only when fully qualified: `` `flyte.init()` ``, `` `flyte.report.log()` ``. Bare `` `init` ``, `` `log` ``, `` `run` `` are not linked: those names are too generic.
- **Python identifiers in fenced code blocks** when they resolve through one of the block's `import` statements.

Trailing `()` and a leading `@` are stripped before lookup, so `` `flyte.init()` ``, `` `flyte.init` ``, and `` `@flyte.trace` `` all match.

### Sigils for special cases

Three sigils let you override the default behavior. Each must be the entire content of the backticks.

| Sigil | Meaning | Example |
|---|---|---|
| `` `[[X]]` `` | Force-link by last-segment lookup; render as `X`. Useful for short forms not in the linkmap (e.g. method short names). | `` `[[get_tab]]` `` → links to `flyte.report.get_tab` |
| `` `[[X\|Y]]` `` | Link to `X`, render as `Y`. Useful to disambiguate the target while rendering a shorter or different label. | `` `[[flyte.remote.Trigger\|Trigger]]` `` |
| `` `{{X}}` `` | Opt-out: render `X` with no link, even if `X` is in the linkmap. Use when the backticked text refers to something other than the Flyte identifier (a variable name, a different library, etc.). | `` `{{File}}` `` |

When in doubt, write the bare backticked identifier and let the linker handle it. Reach for sigils only when the default does the wrong thing.

## Warnings and notices

You can write regular Markdown and use the notation below to create information and warning boxes:

```markdown
> [!NOTE] This is the note title
> You write the note content here. It can be
> anything you want.
```

Or if you want a warning:

```markdown
> [!WARNING] This is the title of the warning
> And here you write what you want to warn about.
```

## Special content generation

There are various short codes to generate content or special components (tabs, dropdowns, etc.)

Refer to [**Content Generation**](./shortcodes) for more information.

## Python generated content

You can generate pages from markdown-commented Python files.

At the top of your `.md` file, add:

```markdown
---
layout: py_example
example_file: /path/to/your/file.py
run_command: union run --remote tutorials//path/to/your/file.py main
source_location: https://www.github.com/unionai/unionai-examples/tree/main/tutorials/path/to/your/file.py
---
```

Where the referenced file looks like this:

```python
# # Credit Default Prediction with XGBoost & NVIDIA RAPIDS
#
# In this tutorial, we will use NVIDIA RAPIDS `cudf` DataFrame library for preprocessing
# data and XGBoost, an optimized gradient boosting library, for credit default prediction.
# We'll learn how to declare NVIDIA  `A100` for our training function and `ImageSpec`
# for specifying our python dependencies.
# {{run-on-union}}
# ## Declaring workflow dependencies
#
# First, we start by importing all the dependencies that is required by this workflow:
import os
import gc
from pathlib import Path
from typing import Tuple
import fsspec
from flytekit import task, workflow, current_context, Resources, ImageSpec, Deck
from flytekit.types.file import FlyteFile
from flytekit.extras.accelerators import A100
```

Note that the text content is embedded in comments as Markdown, and the code is normal python code.

The generator will convert the markdown into normal page text content and the code into code blocks within that Markdown content.

### Run on Union instructions

We can add the run on Union instructions anywhere in the content.
Annotate the location you want to include it with `{{run-on-union}}`. Like this:

```markdown
# The quick brown fox wants to see the Union instructions.
#
# {{run-on-union}}
#
# And it shall have it.
```

The resulting **Run on Union** section in the rendered docs will include the run command and source location,
specified as `run_command` and `source_location` in the front matter of the corresponding `.md` page.

## Jupyter notebooks

You can also generate pages from Jupyter notebooks.

At the top of your.md file, add:

    ---
    jupyter_notebook: /path/to/your/notebook.ipynb
    ---

Jupyter notebook conversion is handled automatically as part of the production build:

```bash
make dist
```

The conversion tool is located at `unionai-docs-infra/tools/jupyter_generator`.

**Committing the change:** When the PR is pushed, a CI check verifies consistency between the notebook and its generated content. Please ensure that if you change the notebook, you run `make dist` to update the generated page.

## Mapped keys (`{{</* key */>}}`)

Key is a very special command that allows us to define mapped values to a variant.
For example, the product name changes if it is Flyte, Union BYOC, etc. For that,
we can define a single key `product_full_name` and map it to reflect automatically,
without the need to `if variant` around it.

Please refer to [{{</* key */>}} shortcode](./shortcodes#key) for more details.

## Mermaid graphs

To embed Mermaid diagrams in a page, insert the code inside a block like this:

    ```mermaid
    your mermaid graph goes here
    ```

Also add `mermaid: true` to the top of your page to enable rendering.

> [!NOTE]
> You can use [Mermaid's playground](https://www.mermaidchart.com/play) to design diagrams and get the code

=== PAGE: https://www.union.ai/docs/latest/flyte/community/contributing-docs/submitting-contributions ===

# Submit a contribution

This page walks through submitting a docs change as a pull request, from forking the repository to getting your change merged.
Both Flyte community members and Union customers are welcome to contribute.

Before you start, [set up a local docs dev environment](./quick-start) so you can preview your changes.

## Target the right branch

The docs repository keeps each version of the site on its own long-lived branch:

* **For Flyte or Union 2.x**, branch off `main` and open your pull request against `main`.
* **For Flyte or Union 1.x**, branch off `v1` and open your pull request against `v1`.

Most contributions target `main` (v2). See [Versions](./versions) for how versions map to branches.

## Fork and clone

If you have write access to the repository, you can branch directly. Otherwise, fork it first:

1. Fork [`unionai/unionai-docs`](https://github.com/unionai/unionai-docs) to your own GitHub account.
2. Clone your fork and initialize the submodules as described in [Set up a local docs dev environment](./quick-start):

   ```bash
   git clone https://github.com/<your-username>/unionai-docs.git
   cd unionai-docs
   make init-infra
   make init-examples
   ```

## Create a feature branch

Create a branch off the branch you are targeting (usually `main`):

```bash
git checkout main
git pull
git checkout -b my-docs-change
```

Give the branch a short, descriptive name.

## Make and preview your changes

Edit the Markdown files under `content/` and preview them locally with the live server:

```bash
make dev
```

See [Author content](./authoring) for how to write pages, and the [writing guidelines](./writing-guidelines) for the editorial conventions the site follows.

## Commit with a sign-off

Sign off each commit with the `-s` flag. This adds a `Signed-off-by` line that records that you agree your contribution can be included in the project:

```bash
git add content/...
git commit -s -m "Describe your change"
```

If you have several commits, sign off each of them.

## Open a pull request

Push your branch and open a pull request against the correct base branch (usually `main`):

```bash
git push -u origin my-docs-change
```

Then open the pull request on GitHub. In the description, explain what you changed and why.
If your change targets v1, make sure the base branch is `v1`.

## Check the preview build

Every pull request produces a preview build of the site on Cloudflare.
Look for the preview link in the pull request checks and open it to confirm your changes render as you expect, in the affected variants.

## Review and merge

A maintainer reviews your pull request.
Continuous integration checks run automatically (for example, link and image validation).
Address any review feedback or failing checks by pushing more commits to the same branch.
Once the pull request is approved and all checks pass, a maintainer merges it, and your change goes live on the next production deploy.

=== PAGE: https://www.union.ai/docs/latest/flyte/community/contributing-docs/writing-guidelines ===

# Writing guidelines

These guidelines describe the editorial conventions the docs follow.
Following them keeps your contribution consistent with the rest of the site.
They cover *how to write* the content; for the mechanics of authoring pages (frontmatter, shortcodes, variants), see [Author content](./authoring).

## Lead with the task

Start a page or section with what the reader needs to do, not with background.
State the goal, then show the shortest example that achieves it, then explain the details.
Move context, caveats, and edge cases below the first working example.

## Write in a clear, active voice

* Use the active voice ("Call `flyte.init()` before submitting a run"), not the passive ("`flyte.init()` should be called").
* Address the reader as "you".
* Keep sentences short and concrete. Prefer plain verbs (`use`, not `leverage` or `utilize`).
* Cut filler. Phrases like "it is worth noting that", "in order to", and "a wide range of" add words without adding meaning.

## Structure a page

A typical page follows this shape:

1. A brief description of what the feature does.
2. A minimal, runnable example early on.
3. The parameters and options, explained after the example.
4. Common use cases and gotchas at the end.

Use headings to break up the page, and keep each section focused on one idea.

## Use sentence case for headings

Write headings and titles in sentence case: capitalize only the first word and any proper nouns.

* Write "Set up a local dev environment", not "Set Up A Local Dev Environment".
* Keep product names and acronyms capitalized as they normally appear: Flyte, Union.ai, Kubernetes, API, SDK, CLI.

## Use notes and warnings deliberately

Use a note for helpful, non-critical information and a warning for something that can cause data loss, breakage, or a security problem. Do not overuse them; if every paragraph is a callout, none of them stand out.

```markdown
> [!NOTE] Optional title
> Helpful, non-critical information.

> [!WARNING] Optional title
> Something the reader must not miss.
```

See [Authoring > Warnings and notices](./authoring#warnings-and-notices) for the syntax.

## Keep terminology consistent

Use the same term for the same thing throughout. Match the spelling and casing the rest of the docs use:

* **Union.ai** for the company and product (not "Union AI" or "UnionAI").
* **Flyte** for the open-source project (lowercase `flyte` only for the package, CLI, or module name, in code).
* **Kubernetes**, not "k8s", in prose.

When you write about a Flyte 2 concept as an ordinary noun ("create a task", "the workflow"), use lowercase.
Capitalize the name only when you mean the literal API class, and then write it in backticks so it links to the API reference: `` `Task` ``, `` `TaskEnvironment` ``, `` `File` ``.

## Make examples runnable and tested

Code examples should run as written. Prefer examples that a reader can copy, paste, and execute.
Longer, runnable examples belong in the [`unionai/unionai-examples`](https://github.com/unionai/unionai-examples) repository and are embedded into pages; see [Author content](./authoring#python-generated-content) for how that works.

## Link to the API reference by writing the identifier

When you mention an API identifier in prose or a code block, write it in backticks and let the site link it automatically. Do not write an explicit Markdown link to the API reference.

```markdown
✅  A `flyte.io.File` is a reference to an offloaded file.
✅  Call `flyte.init()` before submitting a run.
```

See [Authoring > Linking to the API reference](./authoring#linking-to-the-api-reference) for the details.

=== PAGE: https://www.union.ai/docs/latest/flyte/community/contributing-docs/variants ===

# Variants

The docs site supports the ability to show or hide content based of the current variant selection.
There are separate mechanisms for:

* Including or excluding entire pages based on the selected variant.
* Conditional rendering of content within a page based on the selected variant using an if-then-like construct.
* Rendering keywords as variables that change based on the selected variant.

Currently, the docs site supports two variants:

- **Flyte OSS**: The open-source Flyte project.
- **Union**: The Union.ai commercial product, available as BYOC (Bring Your Own Cloud) or Self-managed.

Each variant is referenced in the page logic using its respective code name: `flyte` or `union`.

> [!NOTE]
> The previous code names `byoc`, `selfmanaged`, and `serverless` are no longer valid. They all map to the current `union` variant. Union.ai now ships as a single docs variant covering BYOC and Self-managed deployments. The `flyte` variant covers open-source Flyte. If you encounter any of the retired names in older content, frontmatter, or shortcodes, replace `byoc`, `selfmanaged`, or `serverless` with `union`.

The available set of variants are defined in the `config.<code_name>.toml` files in the `unionai-docs-infra/` directory.

## Variants at the whole-page level

The docs site supports the ability to show or hide entire pages based of the selected variant.
Not all pages are available in all variants because features differ across the variants.

In the public website, if you are on page in one variant, and you change to a different variant, the page will change to the same page in the new variant *if it exists*.
If it does not exist, you will see a message indicating that the page is not available in the selected variant.

In the source Markdown, the presence or absence of a page in a given variant is governed by  `variants` field in the front matter parameter of the page.
For example, if you look at the Markdown source for [this page (the page you are currently viewing)](https://github.com/unionai/unionai-docs/blob/main/content/community/contributing-docs/variants.md), you will see the following front matter:

```markdown
---
title: Variants
weight: 5
variants: +flyte +union
---
```

The `variants` field has the value:

`+flyte +union`

The `+` indicates that the page is available for the specified variant.
In this case, the page is available for both variants.
If you wanted to make the page available for only the `flyte` variant, you would change the `variants` field to:

`+flyte -union`

In [live preview mode](./authoring#live-preview) with the `show_inactive` flag enabled, you will see all pages in the navigation tree, with the ones unavailable for the current variant grayed out.

As you can see, the `variants` field expects a space-separated list of keywords:

* The code names for the current variants are `flyte` and `union`.
* All supported variants must be included explicitly in every `variants` field with a leading `+` or `-`. There is no default behavior.
* The supported variants are configured in the `unionai-docs-infra/` directory in the files named `config.<variant>.toml`.

## Conditional rendering within a page

Content can also differ *within a page* based on the selected variant.
This is done with conditional rendering using the `{{</* variant */>}}` and `{{</* key */>}}` [Hugo shortcodes](https://gohugo.io/content-management/shortcodes/).

<!-- markdownlint-disable-next-line MD037 -- Hugo escaped-shortcode syntax, not emphasis -->
### {{</* variant */>}}

The syntax for the `{{</* variant */>}}` shortcode is:

```markdown
{{</* variant <variant_codes> */>}}
...
{{</* /variant */>}}
```

Where `<variant_codes>` is a list the code name for the variants you want to show the content for.

Note that the variant construct can only directly contain other shortcode constructs, not plain Markdown.
In the most common case, you will want to use the `{{</* markdown */>}}` shortcode  (which can contain Markdown) inside the `{{</* variant */>}}` shortcode to render Markdown content, like this:

```markdown
{{</* variant union */>}}
{{</* markdown */>}}
This content is only visible in the `union` variant.
{{</* /markdown */>}}
{{</* button-link text="Contact Us" target="https://union.ai/contact" */>}}
{{</* /variant */>}}
```

For more details on the `{{</* variant */>}}` shortcode, see the [Shortcodes > `variant`](./shortcodes#variant).

<!-- markdownlint-disable-next-line MD037 -- Hugo escaped-shortcode syntax, not emphasis -->
### {{</* key */>}}

The syntax for the `{{</* key */>}}` shortcode is:

```markdown
{{</* key <key_name> */>}}
```

Where `<key_name>` is the name of the key you want to render.
For example, if you want to render the product name keyword, you would use:

```markdown
{{</* key product_name */>}}
```

The available key names are defined in the [params.key] section of the `hugo.site.toml` configuration file in the root of the repository.

For example the `product_name` used above is defined in that file as

```toml
[params.key.product_name]
flyte = "Flyte"
union = "Union.ai"
```

Meaning that in any content that appears in the `flyte` variant of the site `{{</* key product_name */>}}` shortcode will be replaced with `Flyte`, and in any content that appears in the `union` variant, it will be replaced with `Union.ai`.

For more details on the `{{</* key */>}}` shortcode, see the [Shortcodes > `key`](./shortcodes#key)

## Full example

Here is full example. If you look at the Markdown source for [this page (the page you are currently viewing)](https://github.com/unionai/unionai-docs/blob/main/content/community/contributing-docs/variants.md), you will see the following section:

```markdown
> **This text is visible in all variants.**
>
> {{</* variant flyte */>}}
> {{</* markdown */>}}
>
> **This text is only visible in the `flyte` variant.**
>
> {{</* /markdown */>}}
> {{</* /variant */>}}
> {{</* variant union */>}}
> {{</* markdown */>}}
>
> **This text is only visible in the `union` variant.**
>
> {{</* /markdown */>}}
> {{</* /variant */>}}
>
> **Below is a `{{</* key product_full_name */>}}` shortcode.
> It will be replaced with the current variant's full name:**
>
> **{{</* key product_full_name */>}}**
```

This Markdown source is rendered as:

> **This text is visible in all variants.**
>
> > 
>
> **This text is only visible in the `flyte` variant.**
>
> 
>
> 
>
> **Below is a `{{</* key product_full_name */>}}` shortcode.
> It will be replaced with the current variant's full name:**
>
> **Flyte OSS**

If you switch between variants with the variant selector at the top of the page, you will see the content change accordingly.

## Adding a new variant

A variant is a term we use to identify a product or major section of the site.
Such variant has a dedicated token that identifies it, and all resources are
tagged to be either included or excluded when the variant is built.

> Adding new variants is a rare event and must be reserved when new products
> or major developments.
>
> If you are thinking adding a new variant is the way
> to go, please double-check with the infra admin to confirm before doing all
> the work below and waste your time.

### Location

When deploying, the variant takes a folder in the root

`https://<your-site-domain>/<variant>/<content>`

For example, if we have a variant `acme`, then when built the content goes to:

`https://<your-site-domain>/acme/<content>`

### Creating a new variant

To create a new variant a few steps are required:

| File                                      | Changes                                                        |
| ----------------------------------------- | -------------------------------------------------------------- |
| `hugo.site.toml`                          | Add to `params.variant_weights` and all `params.key`           |
| `unionai-docs-infra/hugo.toml`            | Add to `params.search`                                         |
| `unionai-docs-infra/Makefile`             | Add a new `make variant` to `dist` target                      |
| `<content>.md`                            | Add either `+<variant>` or `-<variant>` to all content pages   |
| `unionai-docs-infra/config.<variant>.toml`| Create a new file and configure `baseURL` and `params.variant` |

### Testing the new variant

As you develop the new variant, it is recommended to have a `pre-release/<variant>` semi-stable
branch to confirm everything is working and the content looks good. It will also allow others
to collaborate by creating PRs against it (`base=pre-release/<variant>` instead of `main`)
without trampling on each other and allowing for parallel reviews.

Once the variant branch is correct, you merge that branch into main.

### Building (just) the variant

You can build the production version of the variant,
which will also trigger all the safety checks as well,
by invoking the variant build:

```bash
make variant VARIANT=<variant>
```

For example:

```bash
make variant VARIANT=union
```

=== PAGE: https://www.union.ai/docs/latest/flyte/community/contributing-docs/versions ===

# Versions

In addition to the product variants, the docs site also supports multiple versions of the documentation.
The version selector is located at the top of the page, next to the variant selector.
Versions and variants are independent of each other, with the version being "above" the variant in the URL hierarchy.

The URL for version `v2` of the current page (the one you are one right now) in the Flyte variant is:

`/docs/v2/flyte//community/contributing-docs/versions`

while the URL for version `v1` of the same page is:

`/docs/v1/flyte//community/contributing-docs/versions`

## What a version contains (and what it does not)

A docs version is a snapshot of **content** — the pages, examples and generated API
reference as they stood against a given SDK release. The site's **look and
navigation** (the theme, built from the shared `unionai-docs-infra` submodule) is
*not* part of the snapshot: every published version, however old, is always served
with the **current** site UI. This is deliberate — the content you are reading has a
version; the reading experience should always be the best available.

Two practical consequences for contributors:

- **Theme or build-system changes never require a new docs version.** They reach
  every published version automatically when the infra submodule pointer is bumped
  on the docs branch.
- **Content changes reach `latest` immediately** on merge, and reach the stable
  version at the next cut.

## Versions are branches

The versioning system is based on long-lived Git branches in the `unionai/unionai-docs` GitHub repository:

- The `main` branch contains the latest version of the documentation. Currently, `v2`.
- Other versions of the docs are contained in branches named `vX`, where `X` is the major version number. Currently, there is one other version, `v1`.

## How to create an archive version

An "archive version" is a static snapshot of the site at a given point in time.

It is meant to freeze a specific version of the site for historical purposes,
such as preserving the content and structure of the site at a specific point in time.

### How to create an archive version

1. Create a new branch from `main` named `vX`, e.g. `v3`.
2. Add the version to the `VERSION` field in the `makefile.inc` file, e.g. `VERSION := v3`.
3. Add the version to the `versions` field in the `hugo.ver.toml` file, e.g. `versions = [ "v1", "v2", "v3" ]`.

> [!NOTE]
> **Important:** You must update the `versions` field in **ALL** published and archived versions of the site.

### Publishing an archive version

> [!NOTE]
> This step can only be done by a Union employee.

1. Update the `docs_archive_versions` in the `docs_archive_locals.tf` Terraform file
2. Create a PR for the changes
3. Once the PR is merged, run the production pipeline to activate the new version

=== PAGE: https://www.union.ai/docs/latest/flyte/community/contributing-docs/shortcodes ===

# Shortcodes

This site has special blocks that can be used to generate code for Union.

> [!NOTE]
> You can see examples by running the dev server and visiting
> [`http://localhost:1313/__docs_builder__/shortcodes/`](`http://localhost:1313/__docs_builder__/shortcodes/`).
> Note that this page is only visible locally. It does not appear in the menus or in the production build.
>
> If you need instructions on how to create the local environment and get the
> `localhost:1313` server running, please refer to [Set up a local docs dev environment](./quick-start).

## How to specify a "shortcode"

The shortcode is a string that is used to generate the HTML that is displayed.

You can specify parameters, when applicable, or have content inside it, if applicable.

> [!NOTE]
> If you specify content, you have to have a close tag.

Examples:

* A shortcode that just outputs something

```markdown
{{</* key product_name */>}}
```

* A shortcode that has content inside

```markdown
{{</* markdown */>}}
* You markdown
* goes here
{{</* /markdown */>}}
```

* A shortcode with parameters

```markdown
{{</* link-card target="union-sdk" icon="workflow" title="Union SDK" */>}}
The Union SDK provides the Python API for building Union workflows and apps.
{{</* /link-card */>}}
```

> [!NOTE]
> If you're wondering why we have a `{{</* markdown */>}}` when we can generate markdown at the top level, it is due to a quirk in Hugo:
>
> * At the top level of the page, Hugo can render markdown directly, interspersed with shortcodes.
> * However, *inside* a container shortcode, Hugo can only render *either* other shortcodes *or* Markdown.
> * The `{{</* markdown */>}}` shortcode is designed to contain only Markdown (not other shortcodes).
> * All other container shortcodes are designed to contain only other shortcodes.

## Variants

The big difference of this site, compared to other documentation sites, is that we generate multiple "flavors" of the documentation that are slightly different from each other. We are calling these "variants."

When you are writing your content, and you want a specific part of the content to be conditional on a flavor, say "Union", you surround that with `variant`.

>[!NOTE]
> `variant` is a container, so inside you will specify what you are wrapping.
> You can wrap any of the shortcodes listed in this document.

Example:

```markdown
{{</* variant union */>}}
{{</* markdown */>}}
**The quick brown fox signed up for Union!**
{{</* /markdown */>}}

{{</* button-link text="Contact Us" target="https://union.ai/contact" */>}}
{{</* /variant */>}}
```

## Component library

### `{{</* audio */>}}`

Generates an audio media player.

<!-- TODO: document parameters -->

### `{{</* grid */>}}`

Creates a fixed column grid for lining up content.

<!-- TODO: document parameters -->

### `{{</* variant */>}}`

Filters content based on which flavor you're seeing.

<!-- TODO: document parameters -->

### `{{</* link-card */>}}`

A floating, clickable, navigable card.

<!--  TODO: document parameters -->

### `{{</* markdown */>}}`

Generates a markdown block, to be used inside containers such as `{{</* dropdown */>}}` or `{{</* variant */>}}`.

<!-- TODO: document parameters -->

### `{{</* multiline */>}}`

Generates a multiple line, single paragraph. Useful for making a multiline table cell.

<!-- TODO: document parameters -->

### `{{</* tabs */>}}` and `{{</* tab */>}}`

Generates a tab panel with content switching per tab.

<!-- TODO: document parameters -->

### `{{</* key */>}}`

Outputs one of the pre-defined keywords.
Enables inline text that differs per-variant without using the heavy-weight `{{</* variant>}}...{{</* /variant */>}}` construct.

Take, for example, the following:

```markdown
The {{</* key product_name */>}} platform is awesome.
```

In the Flyte variant of the site this will render as:

> The Flyte platform is awesome.

Whereas in the Union variant of the site it will render as:

> The Union.ai platform is awesome.

You can add keywords and specify their value, per variant, in `hugo.site.toml`:

```toml
[params.key.product_full_name]
flyte = "Flyte"
union = "Union.ai"
```

#### List of available keys

| Key               | Description                           | Example Usage (Flyte → Union)                                          |
| ----------------- | ------------------------------------- | ---------------------------------------------------------------------- |
| default_project   | Default project name used in examples | `{{</* key default_project */>}}` → "flytesnacks" or "default"             |
| product_full_name | Full product name                     | `{{</* key product_full_name */>}}` → "Flyte OSS" or "Union.ai"            |
| product_name      | Short product name                    | `{{</* key product_name */>}}` → "Flyte" or "Union.ai"                     |
| product           | Lowercase product identifier          | `{{</* key product */>}}` → "flyte" or "union"                             |
| kit_name          | SDK name                              | `{{</* key kit_name */>}}` → "Flytekit" or "Union"                         |
| kit               | Lowercase SDK identifier              | `{{</* key kit */>}}` → "flytekit" or "union"                              |
| kit_as            | SDK import alias                      | `{{</* key kit_as */>}}` → "fl" or "union"                                 |
| kit_import        | SDK import statement                  | `{{</* key kit_import */>}}` → "flytekit as fl" or "union"                 |
| kit_remote        | Remote client class name              | `{{</* key kit_remote */>}}` → "FlyteRemote" or "UnionRemote"              |
| cli_name          | CLI tool name                         | `{{</* key cli_name */>}}` → "Pyflyte" or "Union"                          |
| cli               | Lowercase CLI tool identifier         | `{{</* key cli */>}}` → "pyflyte" or "union"                               |
| ctl_name          | Control tool name                     | `{{</* key ctl_name */>}}` → "Flytectl" or "Uctl"                          |
| ctl               | Lowercase control tool identifier     | `{{</* key ctl */>}}` → "flytectl" or "uctl"                               |
| config_env        | Configuration environment variable    | `{{</* key config_env */>}}` → "FLYTECTL_CONFIG" or "UNION_CONFIG"         |
| env_prefix        | Environment variable prefix           | `{{</* key env_prefix */>}}` → "FLYTE" or "UNION"                          |
| docs_home         | Documentation home URL                | `{{</* key docs_home */>}}` → "/docs/v2/flyte" or "/docs/v2/union"        |
| map_func          | Map function name                     | `{{</* key map_func */>}}` → "map_task" or "map"                           |
| logo              | Logo image filename                   | `{{</* key logo */>}}` → "flyte-logo.svg" or "union-logo.svg"              |
| favicon           | Favicon image filename                | `{{</* key favicon */>}}` → "flyte-favicon.ico" or "union-favicon.ico"     |

### `{{</* download */>}}`

Generates a download link.

Parameters:

- `url`: The URL to download from
- `filename`: The filename to save the file as
- `text`: The text to display for the download link

Example:

```markdown
{{</* download "/_static/public/public-key.txt" "public-key.txt" */>}}
```

### `{{</* docs_home */>}}`

Produces a link to the home page of the documentation for a specific variant.

Example:

```markdown
[See this in Flyte]({{</* docs_home flyte>}}/wherever/you/want/to/go/in/flyte/docs)
```

### `{{</* py_class_docsum */>}}`, `{{</* py_class_ref */>}}`, and `{{</* py_func_ref */>}}`

Helper functions to track Python classes in Flyte documentation, so we can link them to
the appropriate documentation.

Parameters:

- name of the class
- text to add to the link

Example:

```markdown
Please see {{</* py_class_ref flyte.core.Image */>}} for more details.
```

### `{{</* icon name */>}}`

Uses a named icon in the content.

Example:

```markdown
[Download {{</* icon download */>}}](/download)
```

### `{{</* code */>}}`

Includes a code snippet or file.

Parameters:

- `file`: The path to the file to include.
- `fragment`: The name of the fragment to include.
- `from`: The line number to start including from.
- `to`: The line number to stop including at.
- `lang`: The language of the code snippet.
- `show_fragments`: Whether to show the fragment names in the code block.
- `highlight`: Whether to highlight the code snippet.

The examples in this section uses this file as base:

```
def main():
    """
    A sample function
    """
    return 42

# {{docs-fragment entrypoint}}
if __name__ == "__main__":
    main()
# {{/docs-fragment entrypoint}}
```

*Source: /_static/__docs_builder__/sample.py*
Link to [/_static/__docs_builder__/sample.py](https://www.union.ai/docs/latest/flyte/_static/__docs_builder__/sample.py)

#### Including a section of a file: `{{docs-fragment}}`

```markdown
{{</* code file="/_static/__docs_builder__/sample.py" fragment=entrypoint lang=python */>}}
```

Effect:

```
def main():
    """
    A sample function
    """
    return 42

# {{docs-fragment entrypoint}}
if __name__ == "__main__":
    main()
# {{/docs-fragment entrypoint}}
```

*Source: /_static/__docs_builder__/sample.py*

#### Including a file with a specific line range: `from` and `to`

```markdown
{{</* code file="/_static/__docs_builder__/sample.py" from=2 to=4 lang=python */>}}
```

Effect:

```
def main():
    """
    A sample function
    """
    return 42

# {{docs-fragment entrypoint}}
if __name__ == "__main__":
    main()
# {{/docs-fragment entrypoint}}
```

*Source: /_static/__docs_builder__/sample.py*

#### Including a whole file

Simply specify no filters, just the `file` attribute:

```markdown
{{</* code file="/_static/__docs_builder__/sample.py" */>}}
```

> [!NOTE]
> Note that without `show_fragments=true` the fragment markers will not be shown.

Effect:

```
def main():
    """
    A sample function
    """
    return 42

# {{docs-fragment entrypoint}}
if __name__ == "__main__":
    main()
# {{/docs-fragment entrypoint}}
```

*Source: /_static/__docs_builder__/sample.py*

=== PAGE: https://www.union.ai/docs/latest/flyte/community/contributing-docs/api-docs ===

# API docs

You can import Python APIs and host them on the site. To do that you will use
the `unionai-docs-infra/tools/api_generator` to parse and create the appropriate markdown.

Please refer to [`api_generator/README`](https://github.com/unionai/unionai-docs-infra/blob/main/tools/api_generator/README.md) for more details.

## API naming convention

All the buildable APIs are defined in Makefiles of the form:

`unionai-docs-infra/Makefile.api.<api_name>`

To build it, run `make -f unionai-docs-infra/Makefile.api.<your_api>` and observe the setup
requirements in the `README.md` file above. Alternatively, `make update-api-docs` will regenerate all API docs.

## Package resource resolution

When scanning the packages we need to know when to include or exclude an object
(class, function, variable) from the documentation. The parser will follow this
workflow to decide, in order, if the resource must be in or out:

1. `__all__: List[str]` package-level variable is present: Only resources
   listed will be exposed. All other resources are excluded.

   Example:

   ```python
   from http import HTTPStatus, HTTPMethod

   __all__ = ["HTTPStatus", "LocalThingy"]

   class LocalThingy:
      ...

   class AnotherLocalThingy:
      ...
   ```

   In this example only `HTTPStatus` and `LocalThingy` will show in the docs.
   Both `HTTPMethod` and `AnotherLocalThingy` are ignored.

2. If `__all__` is not present, these rules are observed:

    - All imported packages are ignored
    - All objects starting with `_` are ignored

   Example:

   ```python
   from http import HTTPStatus, HTTPMethod

   class _LocalThingy:
      ...

   class AnotherLocalThingy:
      ...

   def _a_func():
      ...

   def b_func():
      ...
   ```

   In this example only `AnotherLocalThingy` and `b_func` will show in the docs.
   Neither none of the imports nor `_LocalThingy` will show in the documentation.

## Tips and tricks

1. If you either have no resources without a `_` nor an `__all__` to
   export blocked resources (imports or starting with `_`, the package will have no content and thus will not be generated.

2. If you want to export something you `from ___ import ____` you _must_
   use `__all__` to add the private import to the public list.

3. If all your methods follow the Python convention of everything private starts
   with `_` and everything you want public does not, you do not need to have a
   `__all__` allow list.

## Auto-linking

Every package that the API generator processes, the SDK and all plugins, emits a linkmap file (`linkmap/<name>-linkmap.json`) that maps identifiers to their API reference URLs. Two scripts in the shared infra consume those linkmaps at runtime to turn mentions of those identifiers in docs prose and code samples into links to the API reference:

- `static/js/inline-code-linker.js`: wraps inline `` `code` `` whose text matches a linkmap key.
- `static/js/codeblock-linker.js`: wraps matching identifiers inside Python code blocks based on the block's `import` statements.

**Registration is automatic.** At build time, `layouts/_default/baseof.html` scans `linkmap/` and exposes every `*-linkmap.json` file as `window.__LINKMAP_SOURCES`. Both linker scripts read that variable and fetch the linkmaps on page load. There is no per-package wiring step: adding an entry to `api-packages.toml` is enough; the generator produces its linkmap and the linkers pick it up.

### Short vs. fully-qualified names

Whether short names get emitted is controlled by the `--short-names` generator flag:

- **Plugins** (`Makefile.api.plugins`): `--short-names` is enabled. Each identifier is emitted under both keys, e.g. `flyteplugins.wandb.wandb_init` _and_ the bare `wandb_init`, so authors can use either form in prose.
- **SDK** (`Makefile.api.sdk`): `--short-names` is not passed. SDK identifiers are only emitted fully qualified (e.g. `flyte.io.File`). Bare short names like `` `File` `` won't autolink against the SDK.

### How auto-linking works

- **Inline code**: `` `flyte.io.File` `` (or `` `wandb_init()` ``) is wrapped with a link to its API reference. A trailing `()` and a leading `@` (for decorators) are stripped before lookup. `ClassName.method` syntax falls back to `<class-url>#method` when the class is in the linkmap.
- **Code blocks**: identifiers inside Python code blocks are linked based on the block's `from … import …` and `import …` statements: only names that resolve through one of those imports get wrapped.

### Magic-marker syntax for inline code

If an identifier is in some linkmap but not in a form that matches what you wrote, wrap the text in `[[…]]` inside the backticks to force a match by last segment:

```markdown
The `[[Trigger]]` class …
```

renders as `Trigger` and links to the API reference (resolving to `flyte.Trigger`) even when only the fully-qualified short form isn't in the linkmap.

=== PAGE: https://www.union.ai/docs/latest/flyte/community/contributing-docs/llm-docs ===

# LLM-optimized documentation

The build pipeline generates LLM-optimized versions of every page and several index files,
designed for use by AI coding agents and AI search engines.

## Output files

The `make dist` command (specifically the `make llm-docs` step) produces the following
in each variant's `dist/docs/v2/{variant}/` directory:

| File | Description |
|------|-------------|
| `page.md` | Per-page LLM-optimized Markdown, generated alongside every `index.html`. Links between pages use relative `page.md` references, then are converted to absolute URLs in a final pass. |
| `section.md` | A single-file bundle concatenating all pages in a section. Only generated for sections with `llm_readable_bundle: true` in frontmatter. Internal links become hierarchical bold references; external links become absolute URLs. |
| `llms.txt` | Page index listing every page grouped by section, with H2/H3 headings for discoverability. Sections with bundles are marked with a "Section bundle" link. |
| `llms-full.txt` | The entire documentation for one variant as a single file, with all internal links converted to hierarchical bold references (e.g. `**Configure tasks > Resources**`). |

### Discovery hierarchy

```
dist/docs/llms.txt                          # Root: lists versions
dist/docs/v2/llms.txt                       # Version: lists variants
dist/docs/v2/{variant}/llms.txt             # Variant: page index with headings
dist/docs/v2/{variant}/llms-full.txt        # Full consolidated doc
dist/docs/v2/{variant}/**/page.md           # Per-page Markdown
dist/docs/v2/{variant}/**/section.md        # Section bundles (where enabled)
```

## How `page.md` files are generated

1. Hugo builds the site into `dist/` and also outputs a Markdown format into `tmp-md/`.
2. `process_shortcodes.py` reads from `tmp-md/`, resolves all shortcodes (variants, code includes, tabs, notes, etc.), and writes the result as `page.md` alongside each `index.html`.
3. `fix_internal_links_post_processing()` converts all internal links in `page.md` files to point to other `page.md` files using relative paths.
4. `build_llm_docs.py` then enhances subpage listings with H2/H3 headings, generates section bundles, converts all relative links to absolute URLs, and creates the `llms.txt` and `llms-full.txt` index files.

## Enabling section bundles

To produce a `section.md` bundle for a documentation section:

1. Add `llm_readable_bundle: true` to the frontmatter of the section's `_index.md`:

   ```yaml
   ---
   title: Configure tasks
   weight: 8
   variants: +flyte +union
   llm_readable_bundle: true
   ---
   ```

2. Add the `{{</* llm-bundle-note */>}}` shortcode in the body of the same `_index.md`,
   right after the page title:

   ```markdown
   # Configure tasks

   {{</* llm-bundle-note */>}}

   As we saw in ...
   ```

   This renders a note on the HTML page pointing readers to the `section.md` file.

Both the frontmatter parameter and the shortcode are required.
A CI check (`check-llm-bundle-notes`) verifies they are always in sync.

## The `llms-full.txt` link conversion

In `llms-full.txt`, all internal `page.md` links are converted to hierarchical bold references:

* Cross-page: `[Resources](../resources/page.md)` becomes `**Configure tasks > Resources**`
* Same-page anchor: `[Image building](#image-building)` becomes `**Container images > Image building**`
* External links (`http`/`https`) are preserved unchanged.

This makes the file self-contained with no broken references.

## Regenerating

LLM documentation is regenerated automatically as part of `make dist`.
To regenerate only the LLM files without a full rebuild:

```
make llm-docs
```

New pages are included automatically if linked via `## Subpages` in their parent's Hugo output.

=== PAGE: https://www.union.ai/docs/latest/flyte/community/contributing-docs/redirects ===

# Redirects

We use Cloudflare's Bulk Redirect to map URLs that moved to their new location,
so the user does not get a 404 using the old link.

The direct files are in CSV format, with the following structure:

`<incoming_redirect>,<target_url>,302,TRUE,FALSE,TRUE,TRUE`

- `<incoming_redirect>`: the URL without `https://`
- `<target_url>`: the full URL (including `https://`) to send the user to

Redirects are recorded in the `unionai-docs-infra/redirects.csv` file.

To take effect, this file must be applied to the production environment on CloudFlare by a Union employee.

If you need to add a new redirect, please create a pull request with the change to `redirect.csv` and a note indicating that you would like to have it applied to production.

## `docs.union.ai` redirects

For redirects from the old `docs.union.ai` site to the new `www.union.ai/docs` site, we use the original request URL. For example:

|
|-|-|
| Request URL | `https://docs.union.ai/administration` |
| Target URL | `/docs/v1/union//user-guide/administration` |
| Redirect Entry | `docs.union.ai/administration,/docs/v1/union//user-guide/administration,302,TRUE,FALSE,TRUE,TRUE` |

## `docs.flyte.org` redirects

For directs from the old `docs.flyte.org` to the new `www.union.ai/docs`, we replace the `docs.flyte.org` in the request URL with the special prefix `www.union.ai/_r_/flyte`. For example:

|
|-|-|
| Request URL | `https://docs.flyte.org/projects/flytekit/en/latest/generated/flytekit.dynamic.html` |
| Converted request URL | `www.union.ai/_r_/flyte/projects/flytekit/en/latest/generated/flytekit.dynamic.html` |
| Target URL | `/docs/v1/flyte//api-reference/flytekit-sdk/packages/flytekit.core.dynamic_workflow_task/` |
| Redirect Entry | `www.union.ai/_r_/flyte/projects/flytekit/en/latest/generated/flytekit.dynamic.html,/docs/v1/flyte//api-reference/flytekit-sdk/packages/flytekit.core.dynamic_workflow_task/,302,TRUE,FALSE,TRUE,TRUE` |

The special prefix is used so that we can include both `docs.union.ai` and `docs.flyte.org` redirects in the same file and apply them on the same domain (`www.union.ai`).

=== PAGE: https://www.union.ai/docs/latest/flyte/community/contributing-docs/publishing ===

# Production builds and troubleshooting

This page covers building the site the way production does and troubleshooting what you see in the local preview.
To set up your machine and run the live preview for the first time, see [Set up a local docs dev environment](./quick-start).

## Build the production site

To build every variant the way the Cloudflare production pipeline does, run:

```bash
make dist
```

This builds all variants and writes the result to the `dist/` folder.

### Test the production build

Serve the `dist/` folder locally to confirm the site behaves as it would at its official URL:

```bash
make serve [PORT=<nnnnn>]
```

If you do not pass a port, it defaults to `9000`. For example:

```bash
make serve PORT=4444
```

Then open `http://localhost:<port>` in your browser. In the example above, that is `http://localhost:4444/`.

## Troubleshooting

### Missing content

Content may be hidden by `{{</* variant */>}}` blocks. To see what is hidden, adjust the show/hide settings in `hugo.local.toml` while running the dev server.

For a production-like view, set:

```toml
show_inactive = false
highlight_active = false
```

For a full developer view that reveals all variant content, set:

```toml
show_inactive = true
highlight_active = true
```

See [Set up a local docs dev environment > Development settings](./quick-start#development-settings) for what each setting does.

### Page visibility

The dev server marks in red any page that is missing from the current variant.
For a page to appear in a variant (or be deliberately excluded), that variant must be listed in the page's `variants` frontmatter field.
Click a red page to see the path you need to add and a link with guidance.

See [Author content > Page visibility](./authoring#page-visibility) for more details on the `variants` field.

