Skip to content

fix(website): playground UX, a11y, benchmarks, VS Code, security — Phase 2 audit#420

Closed
ajitpratap0 wants to merge 18 commits intomainfrom
fix/website-audit-phase2
Closed

fix(website): playground UX, a11y, benchmarks, VS Code, security — Phase 2 audit#420
ajitpratap0 wants to merge 18 commits intomainfrom
fix/website-audit-phase2

Conversation

@ajitpratap0
Copy link
Owner

Summary

Comprehensive phase 2 website audit — improvements accumulated since the visual audit series.

Closes Issues

Playground Improvements

  • Code block line rendering fixes
  • WASM error boundary + better error messages
  • Clipboard copy failure UX (tooltip instead of silent failure)
  • Preserve indentation whitespace in CodeExamples
  • LintTab refactor, clipboard error states

Other Fixes

  • Benchmarks page: remove duplicate Competitor Comparison section, SEO/a11y
  • VS Code page: audit fixes — a11y, SEO, UX
  • .trivyignore for GHSA-6g7g-w4f8-9c9x (buger/jsonparser)
  • next 16.1.6 → 16.1.7 (CVE fixes)
  • Docker base image 1.25 → 1.26
  • CI: auto-trigger Glama build on GitHub release

🤖 Generated with Claude Code

Ajit Pratap Singh and others added 18 commits March 17, 2026 21:43
…nt pages

P0 bugs:
- Guard onRouterTransitionStart behind NEXT_PUBLIC_SENTRY_DSN check to prevent
  spurious router.push() redirect loops when DSN is absent
- Remove clients.claim() from WASM service worker activate handler to prevent
  disruption of in-flight RSC fetches during page load
- Navbar: add pointerEvents:none to mobile menu initial/exit states to block
  iOS ghost click causing accidental navigation; add type="button" to hamburger
- Navbar: change all md: breakpoints → lg: so desktop nav collapses at 1024px

Homepage:
- AnimatedCounter: initialize display to real value to eliminate zero flash on mount;
  add prefers-reduced-motion guard to skip animation
- Hero: move overflow-hidden from section to blobs div; add break-words/hyphens-auto
  to headline; fix playground link contrast text-zinc-500 → text-zinc-300
- SocialProof: fix GitHub shields.io badge URL gosqlx/gosqlx → ajitpratap0/GoSQLX
- VscodeSection: fix publisher ID gosqlx.gosqlx → ajitpratap0.gosqlx

Playground:
- WasmLoader: fix callAndParse to separate JSON parse errors from error objects so
  Go WASM error responses propagate to callers instead of returning raw JSON strings
- AnalyzeTab: fix all field names to match actual Go JSON output (critical_count,
  high_count, medium_count, low_count from security; Score, QueryComplexity,
  Suggestions from optimization — PascalCase because no JSON struct tags in Go)
- Playground: fix breakpoints md: → lg: for side-by-side layout on desktop only

Content:
- GETTING_STARTED.md: replace all .md hrefs with /docs/ routes; update v1.6.0 → v1.12.0
- Sidebar: normalize trailing slash in isActive; add aria-current="page" to active link
  with visual left border accent
- Toc: add H2/H3 visual hierarchy (weight, size, indent, ellipsis + title tooltip)
- blog/page.tsx: rename "Release Notes" → "Changelog" in heading and metadata
- BenchmarksContent: add competitor comparison table (GoSQLX vs xwb1989, pg_query_go,
  blastrain/sqlparser)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds .github/workflows/glama-sync.yml which fires on every published
GitHub release and does two things in parallel:

1. bump-glama-version (continue-on-error):
   - Strips the `v` prefix from the release tag
   - Updates glama.json version field via jq
   - Commits "[skip ci]" back to the release branch
   - Best-effort: silently passes if branch protection rejects the push

2. trigger-glama-build:
   - POSTs to Glama's admin Dockerfile endpoint with:
       intent=build, pinnedCommitSha=<release SHA>
       full build config (Go 1.26.1 download + compile)
   - Pins the build to the exact release commit so Glama always
     runs the binary that matches the published release
   - Gracefully skips with setup instructions when
     GLAMA_SESSION_COOKIE secret is not configured
   - Fails with a clear message when the cookie has expired

Requires one-time manual setup:
  Repo Settings → Secrets → GLAMA_SESSION_COOKIE
  (Chrome DevTools → Network → copy Cookie header from glama.ai)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…builds)

