Skip to content

Commit c231b7b

Browse files
committed
fix(website): comprehensive audit fixes for UX, accessibility, security, and correctness
- 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 <main> elements: page.tsx and not-found.tsx nested inside layout's <main> - Fix SocialProof: migrate from raw <img> 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
1 parent 791b4a6 commit c231b7b

12 files changed

Lines changed: 38 additions & 34 deletions

File tree

website/next.config.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ const withAnalyzer = withBundleAnalyzer({
88

99
const nextConfig: NextConfig = {
1010
trailingSlash: true,
11+
images: {
12+
remotePatterns: [
13+
{ protocol: 'https', hostname: 'img.shields.io' },
14+
],
15+
},
1116
async headers() {
1217
return [
1318
{
@@ -24,7 +29,7 @@ const nextConfig: NextConfig = {
2429
headers: [
2530
{
2631
key: 'Content-Security-Policy',
27-
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'",
32+
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'",
2833
},
2934
{
3035
key: 'Strict-Transport-Security',

website/src/app/benchmarks/BenchmarksContent.tsx

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
'use client';
22

3-
import Link from 'next/link';
43
import { FadeIn } from '@/components/ui/FadeIn';
54
import { GlassCard } from '@/components/ui/GlassCard';
5+
import { Button } from '@/components/ui/Button';
66

77
const metrics = [
88
{ label: 'Sustained Ops/sec', value: '1.38M+' },
@@ -207,18 +207,12 @@ export function BenchmarksContent() {
207207
<div className="text-center">
208208
<p className="text-zinc-400 mb-4">Ready to use GoSQLX in your project?</p>
209209
<div className="flex gap-3 justify-center">
210-
<Link
211-
href="/docs/getting-started/"
212-
className="inline-flex items-center rounded-lg bg-indigo-600 px-5 py-2.5 text-sm font-medium text-white hover:bg-indigo-500 transition-colors"
213-
>
210+
<Button href="/docs/getting-started/" variant="primary">
214211
Get Started
215-
</Link>
216-
<Link
217-
href="/playground/"
218-
className="inline-flex items-center rounded-lg border border-white/10 bg-white/5 px-5 py-2.5 text-sm font-medium text-zinc-300 hover:bg-white/10 hover:text-white transition-colors"
219-
>
212+
</Button>
213+
<Button href="/playground/" variant="ghost">
220214
Try Playground
221-
</Link>
215+
</Button>
222216
</div>
223217
</div>
224218
</FadeIn>

website/src/app/global-error.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ export default function GlobalError({
1414
}, [error]);
1515

1616
return (
17-
<html>
18-
<body>
17+
<html lang="en">
18+
<body className="bg-[#09090b] text-white">
1919
<NextError statusCode={0} />
2020
</body>
2121
</html>

website/src/app/not-found.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ export const metadata: Metadata = {
88

99
export default function NotFound() {
1010
return (
11-
<main id="main-content" className="min-h-screen flex items-center justify-center">
11+
<div className="min-h-screen flex items-center justify-center">
1212
<div className="text-center">
1313
<p className="text-sm font-semibold text-emerald-400 uppercase tracking-wider mb-4">404</p>
1414
<h1 className="text-4xl font-bold tracking-tight text-white mb-4">
@@ -24,6 +24,6 @@ export default function NotFound() {
2424
Back to Home
2525
</Link>
2626
</div>
27-
</main>
27+
</div>
2828
);
2929
}

website/src/app/page.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { CtaBanner } from '@/components/home/CtaBanner';
99

1010
export default function Home() {
1111
return (
12-
<main>
12+
<>
1313
<Hero />
1414
<StatsBar />
1515
<FeatureGrid />
@@ -18,6 +18,6 @@ export default function Home() {
1818
<VscodeSection />
1919
<SocialProof />
2020
<CtaBanner />
21-
</main>
21+
</>
2222
);
2323
}

website/src/components/home/CodeExamples.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const tabs: { label: string; lines: CodeLine[] }[] = [
1414
lines: [
1515
[{ text: 'package', cls: 'text-accent-indigo' }, { text: ' main', cls: 'text-white' }],
1616
[],
17-
[{ text: 'import', cls: 'text-accent-indigo' }, { text: ' ', cls: '' }, { text: '"github.com/gosqlx/gosqlx/pkg/gosqlx"', cls: 'text-accent-green' }],
17+
[{ text: 'import', cls: 'text-accent-indigo' }, { text: ' ', cls: '' }, { text: '"github.com/ajitpratap0/GoSQLX/pkg/gosqlx"', cls: 'text-accent-green' }],
1818
[],
1919
[{ text: 'func', cls: 'text-accent-indigo' }, { text: ' main', cls: 'text-accent-orange' }, { text: '() {', cls: 'text-zinc-300' }],
2020
[{ text: ' ', cls: '' }, { text: '// Parse SQL into an AST', cls: 'text-zinc-500' }],
@@ -31,7 +31,7 @@ const tabs: { label: string; lines: CodeLine[] }[] = [
3131
lines: [
3232
[{ text: 'package', cls: 'text-accent-indigo' }, { text: ' main', cls: 'text-white' }],
3333
[],
34-
[{ text: 'import', cls: 'text-accent-indigo' }, { text: ' ', cls: '' }, { text: '"github.com/gosqlx/gosqlx/pkg/gosqlx"', cls: 'text-accent-green' }],
34+
[{ text: 'import', cls: 'text-accent-indigo' }, { text: ' ', cls: '' }, { text: '"github.com/ajitpratap0/GoSQLX/pkg/gosqlx"', cls: 'text-accent-green' }],
3535
[],
3636
[{ text: 'func', cls: 'text-accent-indigo' }, { text: ' main', cls: 'text-accent-orange' }, { text: '() {', cls: 'text-zinc-300' }],
3737
[{ text: ' ', cls: '' }, { text: '// Format messy SQL', cls: 'text-zinc-500' }],
@@ -48,7 +48,7 @@ const tabs: { label: string; lines: CodeLine[] }[] = [
4848
lines: [
4949
[{ text: 'package', cls: 'text-accent-indigo' }, { text: ' main', cls: 'text-white' }],
5050
[],
51-
[{ text: 'import', cls: 'text-accent-indigo' }, { text: ' ', cls: '' }, { text: '"github.com/gosqlx/gosqlx/pkg/gosqlx"', cls: 'text-accent-green' }],
51+
[{ text: 'import', cls: 'text-accent-indigo' }, { text: ' ', cls: '' }, { text: '"github.com/ajitpratap0/GoSQLX/pkg/gosqlx"', cls: 'text-accent-green' }],
5252
[],
5353
[{ text: 'func', cls: 'text-accent-indigo' }, { text: ' main', cls: 'text-accent-orange' }, { text: '() {', cls: 'text-zinc-300' }],
5454
[{ text: ' ', cls: '' }, { text: '// Validate SQL syntax', cls: 'text-zinc-500' }],
@@ -64,7 +64,7 @@ const tabs: { label: string; lines: CodeLine[] }[] = [
6464
lines: [
6565
[{ text: 'package', cls: 'text-accent-indigo' }, { text: ' main', cls: 'text-white' }],
6666
[],
67-
[{ text: 'import', cls: 'text-accent-indigo' }, { text: ' ', cls: '' }, { text: '"github.com/gosqlx/gosqlx/pkg/gosqlx"', cls: 'text-accent-green' }],
67+
[{ text: 'import', cls: 'text-accent-indigo' }, { text: ' ', cls: '' }, { text: '"github.com/ajitpratap0/GoSQLX/pkg/gosqlx"', cls: 'text-accent-green' }],
6868
[],
6969
[{ text: 'func', cls: 'text-accent-indigo' }, { text: ' main', cls: 'text-accent-orange' }, { text: '() {', cls: 'text-zinc-300' }],
7070
[{ text: ' ', cls: '' }, { text: '// Lint SQL for best practices', cls: 'text-zinc-500' }],

website/src/components/home/SocialProof.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
'use client';
22

3+
import Image from 'next/image';
34
import { FadeIn } from '@/components/ui/FadeIn';
45

56
const badges = [
@@ -36,14 +37,15 @@ export function SocialProof() {
3637
<FadeIn>
3738
<div className="flex flex-wrap items-center justify-center gap-4">
3839
{badges.map((badge) => (
39-
<img
40+
<Image
4041
key={badge.alt}
4142
src={badge.src}
4243
alt={badge.alt}
4344
width={badge.width}
4445
height={badge.height}
45-
className="h-5"
46+
className="h-5 w-auto"
4647
loading="lazy"
48+
unoptimized
4749
/>
4850
))}
4951
</div>

website/src/components/home/StatsBar.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ const stats = [
88
{ value: 1380000, suffix: '+', label: 'ops/sec', color: 'text-accent-orange' },
99
{ value: 1, suffix: 'μs', label: 'latency', color: 'text-accent-indigo', prefix: '<' },
1010
{ value: 85, suffix: '%', label: 'SQL-99', color: 'text-accent-green' },
11-
{ value: 7, suffix: '', label: 'Dialects', color: 'text-accent-purple' },
11+
{ value: 8, suffix: '', label: 'Dialects', color: 'text-accent-purple' },
1212
];
1313

1414
export function StatsBar() {

website/src/components/layout/Navbar.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ export function Navbar() {
4343
const { scrollY } = useScroll();
4444
const bgOpacity = useTransform(scrollY, [0, 100], [0.6, 0.9]);
4545
const blurAmount = useTransform(scrollY, [0, 100], [8, 16]);
46+
const bgColor = useTransform(bgOpacity, (v) => `rgba(9, 9, 11, ${v})`);
47+
const blur = useTransform(blurAmount, (v) => `blur(${v}px)`);
4648

4749
// Close mobile menu on resize
4850
useEffect(() => {
@@ -55,8 +57,8 @@ export function Navbar() {
5557
<motion.header
5658
className="fixed top-0 left-0 right-0 z-50 border-b border-white/[0.06]"
5759
style={{
58-
backgroundColor: useTransform(bgOpacity, (v) => `rgba(9, 9, 11, ${v})`),
59-
backdropFilter: useTransform(blurAmount, (v) => `blur(${v}px)`),
60+
backgroundColor: bgColor,
61+
backdropFilter: blur,
6062
}}
6163
>
6264
<nav aria-label="Main navigation" className="mx-auto max-w-7xl flex items-center justify-between px-4 sm:px-6 lg:px-8 h-16">

website/src/components/playground/AnalyzeTab.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ export default function AnalyzeTab({ data }: AnalyzeTabProps) {
8181
<div className="p-4">
8282
<div className="bg-red-500/10 border border-red-500/30 rounded-lg p-4">
8383
<div className="flex items-center gap-2 text-red-400 font-medium mb-1">
84-
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
84+
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
8585
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
8686
</svg>
8787
Analysis Error
@@ -153,7 +153,7 @@ export default function AnalyzeTab({ data }: AnalyzeTabProps) {
153153
key={i}
154154
className="flex items-start gap-2 bg-slate-800/50 border border-slate-700 rounded-lg p-3"
155155
>
156-
<svg className="w-4 h-4 text-blue-400 mt-0.5 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
156+
<svg className="w-4 h-4 text-blue-400 mt-0.5 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
157157
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z" />
158158
</svg>
159159
<span className="text-sm text-slate-300">{text}</span>

0 commit comments

Comments
 (0)