Customize Portal Content
Features described on this page are in alpha and subject to change. For access, contact your Replicated account representative.
This topic describes how to customize the content in the new Enterprise Portal, including the content template structure, table of contents configuration, MDX components, template variables, visibility rules, and downloadable assets.
For branding and theme customization, see Customize Portal Branding.
Content template structure
The default content template (replicatedhq/enterprise-portal-content) provides a working portal out of the box with the following structure:
your-content-repo/
├── pages/
│ ├── home.md
│ ├── installation/
│ │ ├── requirements.md
│ │ ├── release-history.md
│ │ ├── linux.md
│ │ └── helm.md
│ ├── operations/
│ │ ├── security.md
│ │ └── bundles/
│ │ ├── bundles.md
│ │ ├── helm.md
│ │ ├── linux.md
│ │ └── uploaded.md
│ ├── updates/
│ │ └── checking.md
│ └── support/
│ ├── faq.md
│ └── contact.md
└── toc.yaml
The template's toc.yaml organizes content into four sections:
navigation:
- title: Installation
icon: rocket
items:
- title: Requirements
page: pages/installation/requirements.md
visible_when:
entitlements:
- isEmbeddedClusterDownloadEnabled
- title: Release History
page: pages/installation/release-history.md
- title: Linux
page: pages/installation/linux.md
visible_when:
entitlements:
- isEmbeddedClusterDownloadEnabled
- title: Helm
page: pages/installation/helm.md
visible_when:
entitlements:
- isHelmInstallEnabled
- title: Operations
icon: wrench
items:
- title: Security
page: pages/operations/security.md
- title: Support Bundles
page: pages/operations/bundles/bundles.md
- title: Upload Bundles
page: pages/operations/bundles/uploaded.md
- title: Updates
icon: refresh-cw
items:
- title: Checking for Updates
page: pages/updates/checking.md
- title: Support
icon: life-buoy
items:
- title: FAQ
page: pages/support/faq.md
- title: Contact Support
page: pages/support/contact.md
overrides:
home: pages/home.md
The template pages use built-in MDX components (see MDX Components) to render interactive installation instructions, version selectors, support bundle uploads, and more. You can customize any page by editing the markdown and MDX, or replace the entire structure with your own.
Table of contents
The toc.yaml file at the root of your repo defines the sidebar navigation. Each navigation item has a title and one of the following content types:
| Key | What it does |
|---|---|
page | Renders a markdown file from your repo (e.g. pages/getting-started.md) |
terraform_module | Generates docs from a Terraform module source URI (see Terraform Modules) |
helm_chart | Generates reference docs from a Helm chart in your promoted release (see Helm Reference Docs) |
items | Nests child navigation items to create expandable sections |
Every item also supports icon and visible_when (see Visibility below).
Supported icon values: rocket, download, cloud, settings, wrench, life-buoy, file-text, star, book, shield, package, refresh-cw, database, key. If omitted, defaults to book.
Complete example
Here's a toc.yaml showing all content types together:
navigation:
- title: Getting Started
icon: rocket
page: pages/getting-started.md
- title: Installation
icon: download
items:
- title: Requirements
page: pages/installation/requirements.md
- title: Helm Installation
page: pages/installation/helm.md
visible_when:
entitlements:
- isHelmInstallEnabled
- title: Air Gap Installation
page: pages/installation/airgap.md
visible_when:
entitlements:
- isAirgapSupported
- title: Infrastructure
icon: database
items:
- title: AWS Module
terraform_module: github.com/your-org/your-terraform//modules/aws?ref=v1.0.0
visible_when:
entitlements:
- isAWSEnabled
- title: Reference
icon: book
items:
- title: My App Chart
helm_chart:
name: my-app
overrides:
home: pages/getting-started.md
MDX components
Enterprise Portal content supports MDX, which is markdown with embedded React components. These components render interactive UI elements that adapt to each customer's license, entitlements, and instance state.
Layout and callouts
<Note>: Informational callout box.
<Note title="Before You Begin">
Run `kubectl get sc` to confirm a default StorageClass is available.
</Note>
<Tip>: Highlighted tip or best practice.
<Tip title="New to this portal?">
Start with the Installation Guide for your deployment method.
</Tip>
<Warning>: Warning callout for important caveats.
<Warning title="Back Up Before Updating">
Always create a backup before applying updates.
</Warning>
<Tabs> / <Tab>: Tabbed content sections.
<Tabs>
<Tab title="Linux">
Linux-specific instructions here...
</Tab>
<Tab title="Helm">
Helm-specific instructions here...
</Tab>
</Tabs>
Props: <Tabs> accepts defaultActiveTab. <Tab> requires title.
<Accordion>: Collapsible content section.
<Accordion title="Advanced Configuration" defaultOpen={false}>
Detailed configuration options...
</Accordion>
Props: title (required), defaultOpen (optional, defaults to false).
<OptionSelector> / <Option>: Persistent option picker that remembers the customer's selection across page loads.
<OptionSelector label="Install Method" defaultOption="Linux" storageKey="install-method">
<Option value="Linux">
- [Linux Installation](installation/linux)
- [Linux Support Bundles](operations/bundles/linux)
</Option>
<Option value="Helm">
- [Helm Installation](installation/helm)
- [Helm Support Bundles](operations/bundles/helm)
</Option>
</OptionSelector>
Props: label (display label), defaultOption (pre-selected value), storageKey (key for persisting selection in browser storage).
Display
<CodeBlock>: Syntax-highlighted code block.
<CodeBlock language="yaml" title="values.yaml">
replicaCount: 3
image:
repository: myapp
</CodeBlock>
Props: language, title.
<CommandBlock>: Styled terminal command with copy button.
<CommandBlock>
kubectl get pods -A
</CommandBlock>
Props: command, label, encoded.
<ContentLink>: Internal navigation links. Standard markdown links ([text](path)) are automatically converted to use client-side navigation, so you don't need to use this component directly.
Installation components
These components render dynamic, customer-specific installation instructions based on the customer's license entitlements, selected install method, and instance state.
<PendingInstallSelector>: Shows a list of in-progress installations scoped to a specific install method. Customers select an installation to populate the commands below with that installation's credentials.
<PendingInstallSelector method="linux" />
Props: method ("linux" or "helm", required), network ("online" or "airgap", optional filter), title (optional, defaults to "Installations in progress"), emptyText (optional), initialVisible (optional, number of items to show before "Show all").
<NewInstall>: Button to start a new installation. Creates a service account and generates credentials, which populate the install commands on the page.
<NewInstall method="helm" />
Props: method ("linux" or "helm", required), network ("online" or "airgap", optional, defaults to "online"), label (optional, defaults to "New installation").
The install commands on the page are personalized to the selected installation. If you switch installations or rename your instance, the commands update automatically.
<NetworkAvailability>: Selector for online vs. air gap installation mode.
<NetworkAvailability installType="linux" />
Props: installType ("linux" or "helm").
<VersionSelector>: Dropdown for selecting which release version to install.
<VersionSelector installType="helm" />
Props: installType ("linux" or "helm").
<KubernetesDistribution />: Selector for the target Kubernetes distribution (EKS, GKE, AKS, etc.). No props.
<RegistryAccess />: Displays registry credentials and pull secret configuration. No props.
<LinuxInstallAssets />: Renders the full Linux/Embedded Cluster installation command sequence. Adapts to the customer's selected version and network availability. Props: stepNumber (optional, starting step number).
<HelmInstallAssets />: Renders the full Helm installation command sequence. Props: stepNumber (optional).
<LinuxAirgapInstallAssets />: Linux air gap installation commands. Props: stepNumber.
<HelmAirgapInstallAssets />: Helm air gap installation commands. Props: stepNumber, registryAvailability.
<InstanceName />: Prompts the customer to name their instance after installation. Renaming updates the service account name and refreshes the install commands on the page.
<InstanceName />
Props: title (optional, defaults to "Name Your Instance"), method (optional).
<AdminConsoleUrl />: Displays the admin console URL for Embedded Cluster installations. No props.
<InstallStep>: Wraps content in a numbered step container.
<InstallStep stepNumber={1} title="Download the installer">
Run the following command to download...
</InstallStep>
Props: stepNumber, title, optional (boolean).
<Prerequisites>: Styled prerequisites section.
<Prerequisites title="Before You Begin">
- Kubernetes 1.26+
- Helm 3.x
</Prerequisites>
Update components
<LinuxUpdateAssets />: Renders Linux/Embedded Cluster upgrade instructions for the customer's current instance. Props: stepNumber.
<HelmUpdateAssets />: Renders Helm upgrade instructions. Props: stepNumber.
<UpgradePath>: Conditionally shows content based on the customer's current version. Lets you show different upgrade instructions depending on which version the customer is upgrading from.
Props:
| Prop | Description |
|---|---|
fromBelow | Show content only when the customer's current version is below this version |
fromAbove | Show content only when the customer's current version is above this version |
fromBelowOrEqual | Show content only when the current version is at or below this version |
fromAtLeast | Show content only when the current version is at least this version |
All version values must be strict major.minor.patch format (e.g. 2.0.0). A v prefix is stripped automatically. Pre-release suffixes (e.g. 2.0.0-rc.1) are not supported.
Props can be combined to define a version range (AND logic). If the customer has no selected instance or the version can't be parsed, the content is hidden.
Example:
<UpgradePath fromBelow="2.0.0">
## Upgrading from 1.x
Before upgrading to 2.x, you must migrate your database schema. Run:
```shell
./migrate-schema.sh
```
</UpgradePath>
<UpgradePath fromAtLeast="2.0.0">
## Upgrading from 2.x
No manual migration needed. The upgrade is automatic.
</UpgradePath>
In this example, a customer on version 1.5.0 would see the "Upgrading from 1.x" instructions, while a customer on 2.1.0 would see the "Upgrading from 2.x" block.
<MarkUpdateComplete />: Button for the customer to confirm an upgrade is complete. No props.
<ReleaseNotes />: Displays release notes for the target update version. No props.
Portal components
<ReleaseHistory />: Renders a browsable release history timeline with version details and release notes. Props: limit (optional, max number of releases to show).
<SupportBundleUpload />: Upload interface for support bundles. No props.
<SupportBundleUploadHistory />: Lists previously uploaded support bundles. Props: limit.
<LinuxBundles />: Linux-specific support bundle generation instructions. No props.
<HelmBundles />: Helm-specific support bundle generation instructions. No props.
<ContactInfo />: Displays the support contact information configured in theme.yaml. No props.
<InstancesAndUpdates />: Renders the full instances and updates management page inline. No props.
Security components
These components require Security Center to be enabled for the customer. See Security Center for more information.
<CVEReport />: Displays CVE vulnerability report for the selected release. No props.
<SBOMReport />: Displays the Software Bill of Materials for the selected release. No props.
<SecurityVersionSelector />: Version picker for security reports. No props.
Template variables
Enterprise Portal content supports Mustache-style templating with \{\{ \}\} syntax for dynamic rendering. Template variables and MDX components can be used together in the same page.
Available variables
| Variable | Description |
|---|---|
\{\{ app.name \}\} | Your application name |
\{\{ app.slug \}\} | URL-friendly app identifier |
\{\{ customer.name \}\} | Customer's name |
\{\{ customer.email \}\} | Customer's email |
\{\{ customer.id \}\} | Customer ID |
\{\{ channel.name \}\} | Release channel (Stable, Beta, etc.) |
\{\{ channel.slug \}\} | URL-friendly channel identifier |
\{\{ release.version \}\} | Current release version |
\{\{ license.* \}\} | Any field from the license object (e.g. \{\{ license.id \}\}, \{\{ license.expiresAt \}\}) |
\{\{ entitlements.* \}\} | Any entitlement value, built-in or custom (see below) |
\{\{ release.version \}\} depends on the customer having reported an active instance. It may be empty for new customers who haven't installed yet. Consider using \{\{ channel.name \}\} as a more reliable alternative for version-dependent content.
Conditionals
\{\{#if\}\}: Show content when a value is truthy. Supports nesting.
{{#if entitlements.isHAEnabled}}
## High Availability Setup
For production deployments, enable HA mode...
{{/if}}
Values are considered falsy if they are null, empty string, false, "false", "0", or 0. Everything else is truthy.
\{\{#ifEquals\}\}: Show content when a value equals a specific string. Useful for per-customer or per-channel content.
{{#ifEquals channel.name "Stable"}}
You are on the Stable channel. Updates are less frequent but thoroughly tested.
{{/ifEquals}}
{{#ifEquals customer.name "Acme Corp"}}
## Acme-Specific Configuration
Your dedicated endpoint is acme.example.com
{{/ifEquals}}
The comparison value must be quoted (double or single quotes). Supports nesting.
Entitlements
Entitlements are accessible as \{\{ entitlements.<name> \}\} for interpolation and \{\{#if entitlements.<name>\}\} for conditionals. There are two kinds:
- Built-in flags: Set on the license via Vendor Portal:
isHelmInstallEnabled,isAirgapSupported,isEmbeddedClusterDownloadEnabled,isEmbeddedClusterMultiNodeEnabled,isKotsInstallEnabled,isHelmAirgapEnabled - Custom entitlements: Any that you define (e.g.
isHAEnabled,isEnterpriseEnabled)
Example:
{{#if entitlements.isHelmInstallEnabled}}
## Helm Installation
Follow these steps to install using Helm...
{{/if}}
{{#if entitlements.isHAEnabled}}
## High Availability Setup
For production deployments, enable HA mode...
{{/if}}
Visibility
Use visible_when to control which customers see which content. All conditions must be satisfied (AND logic).
Navigation visibility (toc.yaml)
Apply visible_when on any navigation item in toc.yaml:
- title: Enterprise Features
page: pages/enterprise.md
visible_when:
entitlements:
- isEnterpriseEnabled
channel:
include: [Stable, Beta]
exclude: [Internal]
customer_type:
include: [paid]
All three filter types (entitlements, channel, and customer_type) are fully evaluated on both the server and the client.
Page-level visibility (frontmatter)
You can also apply visible_when in a page's YAML frontmatter. This controls whether the page is accessible to a customer, independent of whether it appears in the navigation.
---
title: Embedded Cluster Installation Requirements
visible_when:
entitlements:
- isEmbeddedClusterDownloadEnabled
---
# Embedded Cluster Installation Requirements
Ensure your environment meets these requirements...
The same entitlements conditions available in toc.yaml work in frontmatter. Use this when you want a page gated by entitlements even if the toc.yaml entry doesn't have its own visible_when (for example, a page reachable via internal links but not navigation).
Downloadable assets
You can distribute files (scripts, checklists, configuration templates, etc.) through Enterprise Portal by committing them to an assets/ directory in your content repo.
Repo structure
your-content-repo/
├── assets/
│ ├── deploy.sh
│ └── onboarding-checklist.pdf
├── pages/
│ └── resources.md
└── toc.yaml
Any file committed to the assets/ directory is available for download. There are no restrictions on file type or size beyond what your git hosting provider allows (GitHub supports files up to ~100MB via raw content). Assets are fetched directly from your git repo when a customer clicks a download link, so changes are available as soon as you push.
Linking to assets
Use the \{\{asset "path"\}\} template tag in your markdown to generate a download link:
## Resources
- [Deployment Script]({{asset "assets/deploy.sh"}})
- [Onboarding Checklist]({{asset "assets/onboarding-checklist.pdf"}})
The tag expands to a URL that authenticates the customer via their session and serves the file directly. Assets are version-aware, so each content branch can have its own set of files.
The path inside the tag is relative to the repo root and must start with assets/.
Per-customer asset delivery
Combine \{\{asset\}\} with template conditionals to show different downloads to different customers:
## Resources
{{#ifEquals customer.name "Acme Corp"}}
- [Acme Deployment Guide]({{asset "assets/acme-deploy-guide.pdf"}})
- [Acme ArgoCD Values]({{asset "assets/acme-argocd-values.yaml"}})
{{/ifEquals}}
{{#ifEquals customer.name "Globex"}}
- [Globex CloudFormation Template]({{asset "assets/globex-cloudformation.yaml"}})
{{/ifEquals}}
{{#if entitlements.isAWSEnabled}}
- [AWS Deployment Script]({{asset "assets/deploy-aws.sh"}})
{{/if}}
- [Onboarding Checklist]({{asset "assets/onboarding-checklist.pdf"}})
This lets you maintain one content repo with assets for all customers. Each customer only sees the downloads that apply to them. Unconditioned assets (like the onboarding checklist) appear for everyone.
This pattern works for any file type: Terraform modules, Argo manifests, Bicep templates, CloudFormation stacks, bash scripts, PDFs, or configuration templates.