The postbuild update-sw-hash script called fs.readFileSync on public/wasm/gosqlx.wasm
which is gitignored. Vercel's automatic preview builds don't run the WASM compile step
(only the GitHub Actions workflow does), causing every Vercel deployment to fail.

Add an fs.existsSync guard: when the binary is absent the script prints a warning and
exits 0 instead of throwing. The SW cache key remains unchanged in that case, which is
correct — Vercel preview builds don't serve the WASM anyway.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
go.mod requires go >= 1.26.1 but the Dockerfile was using golang:1.25-alpine
(Go 1.25.8), causing all Render builds to fail with:
  go: go.mod requires go >= 1.26.1 (running go 1.25.8; GOTOOLCHAIN=local)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Homepage:
- Fix invalid double <main> nesting (layout.tsx wraps in <div> now)
- StatsBar: grid layout prevents 3+1 orphan at tablet breakpoints
- StatsBar: unify performance stat to 1,380,000 (matches benchmarks page)
- Hero: improve hover contrast and mobile overflow handling
- McpSection: fix badge contrast (zinc-500→zinc-300), add MCP guide CTA

Playground:
- SqlEditor: CodeMirror fills container height via theme + h-full wrapper
- Playground: skeleton loading state mirrors real UI layout
- FormatTab: consistent overflow handling
- AnalyzeTab: C:0 H:0 M:0 L:0 severity format with hover tooltip

Benchmarks:
- Section heading, GoSQLX highlight row, CTA section
- Accessible aria-labels on ✓/✗ symbols
- Mobile swipe hint, improved dot contrast, last-updated label
- Updated page title with 1.38M ops/sec

Docs:
- TOC width: w-48 → w-56 (224px) for better readability

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Benchmarks page:
- Fix duplicate <main> landmark (use <div> wrapper)
- Standardize h2 headings to text-2xl font-bold
- Remove extra mt-16 from CTA section (fixes blank space gap)
- Add scope="col" to all <th> elements (WCAG 1.3.1)
- Add sr-only <caption> to both tables
- Fix version v1.12.1 → v1.12.0
- Add trailing slashes to CTA hrefs
- aria-hidden on methodology bullet dots
- Wrap -benchmem in <code> tag
- Add competitor measurement footnote
- Add page-specific openGraph + alternates.canonical

VS Code page:
- Fix duplicate <main> landmark (use <div> wrapper)
- Add sr-only <h2>Features</h2> (fix H1→H3 heading skip)
- aria-label on Install Extension CTA (new tab warning)
- aria-label on features <section>
- role/aria-label/tabIndex on <pre> Key Settings block
- Add page-specific openGraph + alternates.canonical

Shared components:
- FadeIn: respect prefers-reduced-motion via useReducedMotion()
- Navbar: aria-current="page" on active link + active text-white style
- Navbar: aria-label="Main navigation" on <nav>
- TerminalMockup: aria-hidden on decorative dots, break-all→break-words
- layout.tsx: relative canonical '/' (let pages override per-page)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Keep branch improvements:
- Hero.tsx: mobile overflow fix (w-full max-w-full px-4 sm:px-0) and
  hover:text-white contrast improvement
- Navbar.tsx: aria-current="page" active nav link + usePathname

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…marks page

The second competitor comparison table (lines 186-238) was an exact
duplicate of the first, rendered back-to-back. It also lacked the
accessibility improvements (scope="col", aria-labels, sr-only caption)
that were present on the first. Remove the stale duplicate.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…layground improvements

Accessibility (P0/P1):
- layout.tsx: wrap content in <main> landmark (was <div>); add robots metadata
- Navbar: aria-controls/id on hamburger+menu, aria-label on <nav>, aria-current="page" on active links
- Footer: demote nav group headings from h2→h3 (heading hierarchy fix)
- FadeIn: respect prefers-reduced-motion via useReducedMotion()
- FeatureGrid: aria-hidden="true" on all 6 decorative SVGs
- Button: expose aria-label prop through to rendered element
- docs breadcrumb: wrap in semantic <ol>/<li> with aria-label="Breadcrumb", aria-hidden separators

Performance / CWV:
- globals.css: define .container-width and .section-padding (were missing — content bled to edges)
- globals.css: add global prefers-reduced-motion override block
- AnimatedCounter: hardcode 'en-US' locale to fix server/client hydration mismatch
- SqlEditor: remove word-break:break-all (was splitting SQL keywords mid-word)

