fix(landing): API example + new /download page (no more dumping users on GitHub)#487
fix(landing): API example + new /download page (no more dumping users on GitHub)#487
Conversation
…mVoice-only) The curl snippet showed engine: "qwen" alongside an instruct field, but base Qwen3-TTS has no instruct path — that's a Qwen CustomVoice feature. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdded a client-side DownloadPage and centralized download routing (/download), updated landing CTAs to point to the new route, replaced a static API cURL example payload, swapped some platform icon implementations, and added a simple redirect route for platform normalization. No exported API surface was introduced. Changes
Sequence Diagram(s)sequenceDiagram
participant Browser as Browser (DownloadPage)
participant App as App Server (route.ts)
participant Releases as Releases API (/api/releases)
participant External as External Host (GitHub/Storage)
Browser->>App: GET /download/<platform>
App-->>Browser: 307 Redirect → /download?platform=...
Browser->>Browser: Render DownloadPage, parse platform (query/UA)
Browser->>Releases: GET /api/releases
Releases-->>Browser: JSON with download URLs (or error)
Browser->>Browser: create hidden anchor(href=platform URL) and click
Browser->>External: Follow download URL (direct) or route through App
External-->>Browser: Serve file download
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Profile IDs are str(uuid.uuid4()), not slugs (see backend/services/profiles.py:175). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… GitHub
Users were clicking download, landing on the GitHub releases page, and filing
confused comments along the lines of "I ended up on some blog site called
GitHub." We now route every download CTA through a dedicated /download page
that auto-triggers the platform-specific download and gives users a polished
post-click experience with donate + docs + AI help prompts.
- New /download page:
- Big app logo + "Your download has started" messaging.
- Auto-detects platform from ?platform=X or navigator.userAgent.
- Programmatically clicks a hidden anchor to trigger the file download
without leaving the page.
- Platform-specific buttons as a visible fallback for "download not
working" / manual-pick.
- Personal donate spiel + Buy Me a Coffee button.
- Resources grid: docs, DeepWiki ("got questions? ask AI"), GitHub.
- Landing page download section cards now link to /download?platform=X
instead of the asset URL directly.
- /download/[platform] (used by README/docs links) now redirects to the
/download page rather than straight to the asset or to GitHub on error.
- Drops unused downloadLinks state from the landing page.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@landing/src/app/download/`[platform]/route.ts:
- Around line 10-24: PLATFORM_ALIAS currently maps only hyphenated keys
('mac-arm','mac-intel') so requests using canonical camelCase paths (e.g.,
/download/macArm or /download/macIntel) lose their platform param; update the
PLATFORM_ALIAS object to also include 'macArm': 'macArm' and 'macIntel':
'macIntel' (mapping those keys to the same normalized values used for the
hyphenated forms) so the existing GET function (uses PLATFORM_ALIAS and
normalized) will preserve platform query params for both alias styles.
In `@landing/src/app/download/page.tsx`:
- Around line 73-86: The fetch in the useEffect that calls
fetch('/api/releases') leaves links null on error so platform buttons become
disabled; update the error handler (the .catch in the useEffect that uses
setLinksError) to populate setLinks with a fallback DownloadLinks object (e.g.,
GitHub releases URLs for each platform) so manual download buttons remain
usable, and apply the same change to the other identical block around the
useEffect at lines ~181-192; reference the fetch('/api/releases') call, the
useEffect, the setLinks and setLinksError setters, and the DownloadLinks type
when implementing the fallback.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 1100d080-e3d0-4e7d-a1cc-aae05f9d3c49
📒 Files selected for processing (3)
landing/src/app/download/[platform]/route.tslanding/src/app/download/page.tsxlanding/src/app/page.tsx
| useEffect(() => { | ||
| let cancelled = false; | ||
| fetch('/api/releases') | ||
| .then((r) => { | ||
| if (!r.ok) throw new Error(`releases ${r.status}`); | ||
| return r.json(); | ||
| }) | ||
| .then((data) => { | ||
| if (cancelled) return; | ||
| if (data.downloadLinks) setLinks(data.downloadLinks as DownloadLinks); | ||
| }) | ||
| .catch(() => { | ||
| if (!cancelled) setLinksError(true); | ||
| }); |
There was a problem hiding this comment.
Keep manual downloads usable when /api/releases fails.
On fetch failure, links stays null, so every platform button resolves to # and is disabled, while the UI says users can “Pick your platform manually below.” Provide a fallback, e.g. GitHub releases, when release links cannot be loaded.
Proposed fix
.then((data) => {
if (cancelled) return;
- if (data.downloadLinks) setLinks(data.downloadLinks as DownloadLinks);
+ if (!data.downloadLinks) throw new Error('missing downloadLinks');
+ setLinks(data.downloadLinks as DownloadLinks);
})
.catch(() => {
if (!cancelled) setLinksError(true);
}); {PLATFORMS.map((meta) => {
- const url = links?.[meta.key];
+ const directUrl = links?.[meta.key];
+ const url = directUrl ?? (linksError ? `${GITHUB_REPO}/releases` : undefined);
const isActive = meta.key === platform;
return (
<a
key={meta.key}
href={url ?? '#'}
- download
+ download={directUrl ? true : undefined}
+ target={directUrl ? undefined : '_blank'}
+ rel={directUrl ? undefined : 'noopener noreferrer'}
aria-disabled={!url}
onClick={(e) => {
if (!url) e.preventDefault();
}}Also applies to: 181-192
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@landing/src/app/download/page.tsx` around lines 73 - 86, The fetch in the
useEffect that calls fetch('/api/releases') leaves links null on error so
platform buttons become disabled; update the error handler (the .catch in the
useEffect that uses setLinksError) to populate setLinks with a fallback
DownloadLinks object (e.g., GitHub releases URLs for each platform) so manual
download buttons remain usable, and apply the same change to the other identical
block around the useEffect at lines ~181-192; reference the
fetch('/api/releases') call, the useEffect, the setLinks and setLinksError
setters, and the DownloadLinks type when implementing the fallback.
The hand-rolled Linux SVG path wasn't actually Tux — it was a symmetric placeholder shape. Apple/Windows were close but not canonical either. - Apple + Linux: pulled from @icons-pack/react-simple-icons (SiApple, SiLinux). - Windows: simple-icons drops the Microsoft mark over trademark policy, so the Windows 11 flag is inlined from Microsoft's public brand guidance. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…anchor Hero CTA, navbar link, and footer link were all scrolling to #download (the section at the bottom of the page) instead of going to the new /download page that triggers the actual download. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@landing/src/components/PlatformIcons.tsx`:
- Around line 17-23: The inline Windows SVG in PlatformIcons.tsx is missing an
accessible title; add a <title> element inside the <svg> (e.g., "Windows") and
wire it to the SVG via an accessible attribute (prefer aria-labelledby
referencing the title's id or aria-label if you prefer) and include role="img"
so the screen reader can announce it; update the <svg> that currently has
className, viewBox, fill, xmlns and the <path> (the Windows icon) to include the
title element and the appropriate aria-labelledby/id pairing (ensure the id is
unique or derived from a prop if necessary).
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: c019dc44-1a30-407e-a150-4864ccd6ee49
⛔ Files ignored due to path filters (1)
bun.lockis excluded by!**/*.lock
📒 Files selected for processing (2)
landing/package.jsonlanding/src/components/PlatformIcons.tsx
✅ Files skipped from review due to trivial changes (1)
- landing/package.json
Bun runtime + Next 16 Turbopack dev server intermittently trips a
JavaScriptCore allocator panic ('pas panic: deallocation did fail ...
Alloc bit not set') after a few requests. Dropping --bun keeps Bun as
the package manager but runs next dev on Node, which is stable.
Build + start keep --bun since one-shot invocations don't exhibit the
allocator drift.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ng download
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) <noreply@anthropic.com>
…ates - Delete docs/TROUBLESHOOTING.md; the canonical troubleshooting guide now lives under docs/content/docs/overview/troubleshooting.mdx so it's served from docs.voicebox.sh alongside the rest of the docs. - CONTRIBUTING.md + README.md: repoint "Troubleshooting" references to the new MDX path. README gets a top-level callout so users hit the guide before filing an issue. - PROJECT_STATUS.md: refresh issue/PR counts, document the flash-attn warning (cosmetic on all platforms; CUDA-only, fallback is PyTorch SDPA which is near-FA2 on Ampere+) with per-platform context + community Windows wheels + SageAttention/xformers alternatives, add WebAudio audio-session bug note (tracked separately in PR #486), and expand the Qwen 0.6B→1.7B MLX fallback explanation for triage. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Preserve canonical camelCase platform aliases (macArm, macIntel) in the /download/[platform] redirect so those URLs don't lose their platform param. - Add accessible title + role="img" to the inline Windows SVG so it passes Biome's a11y rule and announces to screen readers. - On /api/releases fetch failure, show an explicit error state with a single intentional link to GitHub releases — no more silent GitHub fallback or disabled-button UX lie. Keeps normies off GitHub unless they opt in. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Summary
Two fixes bundled:
1. API example correctness
ApiSection.tsxpreviously showedengine: "qwen"alongside aninstructfield, but base Qwen3-TTS has no instruct path — that's a Qwen CustomVoice feature. Swapped toengine: "qwen_custom_voice".profile_idwas a slug ("morgan-freeman"); profile IDs arestr(uuid.uuid4())perbackend/services/profiles.py:175. Replaced with a realistic UUID.2. New /download page
Users were clicking download on voicebox.sh, ending up on GitHub's releases page, and filing confused comments ("I ended up on some blog site called GitHub"). Every download CTA now routes through a dedicated
/downloadpage instead of dumping to a file URL or GitHub.What the page does:
?platform=Xornavigator.userAgent.Routing changes:
/download?platform=macArm|macIntel|windows(Linux still →/linux-install)./download/[platform]pretty URLs (used by README and docs) → redirect to/download?platform=Xrather than straight to the asset. External links benefit from the new post-click page too.Test plan
bun devinlanding/, visit/, confirm curl snippet readsengine: "qwen_custom_voice"with a UUID profile_id./download?platform=X, download kicks off, "Your download has started" displays./downloaddirectly on Mac/Win/Linux — confirm auto-detect picks the right platform./download/mac-armdirectly — redirects to/download?platform=macArmand auto-downloads./download— page shows "couldn't reach release server" + disabled buttons, does NOT redirect to GitHub.🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Style
Documentation
Chores