Skip to content

antora-supplemental/antora-dark-theme

Repository files navigation

Antora Dark Theme

Features

  • Dark mode toggle - A sun/moon icon button in the navbar that switches between light and dark themes

  • System preference detection - Automatically applies dark mode if the user’s OS is set to dark mode

  • Persistent preference - Remembers the user’s choice via localStorage

  • No FOUC (Flash of Unstyled Content) - Dark mode is applied before page render via inline script

  • Non-invasive - Works as a supplemental UI overlay; no need to fork or rebuild the Antora default UI bundle

  • Comprehensive styling - Covers navbar, navigation panels, content area, code blocks, tables, admonition blocks, footer, and more

  • VCS repo logo - Replaces the default UI’s nonfunctional "Download" button with a version-control provider logo (GitHub, GitLab, Bitbucket, Gitea, Codeberg, Forgejo, SourceHut) that links to the docs repository; provider is detected by domain

  • Debranded “doc site” layout - Full supplemental partials and site-doc-layout.css (load after site-extra.css in head-meta): sticky site chrome, doc mast (component/version pickers in the breadcrumb row), sidebar with component label + page tree, optional edit-in-repo link, Source Sans~3, and adt-* BEM-style hooks (not tied to a product name). A neutral img/logo.svg is used in the top bar; override partials/header-content.hbs and point at your own asset for branding.

  • Playbook site.keys (optional site identity): site_home_url (default: docs home site.url), site_home_label (a11y label for the logo link), header_doc_title (navbar text beside the logo; default: site.title), github_profile_url (fallback when the page has no origin URL), footer_note (HTML fragment after the base footer line), title_bar_brand / title_bar_section (see partials/head-title.hbs).

Help Get Dark Mode into Antora

We’ve submitted this theme for inclusion in the official Antora Default UI. If you’d like to see native dark mode support in Antora, please upvote the feature request:

Your support helps the Antora team prioritize this feature!

Quick Start

Which installation path should I use?

  • If your project already uses Node/npm/pnpm (common for Antora sites) — Prefer Method 1 (install from npm). To add your own supplemental files on top of this theme, follow Method 2 (valid Antora patterns only).

  • If you want no JavaScript install step (minimal CI image, or a repo without Node) — Use Method 3 (pre-built ui-bundle.zip): one URL in the playbook, no node_modules.

Install this theme as a dev dependency so the version is tracked with your project.

npm
npm install --save-dev antora-dark-theme
pnpm
pnpm add -D antora-dark-theme
Yarn
yarn add -D antora-dark-theme
Bun
bun add -D antora-dark-theme

Then reference the supplemental UI from node_modules:

ui:
  bundle:
    url: https://gitlab.com/antora/antora-ui-default/-/jobs/artifacts/HEAD/raw/build/ui-bundle.zip?job=bundle-stable
    snapshot: true
  supplemental_files: ./node_modules/antora-dark-theme/supplemental-ui

Method 2: Project overrides (valid Antora options)

Antora’s ui.supplemental_files accepts either a single filesystem directory or an array of virtual files (path + contents). A YAML list of multiple directories is not supported—the array form is only for virtual entries.

Merged directory (recommended when you use npm and need custom partials/CSS): Copy node_modules/antora-dark-theme/supplemental-ui into your repo (for example supplemental-ui/), merge your changes on top, then point the playbook at that one folder:

ui:
  bundle:
    url: https://gitlab.com/antora/antora-ui-default/-/jobs/artifacts/HEAD/raw/build/ui-bundle.zip?job=bundle-stable
    snapshot: true
  supplemental_files: ./supplemental-ui

Pre-built theme bundle + virtual files: Use the release ui-bundle.zip (default UI + dark theme already combined) and add only extra assets with a virtual supplemental_files array:

ui:
  bundle:
    url: https://github.com/antora-supplemental/antora-dark-theme/releases/latest/download/ui-bundle.zip
    snapshot: true
  supplemental_files:
    - path: ui.yml
      contents: |
        static_files:
          - favicon.ico
    - path: favicon.ico
      contents: ./branding/favicon.ico

Virtual override of a single UI file: Each entry must use path and contents (inline or path to a file on disk). If you replace a partial such as partials/head-meta.hbs, your file must still load this theme’s CSS and scripts (start from the theme’s partial), or use a merged directory instead.

ui:
  bundle:
    url: https://gitlab.com/antora/antora-ui-default/-/jobs/artifacts/HEAD/raw/build/ui-bundle.zip?job=bundle-stable
    snapshot: true
  supplemental_files:
    - path: partials/head-meta.hbs
      contents: ./my-supplemental-ui/partials/head-meta.hbs

Method 3: Pre-built UI bundle (no JavaScript toolchain)

Point your Antora playbook at the latest release bundle. This ships the Antora Default UI plus all dark mode enhancements—no npm install.

  1. Configure your antora-playbook.yml:

    ui:
      bundle:
        url: https://github.com/antora-supplemental/antora-dark-theme/releases/latest/download/ui-bundle.zip
        snapshot: true

Method 4: Copy supplemental-ui into your repo

If you want to vendor or heavily customize the dark mode assets, copy the supplemental-ui folder into your project (instead of resolving it from npm).

  1. Copy the folder:

    cp -r supplemental-ui /path/to/your/antora-project/
  2. Point the playbook at your copy, on top of the default UI bundle:

    ui:
      bundle:
        url: https://gitlab.com/antora/antora-ui-default/-/jobs/artifacts/HEAD/raw/build/ui-bundle.zip?job=bundle-stable
        snapshot: true
      supplemental_files: ./supplemental-ui

Live Demo