SEO:
- not-found.tsx: add 404 metadata with noindex
- blog/page.tsx: add canonical, openGraph block, refresh description
- benchmarks/page.tsx: add canonical, openGraph with absolute form title
- vscode/page.tsx: add canonical, openGraph
- constants.ts: rename nav label 'Blog'→'Changelog' to match page title
- docs/[...slug]: semantic breadcrumb structure

Visual / UX:
- Hero: fix subtitle contrast (rgba→text-zinc-300, ~5.9:1), responsive h1, remove redundant link
- VersionBadge: improve badge text contrast (text-indigo-300, ~5.1:1)
- BenchmarksContent: tighten methodology→CTA spacing (pb-24→pb-8), stronger GoSQLX row highlight
- VscodeContent: responsive h1 scaling, mx-auto on content containers
- SocialProof: reduce section padding py-16→py-8 (was ~200px gap)
- mdx-components: add right-edge fade gradient on code blocks for mobile scroll affordance

Playground:
- Playground: sr-only h1 with visible span, dialect select label association, aria-live on tab panel
- AstTab: add copy-to-clipboard button with 2s reset
- FormatTab: add copy button + read-only badge in header bar
- LintTab: add copy button (serializes as [SEVERITY] rule message text)
- AnalyzeTab: responsive score grid (grid-cols-1 sm:grid-cols-3, was overflowing at 390px)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- BenchmarksContent: keep bg-indigo-500/10 (stronger GoSQLX row highlight)
- Hero: keep redundant playground link removed (3 links to same page was excessive)
- FormatTab: keep full rewrite with copy button + read-only badge

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Fixes 3 MEDIUM CVEs detected by Trivy:
- CVE-2026-27979 (fixed in 16.1.7)
- CVE-2026-27980 (fixed in 16.1.7)
- CVE-2026-29057 (fixed in 16.1.7)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…rser)

No fixed version exists for this MEDIUM advisory. The package is a
transitive dependency: mark3labs/mcp-go → invopop/jsonschema →
wk8/go-ordered-map → buger/jsonparser. GoSQLX does not call it directly.

Will re-evaluate when a patched version is released.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- layout.tsx: restore <main> landmark (was reverted to <div> by merge)
- mdx-components.tsx: add error handling on clipboard.writeText() promise

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
CodeExamples.tsx:
- Rewrite renderCode() to use explicit line-based data structure (CodeLine[][])
  instead of flat segment array with inferred line breaks
- Old renderer only flushed lines on { text: '', cls: '' } — segments like
  { text: '    ', cls: '' } and content with embedded indentation were
  appended to the same line, collapsing all of func main() onto one row
- New structure: each inner array is one code line; empty arrays = blank lines
- Renderer is now a trivial map() with no implicit line-break inference

WasmLoader.tsx:
- Add HTTP status check after fetch(): throw if !response.ok
- Add content-type check: throw descriptive error if response is text/html
  (Vercel preview deployments serve HTML 404 for the gitignored .wasm binary)
- Old error: "expected magic word 00 61 73 6d, found 3c 21 44 4f"
- New error: "SQL parser not available in preview deployments — visit gosqlx.dev"

WasmErrorBoundary.tsx:
- Align error title with WasmLoader: "Failed to load SQL parser"

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…error states

LintTab.tsx:
- Extract extractViolations() helper to replace 3-level nested ternary
- Add copyFailed state with 2s "Failed" indicator on clipboard error

AstTab.tsx, FormatTab.tsx, LintTab.tsx, mdx-components.tsx:
- All clipboard .writeText() calls now catch errors and show brief "Failed"
  indicator instead of silently swallowing permission/insecure-context errors

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add whitespace-pre to line content span — HTML collapses regular spaces
so the 4-space indent segments were rendering with no indentation.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…tooltip

When clipboard write fails, aria-label and title now explain the failure
and suggest Ctrl+C as a fallback, addressing review bot feedback.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… conflicts

Resolved two additive conflicts:
- website/src/app/docs/[...slug]/page.tsx: keep text-zinc-300 (better contrast)
- website/src/components/home/Hero.tsx: keep tabIndex/aria-label from main

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@vercel
Copy link

vercel bot commented Mar 19, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
gosqlx-website Ready Ready Preview, Comment Mar 19, 2026 7:00pm

@github-actions
Copy link

github-actions bot commented Mar 19, 2026

Claude finished @ajitpratap0's task —— View job


PR Review Complete

