Building the Issue Tracking System: From Detection to Drill-Down
Our audit engine detects problems. But detection is useless without actionability. Showing "39 canonical issues" means nothing if users can't see which pages are affected.
Here's how we built the issue tracking system that turns raw audit data into something you can actually act on.
The Problem with On-Demand Computation
Early Glimpse computed issues every time you loaded the dashboard. Open the page? Scan through all crawled pages, check for missing titles, count redirect chains, aggregate everything. Refresh? Do it all again.
This had three problems:
- Slow: Recomputing issues for 200 pages on every render is wasteful
- No persistence: Issue counts weren't stored, making trend tracking impossible
- Limited context: We couldn't easily answer "which pages have this problem?"
The third one hurt the most. Telling someone "you have 39 canonical issues" without showing them which pages are affected is like a doctor saying "something's wrong" without telling you what.
The Persistence Decision
We had a choice: keep computing issues on-demand, or store them in the database when the audit completes.
On-demand means issues are always fresh—if you somehow fixed something between page loads (you didn't, but hypothetically), you'd see the updated count. No extra storage needed.
Persisted means issues are snapshots. They reflect site state at audit completion and don't change until the next audit. But this enables historical comparison, fast retrieval, and storing metadata like affected URLs.
We chose persistence because audits are inherently snapshots. When you run an audit on Monday, you want to see Monday's issues—even if it's now Wednesday. The site may have changed, but that audit captured a specific moment.
The Data Model
Each issue record stores:
- Category: HTTP Errors, Redirects, Indexability, Links, Content, Meta, or Social
- Type: The specific problem (e.g., "redirect_chain", "orphan_page")
- Severity: Error, Warning, or Info
- Count: How many pages have this issue
- Weight: Score penalty per instance
- Affected Pages: List of URLs with this problem
The affected pages list is the key insight. Instead of just "39 canonical issues," we store all 39 URLs. Click the issue, see every page that needs fixing.
Seven Categories, 27 Issue Types
We group issues by what they affect:
| Category | What It Covers |
|---|---|
| HTTP Errors | 404s, 4xx, 5xx status codes |
| Redirects | Chains, broken redirects, 302s that should be 301s |
| Indexability | Canonicals pointing to redirects/errors, noindex conflicts |
| Links | Orphan pages, dead ends, links to redirects/errors |
| Content | Missing/duplicate titles, H1 issues |
| Meta | Missing descriptions, length problems |
| Social | Missing OG tags, Twitter cards |
Categories are ordered by severity. HTTP errors appear first because a 500 error is more urgent than a missing OG image.
Within each category, issues are sorted by severity: errors first, then warnings, then informational items. This puts the worst problems at the top.
The Drill-Down Experience
The dashboard now shows issues grouped by category:
HTTP Errors
├── 404 Not Found (1) [Error]
└── 4xx Client Error (1) [Error]
Redirects
├── Redirect Chain (45) [Warning]
├── 302 Redirect (2) [Warning]
└── HTTP to HTTPS (8) [Info]
Links
├── Orphan Page (5) [Warning]
└── No Outgoing Links (2) [Warning]
Click any issue and a panel slides in showing:
- Stats: How many pages are affected, what percentage of your site, the score penalty
- Affected pages: Every URL with this problem, displayed as paths for readability
- Navigation: Click any page to jump directly to its detail view
The workflow becomes natural: overview → issue → affected pages → specific page. Each click narrows focus until you're looking at exactly what needs fixing.
Path Display, Not Full URLs
When listing affected pages, showing full URLs is noisy:
https://example.com/blog/how-we-built-something
https://example.com/products/widget-pro
https://example.com/about/team/leadership
Instead, we show just the path:
/blog/how-we-built-something
/products/widget-pro
/about/team/leadership
The domain is the same for all of them—you're auditing one site. Hover to see the full URL if needed.
Handling Scale
Some issues affect hundreds of pages. A site with 500 pages might have 200 missing meta descriptions. Storing and displaying all 200 URLs works fine, but we cap the displayed list at 100 with a note showing the true count.
The count field always reflects reality. If 347 pages have missing descriptions, you see "347 affected pages" even though only the first 100 are listed. This keeps the UI responsive while still being accurate.
Issue Definitions
Rather than scattering issue metadata across the codebase, we centralized everything in one place. Each issue type has a definition that includes its category, severity, human-readable title, description, and score weight.
This means adding a new issue type is straightforward: define it once, and it automatically appears in the right category with the right severity badge and score impact.
What This Enables
With issues persisted, we can build features that weren't possible before:
Historical comparison: How did issue counts change between last week's audit and this week's? Are things getting better or worse?
Fix verification: After you fix a problem, the next audit can confirm it's resolved. We could even highlight "issues fixed since last audit."
Priority sorting: Instead of alphabetical or by count, sort by score impact. The issue costing you the most points appears first.
Export: Download affected URLs as a CSV. Hand it to a developer or content team. "Fix these 47 pages."
The Navigation Flow
The system creates a clear path from problem discovery to problem solving:
- Health score: Something's wrong (score is 45)
- Issue categories: HTTP Errors, Redirects, Links...
- Specific issue: Redirect Chain (45 pages)
- Affected pages: /blog/old-post, /products/legacy-item...
- Page detail: Full audit data for that specific page
At each step, you get more specific. By the time you're on step 5, you know exactly what's broken and where.
Why Categories Matter
Grouping by category isn't just organizational—it helps prioritize.
HTTP Errors mean pages are completely broken. Users get error screens. Fix these first.
Redirects mean pages exist but waste time and link equity on unnecessary hops. Important, but not as urgent as errors.
Content and Meta issues affect search appearance but don't break functionality. Fix them, but after the structural problems.
Social issues only matter when links are shared. Nice to have, lowest priority.
The category hierarchy reflects real-world triage. A site owner seeing "5 HTTP Errors" and "47 missing OG images" knows to fix the errors first—the categorization makes that obvious.
Try It
Run an audit at get-glimpse.com. When results appear, click any issue to drill down into affected pages. You'll see exactly which URLs need attention—and that's the point.
Questions about issue tracking? Email ashish.so@redon.ai