From a60a7a3d1f9166110b07342f2b22b7b73fc327f3 Mon Sep 17 00:00:00 2001 From: Val Alexander Date: Wed, 1 Apr 2026 04:02:41 -0500 Subject: [PATCH 1/5] Fix marketing Vercel output config --- apps/marketing/next-env.d.ts | 2 +- apps/marketing/next.config.mjs | 3 +++ turbo.json | 4 ++++ vercel.json | 6 ++++++ 4 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 vercel.json diff --git a/apps/marketing/next-env.d.ts b/apps/marketing/next-env.d.ts index c4b7818fb..9edff1c7c 100644 --- a/apps/marketing/next-env.d.ts +++ b/apps/marketing/next-env.d.ts @@ -1,6 +1,6 @@ /// /// -import "./.next/dev/types/routes.d.ts"; +import "./.next/types/routes.d.ts"; // NOTE: This file should not be edited // see https://nextjs.org/docs/app/api-reference/config/typescript for more information. diff --git a/apps/marketing/next.config.mjs b/apps/marketing/next.config.mjs index bd3419136..8ee7a7de9 100644 --- a/apps/marketing/next.config.mjs +++ b/apps/marketing/next.config.mjs @@ -1,5 +1,8 @@ /** @type {import('next').NextConfig} */ const nextConfig = { + turbopack: { + root: new URL("../..", import.meta.url).pathname, + }, typescript: { ignoreBuildErrors: true, }, diff --git a/turbo.json b/turbo.json index c9471e538..040ee2c39 100644 --- a/turbo.json +++ b/turbo.json @@ -18,6 +18,10 @@ "dependsOn": ["^build"], "outputs": ["dist/**", "dist-electron/**"] }, + "@okcode/marketing#build": { + "dependsOn": ["^build"], + "outputs": [".next/**", "!.next/cache/**"] + }, "dev": { "dependsOn": ["@okcode/contracts#build"], "cache": false, diff --git a/vercel.json b/vercel.json new file mode 100644 index 000000000..dc2a991dd --- /dev/null +++ b/vercel.json @@ -0,0 +1,6 @@ +{ + "$schema": "https://openapi.vercel.sh/vercel.json", + "buildCommand": "bun run build:marketing", + "installCommand": "bun install", + "outputDirectory": "apps/marketing/.next" +} From 9299f80d726030043a474ba8bf3c04ed8dd82170 Mon Sep 17 00:00:00 2001 From: Val Alexander Date: Wed, 1 Apr 2026 05:59:02 -0500 Subject: [PATCH 2/5] docs(marketing): note dependency install before build --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index 5e8fa8655..24dd1679b 100644 --- a/README.md +++ b/README.md @@ -78,6 +78,15 @@ bun dev:desktop # Electron desktop + web bun dev:marketing # Astro marketing site ``` +Build marketing directly: + +```bash +bun install +bun run build:marketing +``` + +If `bun run build:marketing` fails with `next: command not found`, run `bun install` first to restore workspace dependencies. + Quality checks: ```bash From 9684c8bb812cfc5f1ae2e5866d8ac0d42333ac8e Mon Sep 17 00:00:00 2001 From: Val Alexander Date: Wed, 1 Apr 2026 06:02:01 -0500 Subject: [PATCH 3/5] docs(marketing): add package build setup notes --- apps/marketing/README.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 apps/marketing/README.md diff --git a/apps/marketing/README.md b/apps/marketing/README.md new file mode 100644 index 000000000..b0a464f7b --- /dev/null +++ b/apps/marketing/README.md @@ -0,0 +1,30 @@ +# Marketing App + +## Prerequisites + +- Install monorepo dependencies from the repo root before running marketing scripts: + +```bash +bun install +``` + +## Build + +```bash +bun run build:marketing +``` + +If the build fails with: + +```text +/bin/bash: next: command not found +``` + +rerun: + +```bash +bun install +bun run build:marketing +``` + +This usually means the workspace dependencies were not yet installed for the current environment. From cf3ffa7c0e48a1d7c8deef9738192c6f65ac9203 Mon Sep 17 00:00:00 2001 From: Val Alexander Date: Wed, 1 Apr 2026 06:02:51 -0500 Subject: [PATCH 4/5] docs(marketing): document stale CodeBlock/GetsStarted build error context --- apps/marketing/README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/apps/marketing/README.md b/apps/marketing/README.md index b0a464f7b..87c866364 100644 --- a/apps/marketing/README.md +++ b/apps/marketing/README.md @@ -28,3 +28,9 @@ bun run build:marketing ``` This usually means the workspace dependencies were not yet installed for the current environment. + +If you see a build error about `CodeBlock.tsx` or `GetStarted.tsx` importing `useState`/`useEffect` in a Server Component: + +- You are likely running an older marketing checkout where those components still exist. +- Switch to the current branch in this PR (`fix-marketing-build-errors`) and rerun install/build. +- In that older snapshot, the fix is to add `"use client"` at the top of those client-only components. From 007fca809f8fee7f422b114e6e365dc80cd07979 Mon Sep 17 00:00:00 2001 From: Val Alexander Date: Wed, 1 Apr 2026 06:03:20 -0500 Subject: [PATCH 5/5] fix(marketing): mark CodeBlock as client component --- apps/marketing/components/CodeBlock.tsx | 70 +++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 apps/marketing/components/CodeBlock.tsx diff --git a/apps/marketing/components/CodeBlock.tsx b/apps/marketing/components/CodeBlock.tsx new file mode 100644 index 000000000..1d7480425 --- /dev/null +++ b/apps/marketing/components/CodeBlock.tsx @@ -0,0 +1,70 @@ +"use client"; + +import { useState, useCallback, useRef, useEffect } from "react"; + +const svgProps = { + width: 16, + height: 16, + viewBox: "0 0 24 24", + fill: "none", + stroke: "currentColor", + strokeWidth: 2, + strokeLinecap: "round" as const, + strokeLinejoin: "round" as const, +}; + +const CheckIcon = ( + + + +); + +const CopyIcon = ( + + + + +); + +interface CodeBlockProps { + code: string; + label?: string; +} + +export function CodeBlock({ code, label }: CodeBlockProps) { + const [copied, setCopied] = useState(false); + const timerRef = useRef | null>(null); + + useEffect(() => { + return () => { + if (timerRef.current) clearTimeout(timerRef.current); + }; + }, []); + + const handleCopy = useCallback(async () => { + try { + await navigator.clipboard.writeText(code); + if (timerRef.current) clearTimeout(timerRef.current); + setCopied(true); + timerRef.current = setTimeout(() => setCopied(false), 2000); + } catch { + // Fallback: clipboard API unavailable + } + }, [code]); + + return ( +
+ {label && ( + {label} + )} + {code} + +
+ ); +}