See the dark theme in action: Live Demo

File Structure

antora-dark-theme/
├── supplemental-ui/
│   ├── css/
│   │   └── site-extra.css      # Dark mode CSS styles
│   ├── js/
│   │   └── site-dark-mode.js   # Toggle button logic and theme management
│   └── partials/
│       ├── footer-scripts.hbs  # Loads the dark mode script
│       └── head-meta.hbs       # Loads CSS and prevents FOUC
├── docs/                        # Demo documentation
│   ├── antora.yml              # Component descriptor
│   └── modules/ROOT/
│       ├── nav.adoc            # Navigation
│       └── pages/              # Sample pages
├── examples/
│   ├── antora-playbook.yml     # Example playbook (npm install)
│   └── antora-playbook-local.yml # Example playbook (direct copy)
├── .github/workflows/
│   └── deploy.yml              # GitHub Pages deployment
├── antora-playbook.yml         # Playbook for demo site (online / CI)
├── antora-playbook-local.yml  # Local playbook (cached assets, no fetch)
├── package.json
├── LICENSE
└── README.adoc

How It Works

This theme uses Antora’s supplemental UI feature to overlay additional files onto the default UI bundle. The approach involves four key files:

1. head-meta.hbs (Prevents Flash of Unstyled Content)

This Handlebars partial is injected into the <head> of every page. It does two things:

  • Loads the site-extra.css stylesheet

  • Runs a tiny inline script that immediately applies the dark-theme class if the user previously selected dark mode or if their OS prefers dark mode

This prevents the brief flash of light mode before the main JavaScript loads.

<link rel="stylesheet" href="{{{uiRootPath}}}/css/site-extra.css">
<script>
(function () {
  const themeKey = 'antora-theme';
  const savedTheme = localStorage.getItem(themeKey);
  if (savedTheme === 'dark' || (!savedTheme && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
    document.documentElement.classList.add('dark-theme');
  }
})();
</script>

This partial is injected at the end of the page body. It loads the main site script, highlight.js, and the dark mode toggle script.

3. site-dark-mode.js (Theme Toggle Logic)

This JavaScript module:

  • Injects a toggle button into the navbar (.navbar-end)

  • Handles click events to switch between light and dark themes

  • Persists the user’s preference in localStorage under the key antora-theme

  • Updates the button icon (sun for dark mode, moon for light mode)

  • Respects the user’s OS preference if no saved preference exists

4. site-extra.css (Dark Mode Styles)

The CSS file contains all dark mode styles using the selector prefix html.dark-theme. This explicit selector approach works because the Antora default UI’s compiled CSS doesn’t rely on CSS custom properties (variables) for theming.

Customization

Changing Colors

Edit supplemental-ui/css/site-extra.css to customize the color palette. The current theme uses these primary colors:

Variable Value Usage

Background (main)

#1a1b1e

Page body background

Background (elevated)

#25262b

Sidebar, navigation panels, blocks

Background (navbar)

#141517

Top navigation bar

Text (primary)

#c1c2c5

Main body text

Text (headings)

#ffffff

Headings and titles

Link color

#4dabf7

Hyperlinks

Link hover

#74c0fc

Hovered hyperlinks

Border color

#373a40

Dividers and borders

Adding More Styles

To style additional elements not covered by the default theme, add new selectors prefixed with html.dark-theme:

html.dark-theme .my-custom-element {
  background-color: #25262b;
  color: #c1c2c5;
}

Changing the Toggle Button Position

By default, the toggle button is inserted at the beginning of .navbar-end. To change its position, modify the ensureToggleButton() function in site-dark-mode.js:

// Insert at the end instead of the beginning
navbarEnd.appendChild(button);

Using a Custom Toggle Button

If you want to use your own toggle button markup, add an element with id="theme-toggle" anywhere in your page. The script will detect it and attach the click handler automatically.

Browser Support

This theme supports all modern browsers:

  • Chrome/Edge (latest)

  • Firefox (latest)

  • Safari (latest)

  • Opera (latest)

The theme uses standard CSS and JavaScript that works in all browsers supporting:

  • localStorage

  • classList

  • matchMedia

Compatibility

Component Version

Antora

3.x

Antora Default UI

Any version (HEAD recommended)

Node.js

18+

Troubleshooting

Dark mode doesn’t persist

Make sure localStorage is available and not blocked by browser settings or extensions. Check the browser console for errors.

Toggle button doesn’t appear

The toggle button is injected into .navbar-end. If your UI bundle has a different structure, you may need to modify the selector in site-dark-mode.js.

Flash of light mode on page load

Ensure head-meta.hbs is being loaded correctly. Check that the inline script isn’t being blocked by a Content Security Policy.

Some elements aren’t styled

The CSS covers the most common Antora elements. If you find unstyled elements, add selectors for them in site-extra.css with the html.dark-theme prefix.

Contributing

Contributions are welcome! Please feel free to submit issues and pull requests.

  1. Fork the repository

  2. Create a feature branch: git checkout -b feature/my-feature

  3. Commit your changes: git commit -m "Add my feature"

  4. Push to the branch: git push origin feature/my-feature

  5. Open a pull request

License

This project is licensed under the MIT License. See the LICENSE file for details.

Acknowledgments

  • The Antora team for creating an excellent documentation site generator

  • The Antora Default UI which this theme extends

  • Fossil SCM — acknowledged as a solid alternative to Git for version control; see the docs for a short discourse and plans for Dev-Centr support

About

Dark UI theme for Antora documentation sites. npm and UI bundle.

Resources

License

Contributing

Stars

Watchers

Forks

Packages

 
 
 

Contributors