Running screenshot automation across multiple domains sounds clean until you hit reality.
Your staging site has a #dev-banner. Production has .cookie-consent. The marketing site has a floating chat bubble. Each domain is its own mess.
The obvious fix is a hide action on every screenshot:
{
"name": "user-settings",
"url": "https://app.example.com/settings",
"actions": [
{ "type": "hide", "selector": ".cookie-banner" }
]
}
Fifty screenshots later, .cookie-banner is scattered across your entire config. When the selector changes, you're updating it fifty times.
There's a better way.
One rule, all screenshots
Heroshot has a top-level hiddenElements config that maps domains to CSS selectors:
{
"hiddenElements": {
"app.example.com": [".cookie-banner", "#support-chat"],
"docs.example.com": [".announcement-bar"],
"staging.example.com": ["#dev-banner", ".cookie-banner"]
}
}
These fire automatically for every screenshot on that domain. No per-screenshot setup. The .cookie-banner on app.example.com disappears from all 50 shots the moment you add that one line.
Change selector? One place to update.
Set it up in the editor
Running npx heroshot opens the visual editor. There's an eraser tool in the sidebar — click it, click the element you want hidden, and heroshot adds the domain rule to your config automatically based on the page you're on.
No config editing required.
Works alongside inline hide
Under the hood it's the same mechanism — elements get hidden before the screenshot fires. The difference is just where the rule lives.
You can mix both. Domain-level rules run first, then per-screenshot actions. Hide the global nav at the domain level, hide a specific tooltip only on the one screenshot that needs it.
That's the whole feature. If you're running heroshot across multiple environments or projects, hiddenElements cleans up a lot of noise.
heroshot.sh
Top comments (0)