From c231b7bc96b4c9dbb314de4d84266f2c53ba90c5 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 26 Mar 2026 21:33:51 +0000 Subject: [PATCH 1/2] fix(website): comprehensive audit fixes for UX, accessibility, security, and correctness MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fix StatsBar dialect count: 7 → 8 (ClickHouse was added but count not updated) - Fix CodeExamples import path: github.com/gosqlx/gosqlx → github.com/ajitpratap0/GoSQLX - Fix CSP: add va.vercel-scripts.com to script-src and connect-src for Vercel Analytics - Fix Navbar: extract useTransform calls from JSX render body to component scope (React hooks rule) - Fix global-error.tsx: add lang="en" attribute and dark theme styling to match app theme - Fix duplicate
elements: page.tsx and not-found.tsx nested inside layout's
- Fix SocialProof: migrate from raw to next/image with remotePatterns config - Fix BenchmarksContent: replace hardcoded button styles with shared Button component - Fix WasmLoader: move progressListeners cleanup to useEffect return for proper unmount handling - Fix accessibility: add aria-hidden to decorative SVGs in LintTab and AnalyzeTab - Add images.remotePatterns for img.shields.io in next.config.ts https://claude.ai/code/session_01XAKeP67mR8sb1MxDPkYhxC --- website/next.config.ts | 7 ++++++- website/src/app/benchmarks/BenchmarksContent.tsx | 16 +++++----------- website/src/app/global-error.tsx | 4 ++-- website/src/app/not-found.tsx | 4 ++-- website/src/app/page.tsx | 4 ++-- website/src/components/home/CodeExamples.tsx | 8 ++++---- website/src/components/home/SocialProof.tsx | 6 ++++-- website/src/components/home/StatsBar.tsx | 2 +- website/src/components/layout/Navbar.tsx | 6 ++++-- website/src/components/playground/AnalyzeTab.tsx | 4 ++-- website/src/components/playground/LintTab.tsx | 4 ++-- website/src/components/playground/WasmLoader.tsx | 7 ++++--- 12 files changed, 38 insertions(+), 34 deletions(-) diff --git a/website/next.config.ts b/website/next.config.ts index 7f409b0a..cd3ac5d7 100644 --- a/website/next.config.ts +++ b/website/next.config.ts @@ -8,6 +8,11 @@ const withAnalyzer = withBundleAnalyzer({ const nextConfig: NextConfig = { trailingSlash: true, + images: { + remotePatterns: [ + { protocol: 'https', hostname: 'img.shields.io' }, + ], + }, async headers() { return [ { @@ -24,7 +29,7 @@ const nextConfig: NextConfig = { headers: [ { key: 'Content-Security-Policy', - value: "default-src 'self'; script-src 'self' 'unsafe-inline' 'wasm-unsafe-eval'; style-src 'self' 'unsafe-inline'; font-src 'self'; img-src 'self' https://img.shields.io https://goreportcard.com https://*.shields.io data:; connect-src 'self' https://*.sentry.io https://vitals.vercel-insights.com; worker-src 'self' blob:; frame-ancestors 'none'; base-uri 'self'; form-action 'self'", + value: "default-src 'self'; script-src 'self' 'unsafe-inline' 'wasm-unsafe-eval' https://va.vercel-scripts.com; style-src 'self' 'unsafe-inline'; font-src 'self'; img-src 'self' https://img.shields.io https://goreportcard.com https://*.shields.io data:; connect-src 'self' https://*.sentry.io https://vitals.vercel-insights.com https://va.vercel-scripts.com; worker-src 'self' blob:; frame-ancestors 'none'; base-uri 'self'; form-action 'self'", }, { key: 'Strict-Transport-Security', diff --git a/website/src/app/benchmarks/BenchmarksContent.tsx b/website/src/app/benchmarks/BenchmarksContent.tsx index 089206fd..48b4b551 100644 --- a/website/src/app/benchmarks/BenchmarksContent.tsx +++ b/website/src/app/benchmarks/BenchmarksContent.tsx @@ -1,8 +1,8 @@ 'use client'; -import Link from 'next/link'; import { FadeIn } from '@/components/ui/FadeIn'; import { GlassCard } from '@/components/ui/GlassCard'; +import { Button } from '@/components/ui/Button'; const metrics = [ { label: 'Sustained Ops/sec', value: '1.38M+' }, @@ -207,18 +207,12 @@ export function BenchmarksContent() {

