Docusaurus has dark mode built in. Your docs adapt. Your code blocks adapt.
Your screenshots don't.
You know the look - a crisp white UI screenshot glowing in the middle of someone's dark mode docs. Jarring.
The Workaround Nobody Wants to Do
You could maintain two versions of every screenshot. Light and dark. Then write custom React components to toggle between them based on color scheme. CSS media queries, theme context hooks, the works.
Or:
npm install heroshot
How It Works
Heroshot has a Docusaurus plugin that handles theme switching automatically. One component, zero JavaScript gymnastics.
Add the plugin to your config:
// docusaurus.config.js
const { heroshot } = require('heroshot/plugins/docusaurus');
module.exports = {
plugins: [heroshot()],
// ... rest of config
};
Use it in your MDX:
import { Heroshot } from 'heroshot/docusaurus';
# Getting Started
<Heroshot name="dashboard" alt="Dashboard overview" />
That's it. The component:
- Finds both light and dark variants of your screenshot
- Watches the Docusaurus theme toggle
- Switches images instantly when someone clicks the moon icon
- No page reload. No flash.
Setting Up Screenshots
First, capture them. Run the visual picker:
npx heroshot config
Start your Docusaurus dev server in another terminal. Navigate to it in the heroshot browser. Click elements you want to capture. Name them. Close when done.
Heroshot saves a config file. Then capture everything:
npx heroshot
This generates files like:
static/heroshots/dashboard-light.png
static/heroshots/dashboard-dark.png
Both variants captured automatically.
The Full Setup
Your project structure:
my-docs/
├── docs/
│ └── intro.mdx
├── static/
│ └── heroshots/ # screenshots go here
├── .heroshot/
│ └── config.json
└── docusaurus.config.js
Your heroshot config:
{
"outputDirectory": "static/heroshots",
"browser": {
"deviceScaleFactor": 2
},
"screenshots": []
}
The deviceScaleFactor: 2 gives you retina-quality images. Worth it for docs.
Multiple Viewports
Need mobile and desktop versions?
{
"name": "dashboard",
"url": "https://myapp.com/dashboard",
"viewports": ["mobile", "desktop"]
}
The component generates <picture> elements with media queries. Small screens see the mobile shot, large screens see desktop. Each with proper light/dark variants.
Updating Screenshots
UI changed? One command:
npx heroshot
Every screenshot regenerates. Both color schemes. All viewports. Your docs stay accurate.
How the Theme Detection Works
Docusaurus uses <html data-theme="dark"> when someone toggles dark mode. The component watches this attribute. Light screenshot shows by default, dark version swaps in when the theme changes.
Works with Docusaurus's built-in toggle. Works with any theme that follows the same pattern.
CI Integration
Add it to your build pipeline:
- run: npx heroshot
- run: npm run build
Screenshots update before every deploy. Documentation never goes stale.
heroshot - automatic screenshots for Docusaurus docs.
Top comments (0)