From a641ffc91902b50795f38c267ab33fc3a70e2a57 Mon Sep 17 00:00:00 2001 From: James Pine Date: Sat, 18 Apr 2026 23:20:20 -0700 Subject: [PATCH] fix(landing): route Linux users to /linux-install instead of attempting download MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit No prebuilt Linux binary exists yet (see /linux-install for build-from-source instructions). The /download page previously treated Linux like the other platforms — auto-triggering a non-existent AppImage and offering a dead manual button. - /download page: if platform resolves to 'linux' via ?platform or UA detect, window.location.replace('/linux-install') — never try to auto-download. - Manual Linux card: label changed to "Build from source" and links to /linux-install (no download attribute, no asset URL). - /download/linux pretty URL: 307s straight to /linux-install. Co-Authored-By: Claude Opus 4.7 (1M context) --- landing/src/app/download/[platform]/route.ts | 5 +++- landing/src/app/download/page.tsx | 24 ++++++++++++++------ 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/landing/src/app/download/[platform]/route.ts b/landing/src/app/download/[platform]/route.ts index 6c007c17..46140ce8 100644 --- a/landing/src/app/download/[platform]/route.ts +++ b/landing/src/app/download/[platform]/route.ts @@ -11,7 +11,6 @@ const PLATFORM_ALIAS: Record = { 'mac-arm': 'macArm', 'mac-intel': 'macIntel', windows: 'windows', - linux: 'linux', }; export async function GET( @@ -19,6 +18,10 @@ export async function GET( { params }: { params: Promise<{ platform: string }> }, ) { const { platform } = await params; + // No prebuilt Linux binary yet — send straight to the build-from-source page. + if (platform === 'linux') { + return NextResponse.redirect(new URL('/linux-install', request.url), 307); + } const normalized = PLATFORM_ALIAS[platform]; const target = new URL('/download', request.url); if (normalized) target.searchParams.set('platform', normalized); diff --git a/landing/src/app/download/page.tsx b/landing/src/app/download/page.tsx index 087b9d4d..d7f0a8f7 100644 --- a/landing/src/app/download/page.tsx +++ b/landing/src/app/download/page.tsx @@ -29,7 +29,7 @@ const PLATFORMS: PlatformMeta[] = [ { key: 'macArm', label: 'macOS', description: 'Apple Silicon', icon: AppleIcon }, { key: 'macIntel', label: 'macOS', description: 'Intel (x64)', icon: AppleIcon }, { key: 'windows', label: 'Windows', description: '64-bit (MSI)', icon: WindowsIcon }, - { key: 'linux', label: 'Linux', description: 'AppImage', icon: LinuxIcon }, + { key: 'linux', label: 'Linux', description: 'Build from source', icon: LinuxIcon }, ]; function detectPlatform(): Platform | null { @@ -67,7 +67,15 @@ export default function DownloadPage() { useEffect(() => { const fromQuery = parseQueryPlatform(window.location.search); - setPlatform(fromQuery ?? detectPlatform()); + const resolved = fromQuery ?? detectPlatform(); + // No prebuilt Linux binary yet — send Linux users to the build-from-source + // instructions instead of sitting on /download trying to trigger a + // download that doesn't exist. + if (resolved === 'linux') { + window.location.replace('/linux-install'); + return; + } + setPlatform(resolved); }, []); useEffect(() => { @@ -179,22 +187,24 @@ export default function DownloadPage() {
{PLATFORMS.map((meta) => { - const url = links?.[meta.key]; + const isLinux = meta.key === 'linux'; + const url = isLinux ? '/linux-install' : links?.[meta.key]; const isActive = meta.key === platform; + const disabled = !isLinux && !url; return ( { - if (!url) e.preventDefault(); + if (disabled) e.preventDefault(); }} className={`flex items-center rounded-xl border px-5 py-4 transition-all group ${ isActive ? 'border-accent/40 bg-accent/5 hover:border-accent/60' : 'border-border bg-card/40 hover:border-accent/30 hover:bg-card' - } ${!url ? 'opacity-50 cursor-not-allowed' : ''}`} + } ${disabled ? 'opacity-50 cursor-not-allowed' : ''}`} >