This is a comprehensive website audit PR that addresses multiple important areas. Here's my detailed analysis:

Review Tasks:

  • Examine actual code changes in the branch
  • Review accessibility improvements (WCAG 2.1.1 compliance)
  • Assess playground UX enhancements
  • Evaluate security fixes and dependency updates
  • Check benchmarks and VS Code page improvements
  • Analyze code quality and best practices
  • Review test coverage implications

Strengths

Accessibility Excellence

  • WCAG 2.1.1 compliance: Added tabIndex={0} to scrollable code blocks in mdx-components.tsx:79
  • Semantic structure improvements: Proper <main> landmarks, semantic breadcrumbs, correct heading hierarchy
  • Keyboard navigation: Focus management with focus:ring-2 focus:ring-emerald-500/50
  • Screen reader support: aria-label, aria-controls, aria-current="page" throughout
  • Motion sensitivity: prefers-reduced-motion respect via useReducedMotion()

UX/Performance Enhancements

  • Error boundaries: New WasmErrorBoundary.tsx with graceful error handling and retry mechanism
  • Copy functionality: Enhanced clipboard support with failure feedback (copyFailed state in mdx-components.tsx:7,14,23-24)
  • Whitespace preservation: Fixed indentation rendering in CodeExamples.tsx:88 with whitespace-pre
  • Mobile scroll affordances: Right-edge fade gradients on code blocks

Security & Maintenance

  • CVE fixes: Next.js 16.1.6 → 16.1.7 addressing security vulnerabilities
  • Docker security: Go base image 1.25 → 1.26 upgrade
  • Dependency transparency: Proper .trivyignore documentation for GHSA-6g7g-w4f8-9c9x
  • CI automation: Glama build auto-trigger on releases

Code Quality

  • TypeScript safety: Proper error handling with try-catch in mdx-components.tsx:65-73
  • Performance optimization: WASM service worker hash skip when binary absent
  • Clean state management: Logical separation of copied vs copyFailed states

⚠️ Areas for Improvement

Type Safety

// mdx-components.tsx:67 - Consider improving type assertion
const child = children as any;

Recommendation: Use proper type guards or more specific typing instead of any

Error Handling

// mdx-components.tsx:71-73 - Silent error swallowing
} catch {
  // ignore
}

Recommendation: At minimum, log errors in development for debugging

Security Consideration

The .trivyignore entry is well-documented but represents a transitive dependency vulnerability. Consider:

  • Monitoring for buger/jsonparser security updates
  • Evaluating alternative JSON schema libraries in the dependency chain

Accessibility Edge Case

// mdx-components.tsx:79 - tabIndex on scrollable elements
tabIndex={0}

While WCAG-compliant, consider if custom scroll handling or focus management is needed for optimal UX.

📋 Test Coverage Assessment

This is primarily a UI/UX improvement PR affecting the website frontend:

  • No Go code changes - Core parsing library unaffected
  • Frontend changes - Would benefit from:
    • Component unit tests for error boundary behavior
    • A11y testing with tools like @testing-library/jest-dom
    • Copy functionality tests across browsers
    • Error state rendering tests

🔒 Security Review

  • ✅ Dependency updates: Proactive CVE patching
  • ✅ Vulnerability documentation: Clear .trivyignore rationale
  • ✅ No new attack vectors: Changes are defensive in nature
  • ⚠️ Transitive dependency: Monitor buger/jsonparser for patches

🚀 Performance Impact

  • ✅ Positive: Service worker optimizations, reduced motion respect
  • ✅ Minimal bundle impact: Error boundary is code-split appropriately
  • ✅ UX improvements: Better perceived performance through error states

🎯 Overall Assessment

Rating: ⭐⭐⭐⭐⭐ Excellent

This PR demonstrates exceptional attention to detail across accessibility, security, and UX. The changes are well-structured, thoroughly documented, and follow best practices. The commit message quality is outstanding with clear categorization of improvements.

Recommendation: ✅ Approve and merge

Minor suggestions above are non-blocking and can be addressed in future iterations.


Job Run

@ajitpratap0
Copy link
Owner Author

Closing — all changes from this branch were already included in PR #419. The preload fix is live in main.

@ajitpratap0 ajitpratap0 deleted the fix/website-audit-phase2 branch March 19, 2026 19:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

perf(website): add rel=preload for gosqlx.wasm on /playground a11y(website): make scrollable code blocks keyboard accessible (WCAG 2.1.1)

1 participant