Skip to content

Commit bb7d2ad

Browse files
ajitpratap0Ajit Pratap Singhclaude
authored
fix(website): phase 2 & 3 visual audit — a11y, UX, SEO, perf, playground (#413)
* fix(website): phase 2 audit — P0 bugs, playground UX, homepage, content 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> * feat(ci): auto-trigger Glama build on every GitHub release 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> * fix(website): skip SW hash update when WASM binary is absent (Vercel 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> * fix(docker): bump Go base image from 1.25 to 1.26 to match go.mod 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> * fix(website): comprehensive audit fixes — phase 2 & 3 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> * fix(website): VS Code & benchmarks page audit — a11y, SEO, UX fixes 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> * fix(website): remove duplicate Competitor Comparison section on benchmarks 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> * fix(website): comprehensive visual audit — a11y, UX, SEO, perf, and playground 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> * fix(deps): bump next 16.1.6 → 16.1.7 to fix CVEs 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> * fix(security): add .trivyignore for GHSA-6g7g-w4f8-9c9x (buger/jsonparser) 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> * fix(website): address claude-review bot feedback - 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> * fix(website): code block line rendering and WASM error handling 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> * fix(website): address review feedback — LintTab refactor + clipboard 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> * fix(website): preserve indentation whitespace in CodeExamples 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> * fix(website): improve copy failure UX in mdx-components with helpful 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> --------- Co-authored-by: Ajit Pratap Singh <ajitpratapsingh@Ajits-Mac-mini-2655.local> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent c62f107 commit bb7d2ad

29 files changed

Lines changed: 508 additions & 319 deletions

.trivyignore

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Trivy vulnerability ignore file
2+
# Format: <advisory-id> [expiry-date] [comment]
3+
# See: https://aquasecurity.github.io/trivy/latest/docs/configuration/filtering/#trivyignore
4+
5+
# GHSA-6g7g-w4f8-9c9x — buger/jsonparser v1.1.1
6+
# Severity: MEDIUM | No fixed version available (latest is v1.1.1, released 2021-01-08)
7+
# Transitive dependency: mark3labs/mcp-go → invopop/jsonschema → wk8/go-ordered-map → buger/jsonparser
8+
# Not called directly by any GoSQLX code. Risk is scoped to MCP JSON schema generation.
9+
# Re-evaluate when buger/jsonparser releases a patched version or when mcp-go updates its dependency.
10+
GHSA-6g7g-w4f8-9c9x

website/package-lock.json

Lines changed: 106 additions & 41 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

website/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
"framer-motion": "^12.36.0",
2525
"fuse.js": "^7.1.0",
2626
"gray-matter": "^4.0.3",
27-
"next": "16.1.6",
27+
"next": "16.1.7",
2828
"next-mdx-remote": "^6.0.0",
2929
"react": "19.2.3",
3030
"react-dom": "19.2.3",

website/src/app/benchmarks/BenchmarksContent.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ export function BenchmarksContent() {
132132
</tr>
133133
</thead>
134134
<tbody>
135-
<tr className="border-b border-white/[0.04] transition-colors bg-indigo-500/5 border-l-2 border-l-indigo-500">
135+
<tr className="border-b border-white/[0.04] transition-colors bg-indigo-500/10 border-l-2 border-l-indigo-500">
136136
<td className="px-6 py-4 text-white font-medium">
137137
GoSQLX{' '}
138138
<span className="ml-2 inline-block rounded-full bg-indigo-500/20 px-2 py-0.5 text-xs font-medium text-indigo-300">
@@ -184,7 +184,7 @@ export function BenchmarksContent() {
184184
</section>
185185

186186
{/* Methodology */}
187-
<section className="section-padding pb-24">
187+
<section className="section-padding pb-8">
188188
<div className="container-width max-w-2xl">
189189
<FadeIn>
190190
<h2 className="text-2xl font-bold text-white mb-6">Methodology</h2>

website/src/app/blog/page.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,15 @@ import { BlogList } from './BlogList';
44

55
export const metadata: Metadata = {
66
title: 'Changelog',
7-
description: 'GoSQLX changelog. Track new features, improvements, and bug fixes across all versions.',
7+
description: 'GoSQLX changelog — new features, improvements, and bug fixes across all versions of the SQL parsing SDK.',
8+
alternates: {
9+
canonical: '/blog/',
10+
},
11+
openGraph: {
12+
title: 'GoSQLX Changelog',
13+
description: 'New features, improvements, and bug fixes across all GoSQLX versions.',
14+
url: '/blog/',
15+
},
816
};
917

1018
export default function BlogPage() {

website/src/app/docs/[...slug]/page.tsx

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -105,18 +105,22 @@ export default async function DocPage({ params }: PageProps) {
105105
{/* Main content */}
106106
<main className="min-w-0 flex-1 px-6 py-10 lg:px-12">
107107
{/* Breadcrumbs */}
108-
<nav className="mb-6 flex items-center gap-2 text-sm text-zinc-500">
109-
<Link href="/docs" className="hover:text-white transition-colors">
110-
Docs
111-
</Link>
112-
{categoryItem && (
113-
<>
114-
<span>/</span>
115-
<span>{categoryItem.category}</span>
116-
</>
117-
)}
118-
<span>/</span>
119-
<span className="text-zinc-300">{doc.title}</span>
108+
<nav aria-label="Breadcrumb" className="mb-6 text-sm text-zinc-500">
109+
<ol className="flex items-center gap-2">
110+
<li>
111+
<Link href="/docs" className="hover:text-white transition-colors">
112+
Docs
113+
</Link>
114+
</li>
115+
{categoryItem && (
116+
<>
117+
<li aria-hidden="true">/</li>
118+
<li>{categoryItem.category}</li>
119+
</>
120+
)}
121+
<li aria-hidden="true">/</li>
122+
<li className="text-zinc-300">{doc.title}</li>
123+
</ol>
120124
</nav>
121125

122126
{/* Content */}

website/src/app/globals.css

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,33 @@ body {
3939
box-shadow: 0 0 30px rgba(99, 102, 241, 0.05);
4040
}
4141

42+
/* Layout utilities */
43+
.section-padding {
44+
padding-left: 1rem;
45+
padding-right: 1rem;
46+
}
47+
48+
@media (min-width: 640px) {
49+
.section-padding {
50+
padding-left: 1.5rem;
51+
padding-right: 1.5rem;
52+
}
53+
}
54+
55+
@media (min-width: 1024px) {
56+
.section-padding {
57+
padding-left: 2rem;
58+
padding-right: 2rem;
59+
}
60+
}
61+
62+
.container-width {
63+
width: 100%;
64+
max-width: 80rem;
65+
margin-left: auto;
66+
margin-right: auto;
67+
}
68+
4269
/* Scrollbar */
4370
::-webkit-scrollbar { width: 6px; height: 6px; }
4471
::-webkit-scrollbar-track { background: transparent; }
@@ -53,3 +80,13 @@ body {
5380
--tw-prose-code: #fafafa;
5481
--tw-prose-pre-bg: #18181b;
5582
}
83+
84+
/* Respect prefers-reduced-motion for all animations */
85+
@media (prefers-reduced-motion: reduce) {
86+
*, *::before, *::after {
87+
animation-duration: 0.01ms !important;
88+
animation-iteration-count: 1 !important;
89+
transition-duration: 0.01ms !important;
90+
scroll-behavior: auto !important;
91+
}
92+
}

0 commit comments

Comments
 (0)