Ready to use GoSQLX in your project?

- + +
diff --git a/website/src/app/global-error.tsx b/website/src/app/global-error.tsx index 68e60d94..0eb33572 100644 --- a/website/src/app/global-error.tsx +++ b/website/src/app/global-error.tsx @@ -14,8 +14,8 @@ export default function GlobalError({ }, [error]); return ( - - + + diff --git a/website/src/app/not-found.tsx b/website/src/app/not-found.tsx index a4a50e0a..cce190fd 100644 --- a/website/src/app/not-found.tsx +++ b/website/src/app/not-found.tsx @@ -8,7 +8,7 @@ export const metadata: Metadata = { export default function NotFound() { return ( -
+

404

@@ -24,6 +24,6 @@ export default function NotFound() { Back to Home

-
+ ); } diff --git a/website/src/app/page.tsx b/website/src/app/page.tsx index 1932c0c7..89659e51 100644 --- a/website/src/app/page.tsx +++ b/website/src/app/page.tsx @@ -9,7 +9,7 @@ import { CtaBanner } from '@/components/home/CtaBanner'; export default function Home() { return ( -
+ <> @@ -18,6 +18,6 @@ export default function Home() { -
+ ); } diff --git a/website/src/components/home/CodeExamples.tsx b/website/src/components/home/CodeExamples.tsx index 3cf2e206..0e821a5b 100644 --- a/website/src/components/home/CodeExamples.tsx +++ b/website/src/components/home/CodeExamples.tsx @@ -14,7 +14,7 @@ const tabs: { label: string; lines: CodeLine[] }[] = [ lines: [ [{ text: 'package', cls: 'text-accent-indigo' }, { text: ' main', cls: 'text-white' }], [], - [{ text: 'import', cls: 'text-accent-indigo' }, { text: ' ', cls: '' }, { text: '"github.com/gosqlx/gosqlx/pkg/gosqlx"', cls: 'text-accent-green' }], + [{ text: 'import', cls: 'text-accent-indigo' }, { text: ' ', cls: '' }, { text: '"github.com/ajitpratap0/GoSQLX/pkg/gosqlx"', cls: 'text-accent-green' }], [], [{ text: 'func', cls: 'text-accent-indigo' }, { text: ' main', cls: 'text-accent-orange' }, { text: '() {', cls: 'text-zinc-300' }], [{ text: ' ', cls: '' }, { text: '// Parse SQL into an AST', cls: 'text-zinc-500' }], @@ -31,7 +31,7 @@ const tabs: { label: string; lines: CodeLine[] }[] = [ lines: [ [{ text: 'package', cls: 'text-accent-indigo' }, { text: ' main', cls: 'text-white' }], [], - [{ text: 'import', cls: 'text-accent-indigo' }, { text: ' ', cls: '' }, { text: '"github.com/gosqlx/gosqlx/pkg/gosqlx"', cls: 'text-accent-green' }], + [{ text: 'import', cls: 'text-accent-indigo' }, { text: ' ', cls: '' }, { text: '"github.com/ajitpratap0/GoSQLX/pkg/gosqlx"', cls: 'text-accent-green' }], [], [{ text: 'func', cls: 'text-accent-indigo' }, { text: ' main', cls: 'text-accent-orange' }, { text: '() {', cls: 'text-zinc-300' }], [{ text: ' ', cls: '' }, { text: '// Format messy SQL', cls: 'text-zinc-500' }], @@ -48,7 +48,7 @@ const tabs: { label: string; lines: CodeLine[] }[] = [ lines: [ [{ text: 'package', cls: 'text-accent-indigo' }, { text: ' main', cls: 'text-white' }], [], - [{ text: 'import', cls: 'text-accent-indigo' }, { text: ' ', cls: '' }, { text: '"github.com/gosqlx/gosqlx/pkg/gosqlx"', cls: 'text-accent-green' }], + [{ text: 'import', cls: 'text-accent-indigo' }, { text: ' ', cls: '' }, { text: '"github.com/ajitpratap0/GoSQLX/pkg/gosqlx"', cls: 'text-accent-green' }], [], [{ text: 'func', cls: 'text-accent-indigo' }, { text: ' main', cls: 'text-accent-orange' }, { text: '() {', cls: 'text-zinc-300' }], [{ text: ' ', cls: '' }, { text: '// Validate SQL syntax', cls: 'text-zinc-500' }], @@ -64,7 +64,7 @@ const tabs: { label: string; lines: CodeLine[] }[] = [ lines: [ [{ text: 'package', cls: 'text-accent-indigo' }, { text: ' main', cls: 'text-white' }], [], - [{ text: 'import', cls: 'text-accent-indigo' }, { text: ' ', cls: '' }, { text: '"github.com/gosqlx/gosqlx/pkg/gosqlx"', cls: 'text-accent-green' }], + [{ text: 'import', cls: 'text-accent-indigo' }, { text: ' ', cls: '' }, { text: '"github.com/ajitpratap0/GoSQLX/pkg/gosqlx"', cls: 'text-accent-green' }], [], [{ text: 'func', cls: 'text-accent-indigo' }, { text: ' main', cls: 'text-accent-orange' }, { text: '() {', cls: 'text-zinc-300' }], [{ text: ' ', cls: '' }, { text: '// Lint SQL for best practices', cls: 'text-zinc-500' }], diff --git a/website/src/components/home/SocialProof.tsx b/website/src/components/home/SocialProof.tsx index c42ebceb..feca712a 100644 --- a/website/src/components/home/SocialProof.tsx +++ b/website/src/components/home/SocialProof.tsx @@ -1,5 +1,6 @@ 'use client'; +import Image from 'next/image'; import { FadeIn } from '@/components/ui/FadeIn'; const badges = [ @@ -36,14 +37,15 @@ export function SocialProof() {
{badges.map((badge) => ( - {badge.alt} ))}
diff --git a/website/src/components/home/StatsBar.tsx b/website/src/components/home/StatsBar.tsx index 80212510..12cacc97 100644 --- a/website/src/components/home/StatsBar.tsx +++ b/website/src/components/home/StatsBar.tsx @@ -8,7 +8,7 @@ const stats = [ { value: 1380000, suffix: '+', label: 'ops/sec', color: 'text-accent-orange' }, { value: 1, suffix: 'μs', label: 'latency', color: 'text-accent-indigo', prefix: '<' }, { value: 85, suffix: '%', label: 'SQL-99', color: 'text-accent-green' }, - { value: 7, suffix: '', label: 'Dialects', color: 'text-accent-purple' }, + { value: 8, suffix: '', label: 'Dialects', color: 'text-accent-purple' }, ]; export function StatsBar() { diff --git a/website/src/components/layout/Navbar.tsx b/website/src/components/layout/Navbar.tsx index 594c5e03..77cd2b16 100644 --- a/website/src/components/layout/Navbar.tsx +++ b/website/src/components/layout/Navbar.tsx @@ -43,6 +43,8 @@ export function Navbar() { const { scrollY } = useScroll(); const bgOpacity = useTransform(scrollY, [0, 100], [0.6, 0.9]); const blurAmount = useTransform(scrollY, [0, 100], [8, 16]); + const bgColor = useTransform(bgOpacity, (v) => `rgba(9, 9, 11, ${v})`); + const blur = useTransform(blurAmount, (v) => `blur(${v}px)`); // Close mobile menu on resize useEffect(() => { @@ -55,8 +57,8 @@ export function Navbar() { `rgba(9, 9, 11, ${v})`), - backdropFilter: useTransform(blurAmount, (v) => `blur(${v}px)`), + backgroundColor: bgColor, + backdropFilter: blur, }} >