diff --git a/src/content/docs/ci-testing.mdx b/src/content/docs/ci-testing.mdx new file mode 100644 index 0000000..b1c8370 --- /dev/null +++ b/src/content/docs/ci-testing.mdx @@ -0,0 +1,297 @@ +# CI Testing with Playwright + +BugDrop can be tested in your CI/CD pipeline using Playwright. This guide covers everything from a quick verification check to a comprehensive test suite that validates functionality, accessibility, and configuration. + +## Quick Check + +The fastest way to verify BugDrop is loading correctly is to check for its console message. When the widget initializes successfully, it logs: + +``` +[BugDrop] Widget initialized +``` + +You can check for this in a simple Playwright test: + +```typescript +import { test, expect } from '@playwright/test'; + +test('BugDrop loads', async ({ page }) => { + const messages: string[] = []; + page.on('console', (msg) => messages.push(msg.text())); + + await page.goto('https://your-site.com'); + await page.waitForTimeout(2000); + + expect(messages.some((m) => m.includes('[BugDrop]'))).toBe(true); +}); +``` + +## Full Playwright Test Suite + +Here is a comprehensive test file that validates BugDrop's functionality, accessibility (WCAG AA compliance), and configuration. You can copy this directly into your project: + +```typescript +import { test, expect } from "@playwright/test"; + +// ── EXPECTED configuration ────────────────────────────────────── +// Update these values to match YOUR script tag's data-* attributes. +const EXPECTED = { + theme: "light", + position: "bottom-right", + color: "#7c3aed", + showName: false, + requireName: false, + showEmail: false, + requireEmail: false, + buttonDismissible: false, + showRestore: true, + welcomeMessage: "Report a bug or request a feature", +}; + +const URL = "https://your-site.com"; // Replace with your site URL + +// ── Helper: reach into the Shadow DOM ─────────────────────────── +async function shadowEl(page, hostSel: string, innerSel: string) { + return page.evaluateHandle( + ([h, s]) => { + const host = document.querySelector(h); + if (!host?.shadowRoot) throw new Error(`No shadow root on ${h}`); + const el = host.shadowRoot.querySelector(s); + if (!el) throw new Error(`${s} not found in shadow DOM`); + return el; + }, + [hostSel, innerSel] + ); +} + +// ── Tests ─────────────────────────────────────────────────────── + +test.describe("BugDrop Widget", () => { + test.beforeEach(async ({ page }) => { + await page.goto(URL); + await page.waitForSelector("bug-drop-widget"); + }); + + test("renders the floating button", async ({ page }) => { + const btn = await shadowEl(page, "bug-drop-widget", ".floating-btn"); + expect(btn).toBeTruthy(); + }); + + test("opens and closes the form", async ({ page }) => { + const btn = await shadowEl(page, "bug-drop-widget", ".floating-btn"); + await (btn as any).click(); + + const form = await shadowEl(page, "bug-drop-widget", ".feedback-form"); + expect(form).toBeTruthy(); + + const closeBtn = await shadowEl(page, "bug-drop-widget", ".close-btn"); + await (closeBtn as any).click(); + }); + + test("has correct position", async ({ page }) => { + const pos = await page.evaluate(() => { + const host = document.querySelector("bug-drop-widget"); + const btn = host?.shadowRoot?.querySelector(".floating-btn"); + if (!btn) throw new Error("Button not found"); + const style = window.getComputedStyle(btn); + return { right: style.right, left: style.left, bottom: style.bottom }; + }); + + if (EXPECTED.position === "bottom-right") { + expect(parseInt(pos.right)).toBeLessThan(100); + } else { + expect(parseInt(pos.left)).toBeLessThan(100); + } + }); + + test("uses correct accent color", async ({ page }) => { + const bgColor = await page.evaluate(() => { + const host = document.querySelector("bug-drop-widget"); + const btn = host?.shadowRoot?.querySelector(".floating-btn"); + if (!btn) throw new Error("Button not found"); + return window.getComputedStyle(btn).backgroundColor; + }); + expect(bgColor).toBeTruthy(); + }); + + test("displays correct welcome message", async ({ page }) => { + const btn = await shadowEl(page, "bug-drop-widget", ".floating-btn"); + await (btn as any).click(); + + const welcomeText = await page.evaluate(() => { + const host = document.querySelector("bug-drop-widget"); + const welcome = host?.shadowRoot?.querySelector(".welcome-message, h2"); + return welcome?.textContent?.trim(); + }); + + expect(welcomeText).toContain(EXPECTED.welcomeMessage); + }); + + test("shows/hides name field based on config", async ({ page }) => { + const btn = await shadowEl(page, "bug-drop-widget", ".floating-btn"); + await (btn as any).click(); + + const nameFieldVisible = await page.evaluate(() => { + const host = document.querySelector("bug-drop-widget"); + const nameField = host?.shadowRoot?.querySelector( + '[name="name"], #name, .name-field' + ); + if (!nameField) return false; + return window.getComputedStyle(nameField).display !== "none"; + }); + + expect(nameFieldVisible).toBe(EXPECTED.showName); + }); + + test("shows/hides email field based on config", async ({ page }) => { + const btn = await shadowEl(page, "bug-drop-widget", ".floating-btn"); + await (btn as any).click(); + + const emailFieldVisible = await page.evaluate(() => { + const host = document.querySelector("bug-drop-widget"); + const emailField = host?.shadowRoot?.querySelector( + '[name="email"], #email, .email-field' + ); + if (!emailField) return false; + return window.getComputedStyle(emailField).display !== "none"; + }); + + expect(emailFieldVisible).toBe(EXPECTED.showEmail); + }); + + // ── Accessibility (WCAG AA) ───────────────────────────────── + test("button meets WCAG AA contrast ratio", async ({ page }) => { + const contrast = await page.evaluate(() => { + function luminance(r: number, g: number, b: number) { + const [rs, gs, bs] = [r, g, b].map((c) => { + c /= 255; + return c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4); + }); + return 0.2126 * rs + 0.7152 * gs + 0.0722 * bs; + } + function parseRgb(color: string) { + const match = color.match(/(\d+)/g); + return match ? match.map(Number) : [0, 0, 0]; + } + + const host = document.querySelector("bug-drop-widget"); + const btn = host?.shadowRoot?.querySelector(".floating-btn"); + if (!btn) return 0; + const style = window.getComputedStyle(btn); + const [r1, g1, b1] = parseRgb(style.backgroundColor); + const bgLum = luminance(r1, g1, b1); + const whiteLum = luminance(255, 255, 255); + const ratio = + (Math.max(bgLum, whiteLum) + 0.05) / + (Math.min(bgLum, whiteLum) + 0.05); + return ratio; + }); + + // WCAG AA requires 4.5:1 for normal text, 3:1 for large text + expect(contrast).toBeGreaterThanOrEqual(3); + }); + + test("form elements are keyboard accessible", async ({ page }) => { + // Open the form + await page.keyboard.press("Tab"); + await page.keyboard.press("Enter"); + + // Verify form opened and is focusable + const formExists = await page.evaluate(() => { + const host = document.querySelector("bug-drop-widget"); + return !!host?.shadowRoot?.querySelector(".feedback-form, form"); + }); + + expect(formExists).toBe(true); + }); +}); +``` + +## Installation and Setup + +To run the tests, you need Playwright installed in your project: + +```bash +# Install Playwright +npm install --save-dev @playwright/test + +# Install browsers +npx playwright install +``` + +Create or update your `playwright.config.ts`: + +```typescript +import { defineConfig } from '@playwright/test'; + +export default defineConfig({ + testDir: './e2e', + timeout: 30000, + use: { + baseURL: 'https://your-site.com', + }, +}); +``` + +Then run the tests: + +```bash +npx playwright test +``` + +## What the Tests Check + +The test suite covers three areas: + +### Functional Tests + +- **Renders the floating button** -- Verifies the widget loads and the button appears in the Shadow DOM +- **Opens and closes the form** -- Clicks the button, verifies the form appears, then closes it +- **Correct position** -- Validates the button is in the expected corner (bottom-right or bottom-left) +- **Correct accent color** -- Checks the button's background color +- **Welcome message** -- Opens the form and verifies the correct welcome text is displayed +- **Name/email field visibility** -- Confirms fields show or hide based on your configuration + +### Accessibility Tests (WCAG AA) + +- **Contrast ratio** -- Calculates the luminance contrast ratio between the button's background color and white text, ensuring it meets WCAG AA standards (3:1 for large text) +- **Keyboard accessibility** -- Verifies the form can be opened and navigated using only the keyboard + +### Configuration Verification + +The `EXPECTED` object at the top of the test file defines your expected configuration. Update it to match your actual `data-*` attributes: + +```typescript +const EXPECTED = { + theme: "light", // data-theme + position: "bottom-right", // data-position + color: "#7c3aed", // data-color + showName: false, // data-show-name + requireName: false, // data-require-name + showEmail: false, // data-show-email + requireEmail: false, // data-require-email + buttonDismissible: false, // data-button-dismissible + showRestore: true, // data-show-restore + welcomeMessage: "Report a bug or request a feature", // data-welcome +}; +``` + +If any of these values do not match what the widget actually renders, the corresponding test will fail -- catching configuration drift between your script tag and your expected behavior. + +## Running in CI + +Add the test to your CI workflow (GitHub Actions example): + +```yaml +- name: Install Playwright + run: npx playwright install --with-deps chromium + +- name: Run BugDrop tests + run: npx playwright test e2e/bugdrop.spec.ts +``` + +## Next Steps + +- [Configure the widget](/docs/configuration) with data attributes +- [Review security and rate limiting](/docs/security) +- [Pin your widget version](/docs/version-pinning) for stable CI runs diff --git a/src/content/docs/configuration.mdx b/src/content/docs/configuration.mdx index fd428db..85407f6 100644 --- a/src/content/docs/configuration.mdx +++ b/src/content/docs/configuration.mdx @@ -1,18 +1,227 @@ # Configuration -BugDrop is configured entirely through `data-*` attributes on the script tag. +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 -| Attribute | Values | Default | -|-----------|--------|---------| -| `data-repo` | `owner/repo` | required | -| `data-theme` | `light`, `dark`, `auto` | `auto` | -| `data-position` | `bottom-right`, `bottom-left` | `bottom-right` | -| `data-welcome` | `once`, `always`, `false`/`never` | `once` | -| `data-color` | Hex color (e.g. `#FF6B35`) | `#14b8a6` | -| `data-button-dismissible` | `true`, `false` | `false` | -| `data-button` | `true`, `false` | `true` | -| `data-label` | Any string | `Feedback` | - -See [Styling](/docs/styling) for visual customization options. +These attributes control the fundamental behavior of the widget. + +| Attribute | Default | Description | +|-----------|---------|-------------| +| `data-repo` | **(required)** | GitHub repository in `owner/repo` format | +| `data-theme` | `"light"` | Widget theme: `"light"` or `"dark"` | +| `data-position` | `"bottom-right"` | Button position: `"bottom-right"` or `"bottom-left"` | +| `data-color` | `"#7c3aed"` | 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` | `""` | Text label displayed next to the button icon | +| `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 | + +### Basic Example + +```html + +``` + +### Theme Options + +The `data-theme` attribute controls the overall color scheme of the widget: + +- **`light`** (default) -- White background with dark text. Suitable for most sites. +- **`dark`** -- Dark background with light text. Ideal for sites with dark color schemes. + +```html + + + + + +``` + +### Position Options + +The `data-position` attribute controls where the floating button appears: + +- **`bottom-right`** (default) -- Fixed to the bottom-right corner +- **`bottom-left`** -- Fixed to the bottom-left corner + +## 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 + +```html + + +``` + +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` | `"session"` | How long the button stays dismissed: `"session"` (until tab close) or a number in minutes (e.g., `"60"`) | +| `data-show-restore` | `"true"` | Show a small restore link after dismissing | + +### Dismissible Button Example + +```html + + +``` + +When a user dismisses the button: + +1. The floating button hides +2. If `data-show-restore` is `"true"`, a small "Restore feedback button" link appears in the corner +3. The button stays hidden for the duration specified by `data-dismiss-duration` +4. After the duration expires (or the session ends), the button reappears automatically + +## Feedback Categories + +Users can choose from three feedback categories when submitting a report. 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 and cannot be customized at this time. The corresponding GitHub labels are created automatically in your repository if they do not already exist. + +## 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. + +## Custom Icon and Label + +### Custom Icon + +The `data-icon` attribute lets you replace the default bug icon with your own: + +```html + + + + + +``` + +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: + +```html + + + + + +``` + +## 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](/docs/javascript-api): + +```html + +``` + +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](/docs/javascript-api) for details. + +## Complete Configuration Example + +Here is a script tag using many configuration options together: + +```html + +``` + +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 2 hours with a restore link. + +## Next Steps + +- [Style the widget](/docs/styling) with custom fonts, colors, borders, and shadows +- [Use the JavaScript API](/docs/javascript-api) for programmatic control +- [Pin to a specific version](/docs/version-pinning) for production stability diff --git a/src/content/docs/faq.mdx b/src/content/docs/faq.mdx index 90042fb..f2b5a13 100644 --- a/src/content/docs/faq.mdx +++ b/src/content/docs/faq.mdx @@ -1,21 +1,213 @@ -# FAQ +# Frequently Asked Questions -## Does BugDrop work with private repositories? +Answers to the most common questions about BugDrop. If your question is not covered here, open an issue on the [GitHub repository](https://github.com/mean-weasel/bugdrop/issues). -Yes. The GitHub App works with both public and private repositories. +## General -## Is any data stored on your servers? +### What is BugDrop? -Screenshots are uploaded as part of the GitHub issue creation process and stored on GitHub, not on BugDrop servers. +BugDrop is a lightweight, open-source bug reporting widget that you add to your website with a single script tag. When users encounter a bug, they click the floating button, fill out a simple form, and the report is automatically created as a GitHub Issue in your repository -- complete with a screenshot and system information. -## Does BugDrop use cookies or tracking? +### How does BugDrop work? -No. BugDrop uses no cookies, no tracking, and no analytics. URLs in bug reports are automatically redacted. +BugDrop works in three steps: -## Can I customize the widget's appearance? +1. **User clicks the button** -- A floating button appears on your site. Clicking it opens a feedback form rendered inside a Shadow DOM. +2. **User submits feedback** -- The user fills in a title, description, selects a category (Bug, Feature, or Question), and optionally attaches a screenshot. System info (browser, OS, viewport, language, URL) is captured automatically. +3. **GitHub Issue created** -- The form submission is sent to a Cloudflare Worker API, which creates a GitHub Issue in your repository with all the details, labels, and screenshot. -Yes. BugDrop supports extensive [styling customization](/docs/styling) through `data-*` attributes. +### Is BugDrop free? -## What browsers are supported? +Yes. BugDrop is completely free and open source under the [MIT License](https://github.com/mean-weasel/bugdrop/blob/main/LICENSE). There are no paid tiers, usage limits (beyond rate limiting), or premium features. You can use it on personal projects, commercial products, and enterprise applications without restriction. -BugDrop works in all modern browsers (Chrome, Firefox, Safari, Edge). It uses Shadow DOM for style isolation. +### Is BugDrop free for commercial use? + +Yes. The MIT License permits commercial use, modification, distribution, and private use. You can use BugDrop on commercial websites, SaaS products, and internal tools without paying any fees or attributing the project (though attribution is appreciated). + +### Does BugDrop work with React, Next.js, Vue, and other frameworks? + +Yes. BugDrop is a plain JavaScript widget loaded via a ` + + + +``` + +Each site sends feedback to its own repository. There is no limit to the number of repositories you can use BugDrop with. + +### How do I remove BugDrop? + +To completely remove BugDrop: + +1. **Remove the script tag** from your HTML. This immediately stops the widget from appearing on your site. +2. **Uninstall the GitHub App** (optional) -- Go to GitHub Settings > Applications > Installed GitHub Apps and uninstall the BugDrop app. This revokes all permissions. +3. **Delete the screenshots branch** (optional) -- Delete the `bugdrop-screenshots` branch from your repository to remove stored screenshots. + +Removing the script tag is all that is needed to stop BugDrop from appearing. Steps 2 and 3 are optional cleanup. + +### Why can't I use async or defer on the script tag? + +BugDrop needs to initialize synchronously to ensure the widget is ready as early as possible and to properly read its configuration from the script tag's data attributes. Using `async` or `defer` can cause the widget to initialize after other scripts have run, which may lead to race conditions with the `bugdrop:ready` event or the `window.BugDrop` API. + +## Configuration + +### Does BugDrop support custom labels? + +Yes. The `data-label` attribute adds a text label next to the button icon: + +```html + +``` + +You can also set `data-icon="none"` to show only the text label without an icon: + +```html + +``` + +### Can I customize the feedback categories? + +The three categories (Bug, Feature Request, and Question) are built into the widget and cannot currently be customized through data attributes. Each category maps to a GitHub label (`bug`, `enhancement`, and `question` respectively). If you need custom categories, consider [self-hosting](/docs/self-hosting) and modifying the widget source code. + +### Can I collect the user's name and email? + +Yes. By default, the name and email fields are hidden. Enable them with data attributes: + +```html + + +``` + +When enabled, the submitter's name and email are included in the GitHub Issue body. + +## Rate Limiting and Errors + +### What happens if the API is rate limited? + +When a rate limit is exceeded, the API returns an HTTP `429 Too Many Requests` response with a `Retry-After` header indicating how many seconds to wait. The widget displays a user-friendly message telling the user to try again later. + +Rate limits are: + +| Scope | Limit | Window | +|-------|-------|--------| +| Per IP | 10 requests | 15 minutes | +| Per Repository | 50 requests | 1 hour | + +These limits are designed to be invisible to legitimate users while preventing automated abuse. If you need higher limits, consider [self-hosting](/docs/self-hosting). + +### What if the GitHub API is down? + +If the GitHub API is unavailable when a user submits feedback, the BugDrop API will return an error and the widget will display a message asking the user to try again later. Submissions are not queued or retried automatically -- the user must resubmit after the issue is resolved. + +## Privacy and Security + +### Does BugDrop track users? + +No. BugDrop does not set cookies, use local storage for tracking, send analytics, or fingerprint users. The only data sent to the server is the feedback form contents (title, description, category, optional screenshot, optional name/email, and automatically captured system information). This data goes directly to your GitHub repository and is not stored anywhere else. + +### Where is my data stored? + +All data is stored in your GitHub repository: + +- **Issues** are created as GitHub Issues with labels and formatted bodies +- **Screenshots** are committed to the `bugdrop-screenshots` branch in a `.bugdrop/` directory + +No data is stored on the Cloudflare Worker. The API is stateless -- it receives the form submission, creates the GitHub Issue, and discards the data. + +### Can I self-host BugDrop? + +Yes. BugDrop can be self-hosted on your own Cloudflare Workers account with your own GitHub App. This gives you full control over the infrastructure, credentials, and rate limits. See the [Self-Hosting](/docs/self-hosting) page for an overview and the [SELF_HOSTING.md](https://github.com/mean-weasel/bugdrop/blob/main/SELF_HOSTING.md) file in the repository for full instructions. + +## Troubleshooting + +### The widget is not appearing on my site + +Check the following: + +1. **Verify the script tag** -- Make sure it does not have `async` or `defer` attributes +2. **Check the console** -- Open your browser's developer console and look for `[BugDrop]` messages or errors +3. **Check CSP** -- If your site uses a Content Security Policy, make sure `https://bugdrop.neonwatty.workers.dev` and `https://cdn.jsdelivr.net` are allowed in `script-src` +4. **Check the repo** -- Ensure `data-repo` matches your GitHub repository path exactly (case-sensitive) +5. **Check app installation** -- Verify the BugDrop GitHub App is installed on the repository + +### Issues are not being created + +If the widget appears but submissions fail: + +1. **Check the GitHub App** -- Make sure it is installed on the correct repository with Issues and Contents permissions +2. **Check rate limits** -- You may have hit the per-IP or per-repository rate limit +3. **Check the console** -- Look for error messages in the browser developer console +4. **Check the network tab** -- Inspect the API request to see the response status and body + +### Screenshots are not being uploaded + +If issues are created but without screenshots: + +1. **Check branch protection** -- The GitHub App needs permission to push to the `bugdrop-screenshots` branch. See the [Installation](/docs/installation) page for details on branch protection configuration. +2. **Check CSP** -- The html2canvas library is loaded from `cdn.jsdelivr.net`. Make sure it is allowed by your Content Security Policy. +3. **Cross-origin content** -- html2canvas cannot capture cross-origin iframes or images loaded without CORS headers. These elements may appear blank in the screenshot. + +## Still Have Questions? + +- Browse the [GitHub Issues](https://github.com/mean-weasel/bugdrop/issues) for existing discussions +- Open a new issue on the [GitHub repository](https://github.com/mean-weasel/bugdrop/issues/new) +- Read the full [README](https://github.com/mean-weasel/bugdrop/blob/main/README.md) for additional details diff --git a/src/content/docs/getting-started.mdx b/src/content/docs/getting-started.mdx new file mode 100644 index 0000000..5cfd97b --- /dev/null +++ b/src/content/docs/getting-started.mdx @@ -0,0 +1,83 @@ +# Getting Started with BugDrop + +BugDrop is a lightweight, open-source bug reporting widget that lets your users submit bugs, feature requests, and questions directly from your website — straight into GitHub Issues. No backend to manage, no dashboard to maintain, and no third-party accounts for your users to create. Just a single script tag and you're up and running. + +## How It Works + +BugDrop operates in three simple steps, creating a seamless bridge between your users and your GitHub repository: + +### Step 1: User Clicks the Bug Button + +A small, customizable floating button appears on your site. When a user clicks it, a clean feedback form opens -- right inside the page, wrapped in a Shadow DOM so it never interferes with your site's styles. + +### Step 2: User Submits Feedback + +The user fills out the form with a title, description, and optional screenshot. They choose a category -- Bug, Feature Request, or Question -- and hit submit. BugDrop automatically captures system information like browser type, operating system, viewport size, language, and current URL. + +### Step 3: GitHub Issue Created + +BugDrop sends the report to your Cloudflare Worker API, which creates a GitHub Issue in your repository. Screenshots are committed to a dedicated `bugdrop-screenshots` branch, and the issue is labeled and formatted with all the context your team needs. + +That is it. No servers to run, no databases to manage, no user accounts required. + +## Why BugDrop? + +| Feature | BugDrop | Traditional Bug Trackers | +|---------|---------|--------------------------| +| Setup time | 30 seconds | Hours to days | +| Backend required | No (Cloudflare Workers) | Yes | +| User accounts | None required | Usually required | +| Where issues live | GitHub Issues | Separate dashboard | +| Cost | Free | Often paid | +| Customizable | Fully | Limited | +| Open source | Yes (MIT) | Rarely | + +## Key Features + +- **One-line installation** -- Add a single script tag and BugDrop is live on your site +- **Automatic screenshots** -- Users can attach screenshots captured client-side with html2canvas +- **System info capture** -- Browser, OS, viewport, language, and URL are automatically included +- **GitHub-native** -- Issues land directly in your repository with proper labels and formatting +- **Shadow DOM isolation** -- The widget never conflicts with your site's CSS +- **Fully customizable** -- Colors, position, icons, labels, themes, and more +- **JavaScript API** -- Programmatic control for advanced integrations +- **Version pinning** -- Pin to major, minor, or patch versions for stability +- **Rate limiting** -- Built-in protection against abuse +- **Privacy-first** -- No user data stored on external servers + +## Quick Links + +Ready to get started? Here is where to go next: + +- **[Installation](/docs/installation)** -- Step-by-step setup guide to add BugDrop to your site +- **[Configuration](/docs/configuration)** -- All widget attributes for customizing behavior +- **[Styling](/docs/styling)** -- Theme your widget with colors, fonts, borders, and shadows +- **[JavaScript API](/docs/javascript-api)** -- Programmatic control with `window.BugDrop` +- **[Version Pinning](/docs/version-pinning)** -- Lock to specific versions for production stability +- **[CI Testing](/docs/ci-testing)** -- Automated testing with Playwright +- **[Security](/docs/security)** -- Permissions, data storage, privacy, and rate limiting +- **[Self-Hosting](/docs/self-hosting)** -- Run your own BugDrop instance +- **[FAQ](/docs/faq)** -- Common questions answered + +## Requirements + +BugDrop works with any website. There are no framework dependencies, no build step required, and no npm packages to install. All you need is: + +1. A **GitHub repository** where issues will be created +2. The **BugDrop GitHub App** installed on that repository +3. A **script tag** added to your HTML + +BugDrop supports all modern browsers including Chrome, Firefox, Safari, and Edge. The widget is built with vanilla JavaScript and Web Components, so it works alongside React, Next.js, Vue, Svelte, Angular, or any other framework -- or no framework at all. + +## Example + +Here is the simplest possible BugDrop installation: + +```html + +``` + +That single script tag gives your users a fully functional bug reporting widget. From there, you can customize everything -- read the [Configuration](/docs/configuration) and [Styling](/docs/styling) docs to make it your own. diff --git a/src/content/docs/installation.mdx b/src/content/docs/installation.mdx index 2a47282..2765a85 100644 --- a/src/content/docs/installation.mdx +++ b/src/content/docs/installation.mdx @@ -1,21 +1,163 @@ # Installation -Get BugDrop running on your site in under a minute. +Getting BugDrop running on your site takes about 30 seconds. There are only two steps: install the GitHub App and add a script tag. No npm packages, no build configuration, no backend setup required. ## Step 1: Install the GitHub App -Install the [BugDrop GitHub App](https://github.com/apps/neonwatty-bugdrop/installations/new) on the repository where you want issues created. +BugDrop needs access to your GitHub repository to create issues and store screenshots. Install the official GitHub App to grant these permissions. -The app needs permission to create issues on your behalf. +**[Install BugDrop GitHub App](https://github.com/apps/neonwatty-bugdrop/installations/new)** + +During installation you will be asked which repositories to grant access to. You can choose specific repositories or grant access to all repositories in your account or organization. + +### What permissions does the app request? + +| Permission | Access Level | Purpose | +|-----------|-------------|---------| +| Issues | Read & Write | Create bug reports as GitHub Issues | +| Contents | Read & Write | Store screenshots in the repository | + +These are the minimum permissions required for BugDrop to function. The app does not request access to your code, pull requests, actions, or any other repository data. ## Step 2: Add the Script Tag -Add this to your HTML, replacing `owner/repo` with your GitHub repository: +Add the BugDrop script tag to your HTML, just before the closing `
+ + + + +` tag: + +```html + +``` + +Replace `your-username/your-repo` with your actual GitHub repository path (e.g., `acme-corp/my-website`). + +### Full HTML Example + +```html + + +
+ + +
+ +
+