This is a sample report. It comes from a real scan of Bugpen — a demo app we built with bugs planted on purpose — run the same way your scans run and shown on the same report page you would get. One thing is changed: Bugpen runs on a test machine, so its address is shown as bugpen.example, a name that goes nowhere. The screenshots and the CSV/JSON export work; the buttons for marking a finding “not a bug” or “won’t fix” are hidden, because no account sits behind this report.
We crawled 11 authenticated pages and scored this site 92/100 (grade A) — needs some attention. We found 6 high-severity issues, 8 mediums, 5 low-severity items. The weakest area is Errors (70/100). Start with: JavaScript console error (2 pages).
How is this score calculated?
Each category is scored by defect density: findings subtract points by severity (high 10 · medium 3 · low 1 · info 0), normalized by the 11 page(s) analyzed so a large healthy site isn't penalized for its size — score = 100·e^(−penalty/page ÷ 10). The overall grade is the priority-weighted average of the category scores (this scan: Errors ×14, Security ×13, Reliability ×12, Interactivity ×11, Forms ×10, Links & navigation ×9, Layout & responsive ×8, Media ×7, Content quality ×5, SEO & metadata ×4, Accessibility ×3)— problems in a high-priority area like Errors weigh more than the same density in a low-priority one. It is a site-health measure, not a certification.
Fix first
5- highJavaScript console error×22 pages: /products/:id, /reports
- highServer error (5xx)×1/reports
- highUncaught JavaScript exception×1/products/:id
- highUnrendered template token×1/settings
- highNever finishes loading×1/reports
What do these severities mean?
- high
- Broken for users right now — fix first.
- medium
- Degrades the experience or blocks some users.
- low
- Minor or cosmetic; fix when convenient.
- info
- Informational only — no action implied, and it does not affect the score.
Findings
19Errors · 4
Things visibly breaking for your users right now — failed requests, crashed scripts, errors surfacing in the browser.
console.error on /products/:id
/products/:id · console-error
console: Failed to load inventory for product 101: Cannot read properties of undefined (reading 'count')
Repro: Log in as the supplied user → Open /products/:id
Show page
Why it matters & how to fix
Why it matters: Console errors often mark a broken feature the user can hit — a failed request, a null reference, a crashed component.
How to fix: Open the page, reproduce the error in devtools, and fix the throwing code or the failing request behind it.
Uncaught error on /products/:id
/products/:id · uncaught-exception
Cannot read properties of undefined (reading 'count')
Repro: Log in as the supplied user → Open /products/:id
Show page
Why it matters & how to fix
Why it matters: An uncaught exception usually crashes the interaction it happened in — the user hits a broken or frozen feature.
How to fix: Reproduce in devtools, follow the stack trace to the throwing line, and add the missing guard or fix the bug.
console.error on /reports
/reports · console-error
console: Reports failed to load: reports-data HTTP 500
Repro: Log in as the supplied user → Open /reports
Show page
Why it matters & how to fix
Why it matters: Console errors often mark a broken feature the user can hit — a failed request, a null reference, a crashed component.
How to fix: Open the page, reproduce the error in devtools, and fix the throwing code or the failing request behind it.
500 from /api/reports-data
/reports · http-5xx
A backend call the page makes returned HTTP 500 (GET /api/reports-data).
- URL
- https://bugpen.example/api/reports-data
- HTTP status
- 500
- Method
- GET
Repro: Log in as the supplied user → Open /reports
Show page
Why it matters & how to fix
Why it matters: A 5xx is a server-side failure — the feature behind it is broken for every user right now.
How to fix: Check the server logs for the failing endpoint and fix the underlying error.
Security · 1
Leads from the opt-in security checks — data that may be readable across accounts. Verify before acting; a lead is not a full audit.
Missing security headers on /
/ · missing-security-headers
The site's responses omit recommended security headers: Content-Security-Policy, X-Frame-Options, X-Content-Type-Options, Referrer-Policy. These defend against clickjacking, MIME-type sniffing, protocol downgrade, and referrer leakage.
- Missing
- Content-Security-Policy, X-Frame-Options, X-Content-Type-Options, Referrer-Policy
Repro: Log in as the supplied user → Open /
Show page
Why it matters & how to fix
Why it matters: These headers are the browser’s frontline defense against clickjacking, MIME-type sniffing, protocol downgrade, and referrer leakage; without them common attacks are easier to land.
How to fix: Set the missing headers at the server/CDN: Content-Security-Policy, X-Frame-Options (or CSP frame-ancestors), X-Content-Type-Options: nosniff, Referrer-Policy, and Strict-Transport-Security over HTTPS.
Reliability · 1
Pages that never finish loading — a user staring at a spinner is a user leaving.
Stuck loading indicator on /reports
/reports · infinite-loadingLikely
A loading indicator ("Loading reports…") is still visible 2.5s after load — the feature never finishes loading.- Label
- Loading reports…
- Element id
- spinner
Repro: Log in as the supplied user → Open /reports
Show page
Why it matters & how to fix
Why it matters: The user stares at a spinner that never resolves — the content or feature is effectively unavailable.
How to fix: Trace the stuck request/state; ensure the loading state resolves (or shows an error) instead of hanging.
Interactivity · 1
Buttons and controls that do nothing when used — features your users are trying and failing to use.
Dead control "Save preferences" on /settings
/settings · dead-controlLikely
Clicking "Save preferences" changed nothing and the control has no click handler bound — it appears dead.
- Name
- Save preferences
- Element id
- save-prefs
Repro: Log in as the supplied user → Open /settings → Click the control "Save preferences"
Show page
Why it matters & how to fix
Why it matters: The user clicks and nothing happens — a silently broken feature that looks functional.
How to fix: Verify the handler runs and performs its action; fix the broken logic or remove the dead control.
Forms · 1
Forms that lose or mishandle input — every one of these can be a lost signup, order, or message.
Validation error never clears on /profile
/profile · validation-never-clears
After correcting the field and resubmitting, the validation error "Enter a valid email." was still shown — the form never clears stale errors.
Enter a valid email.
- Form
- profile-form
Repro: Log in as the supplied user → Open /profile → Submit invalid, correct the field, resubmit
Show page
Why it matters & how to fix
Why it matters: The user fixes their input but the form still shows an error, blocking them from completing the flow.
How to fix: Re-run validation on change/resubmit and clear the error state once the field is valid.
Links & navigation · 2
Dead ends and broken paths — links that 404, redirects that loop, pages that can’t be reached directly.
Dead link on /products
/products · dead-link-404
A link points to /promotions-nonexistent, which returns HTTP 404.
- HTTP status
- 404
Repro: Log in as the supplied user → Open /products → Follow the link to https://bugpen.example/promotions-nonexistent
Show page
Why it matters & how to fix
Why it matters: Users clicking it hit a dead end — a classic broken-navigation defect.
How to fix: Fix or remove the link, or restore the missing target route.
Orphaned page /orphan
/orphan · orphaned-pageLikely
/orphan is reachable but is not linked from anywhere in the app — it was only found via the provided sitemap seed.
- Page URL
- https://bugpen.example/orphan
Repro: Log in as the supplied user → Open /orphan
Show page
Why it matters & how to fix
Why it matters: Users can’t navigate to an unlinked page through the UI, and it may never be discovered organically.
How to fix: Link this page from the relevant navigation or flow, or confirm it’s intentionally unlinked.
Layout & responsive · 2
Pages that render wrong — content overflowing or breaking on phone-sized screens.
Mobile overflow on /pricing
/pricing · responsive-overflow
<div.wide-card> renders 460px wide, overflowing the 375px mobile viewport though it fits on desktop — likely a fixed or min-width, non-responsive element.
- Selector
- div.wide-card
- Breakpoint
- 375
- Element width
- 460
Repro: Log in as the supplied user → Open /pricing
Show page
Why it matters & how to fix
Why it matters: Mobile users get a broken, sideways-scrolling layout — often the majority of real traffic.
How to fix: Add responsive rules (max-width, flex-wrap, media queries) so the layout fits small viewports.
Horizontal overflow on /products
/products · horizontal-overflow
Page content is 970px wider than the 1280px viewport, widest element: <div.overflow-banner>.
- Widest element
- div.overflow-banner
- Overflow past viewport
- 970
- Viewport width
- 1280
Repro: Log in as the supplied user → Open /products
Show location on page
Why it matters & how to fix
Why it matters: Users must scroll sideways to read content — awkward on desktop and broken-feeling on mobile.
How to fix: Find the overflowing element (often a fixed width, large image, or unwrapped text) and constrain it with max-width / wrapping.
Media · 1
Images that fail to load — empty boxes and broken thumbnails make a site look unmaintained.
Broken image on /products
/products · broken-image
An image failed to load (naturalWidth 0): /img/missing.png
- Image src
- https://bugpen.example/img/missing.png
- Alt text
- Featured widget
Repro: Log in as the supplied user → Open /products
Show location on page
Why it matters & how to fix
Why it matters: A broken image shows a placeholder or empty box, making the page look unmaintained.
How to fix: Fix the image URL or restore the missing asset; verify the path resolves for logged-in users.
Content quality · 4
Text that shipped unfinished — placeholder copy, broken characters, untranslated labels.
Unrendered template token on /settings
/settings · unrendered-template-token
Found "{{user_name}}" in the rendered page.- Sample
- {{user_name}}
Repro: Log in as the supplied user → Open /settings
Show page
Why it matters & how to fix
Why it matters: A leaked template token means a binding failed — the user sees code instead of their data.
How to fix: Fix the data binding so the token resolves; verify the variable is populated in this render path.
Untranslated i18n key on /settings
/settings · untranslated-i18n-keyLikely
Found "settings.section.preferences" in the rendered page.
- Sample
- settings.section.preferences
Repro: Log in as the supplied user → Open /settings
Show page
Why it matters & how to fix
Why it matters: A missing translation exposes an internal key to the user — the string was never localized for this locale.
How to fix: Add the missing key to the translation catalog for this locale, or fix the lookup path.
Placeholder text shipped on /settings
/settings · placeholder-lorem
Found "Lorem ipsum dolor sit amet, consectetur adipiscing" in the rendered page.
- Sample
- Lorem ipsum dolor sit amet, consectetur adipiscing
Repro: Log in as the supplied user → Open /settings
Show page
Why it matters & how to fix
Why it matters: Placeholder copy on a live page reads as unfinished and erodes trust in the product.
How to fix: Replace the filler with the real, reviewed copy for this page before it ships.
Encoding corruption (mojibake) on /settings
/settings · mojibake
Found "ferred caf� locale fo" in the rendered page.
- Sample
- ferred caf� locale fo
Repro: Log in as the supplied user → Open /settings
Show page
Why it matters & how to fix
Why it matters: Garbled characters look broken and can make copy unreadable, especially for non-ASCII languages.
How to fix: Serve and store content as UTF-8 end-to-end; ensure the page declares <meta charset="utf-8"> and the DB/API return UTF-8.
SEO & metadata · 1
How your pages present to search engines and social shares — weak metadata costs discovery and click-through.
Duplicate <title> on /reports
/reports · duplicate-title
The document head has 2 <title> elements; there should be exactly one.
- Title count
- 2
Repro: Log in as the supplied user → Open /reports
Show page
Why it matters & how to fix
Why it matters: Duplicate titles hurt search ranking and make browser tabs / bookmarks ambiguous for users.
How to fix: Give each page a unique, descriptive <title> reflecting its specific content.
Accessibility · 1
Barriers for users with disabilities — an inclusion, quality, and legal-exposure issue.
Form control has no label on /profile
/profile · input-missing-label
The control #p-display has no associated label (a placeholder "Display name" is not a label).
- Placeholder text
- Display name
Repro: Log in as the supplied user → Open /profile
Show location on page
Why it matters & how to fix
Why it matters: Screen-reader users can’t tell what to enter, and clicking the label to focus the field doesn’t work.
How to fix: Add a <label for="id"> tied to the field’s id, or an aria-label. A placeholder is not a label.
What we checked — 43 deterministic checks, 18 with issues, 6 public-site only, 25 passed
- ⚠ JavaScript console error (2)
- ⚠ Server error (5xx) (1)
- ⚠ Uncaught JavaScript exception (1)
- ✓ All scripts load
- ✓ No failed requests (4xx)
- ⚠ Missing security response headers (1)
- ✓ No mixed content on HTTPS pages
- ⚠ Never finishes loading (1)
- ⚠ Control does nothing when clicked (1)
- ✓ Create round-trips work
- ✓ Edit round-trips work
- ✓ Every interactive control was exercised
- ⚠ Form error never clears (1)
- ✓ Required fields are enforced
- ⚠ Broken internal link (404) (1)
- ⚠ Orphaned page (no inbound links) (1)
- ✓ External links resolve
- ✓ Redirects resolve cleanly
- ✓ Routes are directly addressable
- ⚠ Horizontal overflow (1)
- ⚠ Mobile layout overflow (1)
- ⚠ Broken image (1)
- ✓ Background images load
- ✓ API calls respond promptly
- ✓ Interactivity is responsive (low Total Blocking Time)
- ✓ Largest Contentful Paint (LCP) is fast
- ✓ Layout is stable (low CLS)
- ⚠ Garbled text (encoding error) (1)
- ⚠ Placeholder (lorem ipsum) text shipped to users (1)
- ⚠ Unrendered template token (1)
- ⚠ Untranslated i18n key (1)
- ⚠ Duplicate page title (1)
- ✓ Every page has a title
- ✓ Mobile viewport is declared
- ○ Canonical link validity — checked on public-site scans only
- ○ Canonical links — checked on public-site scans only
- ○ Meta descriptions — checked on public-site scans only
- ○ Open Graph completeness — checked on public-site scans only
- ○ Open Graph tags — checked on public-site scans only
- ○ Structured data (JSON-LD) validity — checked on public-site scans only
- ⚠ Form field has no label (1)
- ✓ Buttons have accessible names
- ✓ Document language is declared
- ✓ Heading levels are in order
- ✓ Images have alt text
- ✓ Links have accessible names
- ✓ List markup is well-formed
- ✓ Text contrast meets WCAG AA
- ✓ Touch targets are at least 24×24px
How we crawled — 11 page(s), 0 write(s) blocked
This scan is read-only over HTTP: once signed in, every non-GET request the crawl made was aborted by a network guard before it left the browser, not merely avoided. During sign-in itself, requests your own app makes to itself are delivered — its login endpoint is indistinguishable from anything else it sends at that moment — while anything addressed to another host is still refused. “Writes blocked” counts the aborted requests. WebSocket connections are governed too: your app’s own sockets are allowed so live features keep working, and connections to other hosts are refused and included in that count. A socket opened by a Web Worker is refused by the same policy but is not itemised individually.
Coverage sitemap
11Each page nested under the page it was first reached from. “Found on page” is the raw crawl total — it counts duplicates that are collapsed in the list above and findings you dismissed, so it can be higher than the number of cards shown.
| Route | Reached via | Status | Found on page | |
|---|---|---|---|---|
| / | login | 200 | 1 | |
| /changelog | link | 200 | 0 | |
| /help | link | 200 | 0 | |
| /patterns | link | 200 | 0 | |
| /pricing | link | 200 | 1 | |
| /products | link | 200 | 3 | |
| /products/:id ×3 | link | 200 | 2 | |
| /profile | link | 200 | 2 | |
| /reports | link | 200 | 4 | |
| /settings | link | 200 | 5 | |
| /orphan | your list | 200 | 1 |
Expected routes covered: 10/10
Pages we could not reach:
- /promotions-nonexistent — the server returned 404 Not Found
Run it on your own app
Verify a domain you own, give it a standard user login, and get this report for your site.