Configuration
BugDrop is configured entirely through data attributes on the script tag. No JavaScript configuration object, no external config file -- just HTML attributes. This page covers every available attribute.
Core Attributes
These attributes control the fundamental behavior of the widget.
| Attribute | Default | Description |
|---|---|---|
data-repo |
(required) | GitHub repository in owner/repo format |
data-theme |
"auto" |
Widget theme: "light", "dark", or "auto" |
data-position |
"bottom-right" |
Button position: "bottom-right" or "bottom-left" |
data-color |
"#14b8a6" |
Primary accent color (any CSS color value) |
data-icon |
(default bug icon) | Custom icon: URL to an image, "none" to hide, or omit for default |
data-label |
"Feedback" |
Text label displayed next to the button icon |
data-category-labels |
built-in labels | Self-hosted JSON mapping from built-in categories to GitHub labels |
data-button |
"true" |
Show the floating button: "true" or "false" |
data-welcome |
"Report a bug or request a feature" |
Welcome message displayed at the top of the form |
data-show-issue-link |
"public" |
Show the GitHub issue link after submission: "public", "always", or "never" |
Basic Example
<script
src="https://bugdrop.neonwatty.workers.dev/widget.js"
data-repo="acme-corp/my-app"
data-theme="dark"
data-position="bottom-left"
data-color="#ef4444"
data-welcome="Found a bug? Let us know!"
></script>
Theme Options
The data-theme attribute controls the overall color scheme of the widget:
auto(default) -- Follows the user's system color scheme.light-- White background with dark text. Suitable for most sites.dark-- Dark background with light text. Ideal for sites with dark color schemes.
<!-- Auto theme (default) -->
<script src="https://bugdrop.neonwatty.workers.dev/widget.js"
data-repo="owner/repo" data-theme="auto"></script>
<!-- Light theme -->
<script src="https://bugdrop.neonwatty.workers.dev/widget.js"
data-repo="owner/repo" data-theme="light"></script>
<!-- Dark theme -->
<script src="https://bugdrop.neonwatty.workers.dev/widget.js"
data-repo="owner/repo" data-theme="dark"></script>
Position Options
The data-position attribute controls where the floating button appears:
bottom-right(default) -- Anchored to the right edgebottom-left-- Anchored to the left edge
The button is shown as an edge label with a small drag handle. Users can drag it vertically when it covers page content, and BugDrop remembers that position in the browser for the same repository and side.
Issue Link Visibility
Control whether the success confirmation links to the GitHub Issue that was created.
| Value | Behavior |
|---|---|
"public" |
Default. Show the issue number and GitHub link for public repositories only. Private repository submissions use a generic success message. |
"always" |
Show the issue number and GitHub link whenever the server returns an issue URL, including private repositories. Use this only for trusted internal users who already have GitHub access to the target repository. |
"never" |
Show the issue number for public repositories, but do not show a GitHub link. Private repository submissions use a generic success message. |
<!-- Show private repository issue links to trusted internal users -->
<script
src="https://bugdrop.neonwatty.workers.dev/widget.js"
data-repo="owner/private-repo"
data-show-issue-link="always"
></script>
Submitter Information
Control whether the feedback form collects the submitter's name and email address.
| Attribute | Default | Description |
|---|---|---|
data-show-name |
"false" |
Show the name field in the form |
data-require-name |
"false" |
Make the name field required (implies data-show-name="true") |
data-show-email |
"false" |
Show the email field in the form |
data-require-email |
"false" |
Make the email field required (implies data-show-email="true") |
Submitter Info Example
<!-- Show both name and email, require email only -->
<script
src="https://bugdrop.neonwatty.workers.dev/widget.js"
data-repo="owner/repo"
data-show-name="true"
data-show-email="true"
data-require-email="true"
></script>
When submitter information is collected, it is included in the GitHub Issue body so your team knows who reported the issue.
Dismissible Button
Allow users to dismiss the floating button so it does not obstruct their view. This is especially useful for content-heavy sites where the button might overlay important elements.
| Attribute | Default | Description |
|---|---|---|
data-button-dismissible |
"false" |
Allow users to dismiss (hide) the floating button |
data-dismiss-duration |
Forever | How long the button stays dismissed: omit for forever, or provide a number of days (e.g., "7") |
data-show-restore |
"true" |
Show a small restore link after dismissing |
Dismissible Button Example
<!-- Dismissible button that stays hidden for 7 days -->
<script
src="https://bugdrop.neonwatty.workers.dev/widget.js"
data-repo="owner/repo"
data-button-dismissible="true"
data-dismiss-duration="7"
data-show-restore="true"
></script>
When a user dismisses the button:
- The floating button hides
- If
data-show-restoreis"true", a small "Restore feedback button" link appears in the corner - The button stays hidden for the duration specified by
data-dismiss-duration - After the duration expires, the button reappears automatically
Feedback Categories
Users can choose from three feedback categories when submitting a report. By default, each category maps to a specific GitHub label:
| Category | Emoji | GitHub Label | Description |
|---|---|---|---|
| Bug | :beetle: | bug |
Something is not working correctly |
| Feature | :sparkles: | enhancement |
A new feature or improvement request |
| Question | :question: | question |
A question about the product or usage |
These categories are built into the widget. Self-hosted deployments can customize which GitHub labels each category applies. There are two configuration paths:
Server-side mapping (recommended)
Set CATEGORY_LABELS on your worker. The mapping is authoritative — clients cannot override it. Two shapes are supported:
Flat shape — same labels for every repo your worker serves:
{
"bug": ["defect", "frontend"],
"feature": "product-feedback",
"question": "support"
}
Per-repo shape — different labels per repo, with an optional "*" wildcard fallback:
{
"acme-corp/my-app": {
"bug": ["defect", "frontend"],
"feature": "product-feedback"
},
"acme-corp/docs": {
"bug": "docs-bug"
},
"*": {
"bug": "triage"
}
}
The shape is detected automatically: keys containing / or equal to * mean per-repo; otherwise it's treated as flat.
Client-side mapping (self-hosts only, opt-in)
Self-hosted deployments can also let pages set labels via the data-category-labels attribute. This is disabled by default because it lets any page that loads your worker dictate which labels appear on issues. Enable it by setting ALLOW_CLIENT_CATEGORY_LABELS to the literal string "true" (case-sensitive — values like "True", "1", or "yes" keep the gate closed):
<script
src="https://bugdrop.neonwatty.workers.dev/widget.js"
data-repo="acme-corp/my-app"
data-category-labels='{"bug":["defect","frontend"],"feature":"product-feedback","question":"support"}'
></script>
Only enable this when your worker's ALLOWED_ORIGINS is locked down to trusted domains.
Rules and behavior
- Recognized keys:
bug,feature,question. Other keys are ignored with a warning. - Each category accepts a single label string or an array of 1-5 strings; each label must be 1-50 characters after trimming (GitHub's limit). Labels containing control characters are rejected.
- Every issue also receives the
bugdroplabel (always added). - Precedence: when both server and client mappings are present,
CATEGORY_LABELSwins. - Fail-closed on misconfig: if
CATEGORY_LABELSis set but unusable (malformed JSON, wrong shape, or a per-repo map with no entry for the current repo and no"*"fallback), the worker uses default labels and emits a warning — it does not silently fall back todata-category-labels. This keeps a typo from handing label control back to the browser. - GitHub rejection retry: if GitHub rejects a configured label (e.g. it doesn't exist in the repo), BugDrop retries once with default labels and embeds a label-mapping warning in the issue body.
- Warnings in the response: if any warnings were emitted, the
/feedbackJSON success response includes alabelMappingWarnings: string[]field so callers can surface configuration issues programmatically.
Troubleshooting
| Symptom | Likely cause |
|---|---|
Issues are filed with default labels (bug, enhancement, question) instead of yours |
CATEGORY_LABELS JSON is malformed, the shape is wrong, or the per-repo map has no entry for this repo and no "*" fallback. Check the issue body for a ## Label mapping warning section, or the worker logs for [BugDrop] Category label config warnings. |
data-category-labels is ignored |
ALLOW_CLIENT_CATEGORY_LABELS is unset or not exactly the string "true". Or CATEGORY_LABELS is also set, in which case it always wins. |
| Some categories take effect but others don't | Unknown category keys (anything other than bug/feature/question) are dropped with a warning. Check spelling. |
| GitHub returns a 422 | A configured label doesn't exist in the repo. BugDrop retries with default labels automatically; the issue still gets created and the rejection is recorded in the body. |
Automatic System Information
Every feedback submission automatically captures the following system information, with no configuration required:
| Field | Example | Description |
|---|---|---|
| Browser | Chrome 120.0.0.0 |
Browser name and version |
| OS | macOS 14.2.1 |
Operating system and version |
| Viewport | 1920x1080 |
Browser window dimensions |
| Language | en-US |
Browser language setting |
| URL | https://example.com/page |
Current page URL |
This information is included in every GitHub Issue body under a "System Info" section, giving your team the context they need to reproduce and fix bugs.
Screenshot Behavior
Control how screenshots are collected during the feedback flow.
| Attribute | Default | Description |
|---|---|---|
data-screenshot |
"optional" |
Screenshot mode: "optional", "auto", or "required" |
data-screenshot-scale |
"2" |
Minimum pixel ratio for screenshot captures |
data-element-context-max-area |
"0" |
Maximum surrounding container size for Select Element captures, expressed as a multiple of the visible viewport area |
Screenshot Modes
optional-- Shows the screenshot checkbox checked by default. Users can choose full page, element, area, annotate, redact, or skip.auto-- Automatically captures a full-page screenshot after the form is submitted, without showing the manual screenshot picker or redaction step.required-- Requires a screenshot before submission. Users can choose full page, element, or area, then annotate or redact before submitting.
Manual redaction is controlled by the person submitting feedback. Use developer-configured masking for fields that should be visually covered in supported screenshot modes, especially with automatic screenshots. Auto mode warns users that a full-page screenshot will be attached, but it does not show the manual picker or annotation review step.
Select Element screenshots
When a user chooses Select Element, BugDrop captures the selected element and draws a rounded border around it. The border is drawn with a small 2px inner gap so it does not sit directly on top of the selected element. This keeps the default behavior tight and predictable.
The highlight uses the same styling controls as the widget:
data-colorcontrols the highlight color.data-radiuscontrols the rounded corners.data-border-widthcontrols the highlight border thickness.
GitHub issues include a screenshot caption that identifies the selected element border and includes the exact resolved highlight color.
Selected-element reports also include CSS selector metadata for the chosen element, including a full CSS path. Avoid putting secrets, customer identifiers, or other private data in DOM IDs or class names if issue visibility is broader than your internal team.
The amount of surrounding context is controlled by one attribute:
<script
src="https://bugdrop.neonwatty.workers.dev/widget.js"
data-repo="owner/repo"
data-element-context-max-area="1.5"
></script>
- Omit
data-element-context-max-area, or set it to"0", to capture only the selected element. - Increase
data-element-context-max-areato allow larger surrounding containers. This can provide more context for triage and AI-assisted review, but may create larger images and slower captures.
Select Element captures are capped at 1x pixel ratio even when data-screenshot-scale is higher. This keeps context screenshots small enough for practical issue uploads.
The screenshot review step also links to this configuration section when a Select Element screenshot is being reviewed, so teams can discover the context setting during testing.
Developer-configured screenshot masking
BugDrop can visually mask fields that your app marks as private before a screenshot is uploaded:
<input data-bugdrop-redact value="sk_live_..." />
<section data-bugdrop-mask>Private account details</section>
Supported attributes:
data-bugdrop-redactdata-bd-redactdata-bugdrop-redacteddata-bugdrop-mask
This is best-effort visual masking, not a data-loss-prevention or security boundary. BugDrop can only mask content it can measure in the page DOM. Unmarked sensitive information can still appear, and browser rendering limits can apply to canvas, image, video, iframe, SVG, shadow DOM, pseudo-element, and highly custom control content.
Selected-area screenshots are rendered to the selected dimensions and masks are translated into that crop, but the capture still runs client-side against the page DOM. Avoid screenshots entirely for pages where client-side screenshot rendering is unacceptable.
<!-- Automatically attach a full-page screenshot -->
<script
src="https://bugdrop.neonwatty.workers.dev/widget.js"
data-repo="owner/repo"
data-screenshot="auto"
></script>
<!-- Require a screenshot before submitting feedback -->
<script
src="https://bugdrop.neonwatty.workers.dev/widget.js"
data-repo="owner/repo"
data-screenshot="required"
></script>
Custom Icon and Label
Custom Icon
The data-icon attribute lets you replace the default bug icon with your own:
<!-- Use a custom icon image -->
<script
src="https://bugdrop.neonwatty.workers.dev/widget.js"
data-repo="owner/repo"
data-icon="https://example.com/my-icon.svg"
></script>
<!-- Hide the icon entirely -->
<script
src="https://bugdrop.neonwatty.workers.dev/widget.js"
data-repo="owner/repo"
data-icon="none"
data-label="Feedback"
></script>
When using a custom icon URL, the image is displayed at 24x24 pixels inside the button. SVG format is recommended for best quality at all screen densities.
Custom Label
The data-label attribute adds a text label next to the button icon:
<!-- Icon + label -->
<script
src="https://bugdrop.neonwatty.workers.dev/widget.js"
data-repo="owner/repo"
data-label="Report Bug"
></script>
<!-- Label only (no icon) -->
<script
src="https://bugdrop.neonwatty.workers.dev/widget.js"
data-repo="owner/repo"
data-icon="none"
data-label="Send Feedback"
></script>
API-Only Mode
Set data-button="false" to hide the floating button entirely. This is useful when you want to trigger the widget from your own UI elements using the JavaScript API:
<script
src="https://bugdrop.neonwatty.workers.dev/widget.js"
data-repo="owner/repo"
data-button="false"
></script>
In API-only mode, the widget loads but no button appears. Use window.BugDrop.open() to show the feedback form programmatically. See the JavaScript API documentation for details.
Complete Configuration Example
Here is a script tag using many configuration options together:
<script
src="https://bugdrop.neonwatty.workers.dev/widget.js"
data-repo="acme-corp/my-app"
data-theme="dark"
data-position="bottom-left"
data-color="#6366f1"
data-welcome="We'd love to hear from you!"
data-show-name="true"
data-show-email="true"
data-require-email="true"
data-button-dismissible="true"
data-dismiss-duration="7"
data-show-restore="true"
data-label="Feedback"
></script>
This configuration creates a dark-themed widget in the bottom-left corner with an indigo accent color, collects the submitter's name and email (email required), and shows a "Feedback" label on the button. The button is dismissible for 7 days with a restore link.
Next Steps
- Style the widget with custom fonts, colors, borders, and shadows
- Use the JavaScript API for programmatic control
- Pin to a specific version for production stability