diff --git a/apps/web/app/(marketing)/page.tsx b/apps/web/app/(marketing)/page.tsx index 5314520..42706d6 100644 --- a/apps/web/app/(marketing)/page.tsx +++ b/apps/web/app/(marketing)/page.tsx @@ -1,5 +1,5 @@ -import { CodeBlock } from '@/components/code-block'; import { JsonLd } from '@/components/json-ld'; +import { StaticCodeBlock } from '@/components/static-code-block'; import { FAQ, faqJsonLd } from '@/lib/seo'; import Link from 'next/link'; @@ -134,9 +134,9 @@ export default function Landing() {
- - - + + +
diff --git a/apps/web/components/static-code-block.tsx b/apps/web/components/static-code-block.tsx new file mode 100644 index 0000000..c1d947e --- /dev/null +++ b/apps/web/components/static-code-block.tsx @@ -0,0 +1,37 @@ +import { cn } from '@/lib/cn'; + +export interface StaticCodeBlockProps { + code: string; + language?: string; + label?: string; + className?: string; +} + +/** + * Server-only variant of CodeBlock — no copy button, no client hydration. + * + * Use this for above-the-fold marketing content where every kilobyte of + * JS hurts LCP. The interactive CodeBlock pulls in lucide-react icons and + * a useState boundary that forces an entire client chunk to load before + * Lighthouse considers the element "rendered". This static variant is + * pure SSR markup and lets the browser paint as soon as the HTML arrives. + * + * CodeBlock (with copy button) stays in use for dashboard pages where + * users actually want to copy snippets. + */ +export function StaticCodeBlock({ code, language, label, className }: StaticCodeBlockProps) { + return ( +
+ {(label || language) && ( +
+ + {label ?? language} + +
+ )} +
+        {code}
+      
+
+ ); +}