Customising
Colours, fonts, where the button sits, your own trigger, and the JavaScript API.
The widget renders in a shadow DOM, so your site's CSS cannot reach into it and
break it, and it cannot leak out and break your site. Everything you can change
is a named custom property or a data- attribute.
Where the button sits
<script async src="https://brokenhere.com/w.js"
data-wq-key="wq_…"
data-wq-position="bottom-left"></script>bottom-right (default), bottom-left, top-right, top-left, or none to
hide the floating button entirely.
Using your own button
<script async src="https://brokenhere.com/w.js"
data-wq-key="wq_…"
data-wq-trigger="#report-a-bug"></script>The value is any CSS selector. Clicking anything that matches opens the
report, including elements added to the page later, because the listener is
delegated. Setting a
trigger hides the floating button unless you also set data-wq-position.
An invalid selector is ignored rather than thrown, because a typo in your snippet must never break the host page.
Theming
Every colour, font and radius is a --wq-* custom property. You can set them
three ways, and each one below beats the one before it:
Defaults
They are set on :host inside the shadow root. Do nothing and you get these.
Your stylesheet
Custom properties inherit through the shadow boundary, so your own CSS can restyle the widget from outside:
[data-wq-root] {
--wq-accent: #2f6b4f;
--wq-font: Inter, sans-serif;
--wq-radius: 4px;
}Script tag attributes
These beat both, which helps when you cannot add CSS:
<script async src="https://brokenhere.com/w.js"
data-wq-key="wq_…"
data-wq-accent="#2f6b4f"
data-wq-accent-fg="#fff"
data-wq-font="Inter, sans-serif"></script>Tokens with a script-tag attribute
| Property | Attribute | Default | What it colours |
|---|---|---|---|
--wq-accent | data-wq-accent | #111 | Button, primary actions, the closing bar |
--wq-accent-fg | data-wq-accent-fg | #fff | Text on the accent |
--wq-timer | data-wq-timer | the accent | The bar that counts down on the confirmation |
--wq-font | data-wq-font | system-ui | Everything |
--wq-radius | data-wq-radius | 8px | Inputs, buttons |
--wq-bg | data-wq-bg | #fff | Panel background |
--wq-fg | data-wq-fg | #111 | Panel text |
Tokens you set from CSS only
| Property | Default | What it colours |
|---|---|---|
--wq-muted | #666 | Secondary text |
--wq-faint | #767676 | "(optional)" labels, hints, the element path |
--wq-border | #d4d4d4 | Input and card borders |
--wq-surface | #fafafa | Thumbnails, the drop zone |
--wq-surface-strong | #f2f2f2 | The context summary block |
--wq-focus | #2563eb | Focus rings, the element highlight |
--wq-danger | #b91c1c | Error messages |
--wq-radius-lg | 14px | The panel itself |
--wq-shadow | 0 12px 40px rgba(0,0,0,.28) | The panel's shadow |
Dark sites
There is deliberately no dark mode setting. A dark site sets the five properties that carry the panel's surfaces:
[data-wq-root] {
--wq-bg: #16161a;
--wq-fg: #f4f4f5;
--wq-surface: #1f1f24;
--wq-surface-strong: #26262c;
--wq-border: #33333a;
}The link under the form
The form ends with one line that is about us rather than the report, Reported with brokenhere.com. The Free plan carries it, and the Team and Agency plans remove it.
There is nothing to set. The widget asks the server what to draw when it boots, and the answer comes from your workspace's plan, so upgrading turns the link off everywhere the key is installed without touching anybody's markup. There is no attribute for it, on purpose, because a switch in the page would be in the hands of whoever had not paid for it. See the pricing page.
The JavaScript API
For anything the attributes do not cover:
window.brokenHere.open(); // open the report form
window.brokenHere.selectElement(); // start the element picker directlyBoth are available as soon as w.js has run. If you call them from a script
that might run first, guard with window.brokenHere?.open().
Confirmation and auto-close
After a report sends, the confirmation closes itself after six seconds, with a bar across the top of the panel draining to show it coming. Hovering the panel pauses it, and clicking anything inside cancels it, so following the status link does not close the panel you opened it from.