Skip to content

Commit ea95c5b

Browse files
bloveclaude
andauthored
refactor(website): host demo videos on Vercel Blob, not in git (#647)
The homepage DemoShowcase clips are large binaries that bloated git history on every recut (~3.6 MB across versions). Move them to a public Vercel Blob store (ngaf-website-assets) and reference absolute URLs; remove them from the repo and re-ignore apps/website/public/demo/ so video bytes never re-enter history. - DemoShowcase: DEMO_CDN constant -> blob URLs (same filenames, stable URLs). - Add apps/website/scripts/upload-demo-media.md runbook. - A follow-up history rewrite purges the already-committed blobs. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 6575653 commit ea95c5b

3 files changed

Lines changed: 53 additions & 2 deletions

File tree

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ deploy/
1414
.nx/workspace-data
1515
tmp/
1616
apps/website/test-results/
17+
# Demo media is hosted on Vercel Blob, not committed (see DemoShowcase.tsx /
18+
# apps/website/scripts/upload-demo-media.md). Keep these binaries out of git.
19+
apps/website/public/demo/
1720
cockpit/**/angular/test-results/
1821
/test-results/
1922

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Homepage demo media (Vercel Blob)
2+
3+
The homepage `DemoShowcase` plays short recorded loops of the LangGraph and
4+
AG-UI demos. These are **large binaries**, so they are NOT committed to git —
5+
they live in a public **Vercel Blob** store and are referenced by absolute URL
6+
from `apps/website/src/components/landing/DemoShowcase.tsx` (`DEMO_CDN`).
7+
8+
- **Store:** `ngaf-website-assets` (id `store_ELgKDAxPSvqCrns1`), team `cacheplane`, public access.
9+
- **Public base:** `https://elgkdaxpsvqcrns1.public.blob.vercel-storage.com/demo`
10+
- **Files:** `{langgraph,ag-ui}-demo.mp4`, `{langgraph,ag-ui}-demo.webm`, `{langgraph,ag-ui}-demo-poster.webp`
11+
12+
`apps/website/public/demo/` is gitignored so these never re-enter history.
13+
14+
## Re-uploading (e.g. a recut)
15+
16+
Uploads use the same pathnames, so the URLs in `DemoShowcase.tsx` stay stable —
17+
no code change needed unless you add/rename a file.
18+
19+
1. Get the store's read-write token (`BLOB_READ_WRITE_TOKEN`). It is connected to
20+
the `threadplane` Vercel project; pull it with the Vercel API or
21+
`vercel env pull` (CLI ≥ 37 also has `vercel blob` commands).
22+
23+
2. Upload each file with a stable pathname (no random suffix):
24+
25+
```bash
26+
curl -X PUT "https://blob.vercel-storage.com/demo/langgraph-demo.mp4" \
27+
-H "authorization: Bearer $BLOB_READ_WRITE_TOKEN" \
28+
-H "x-content-type: video/mp4" \
29+
-H "x-add-random-suffix: 0" \
30+
-H "x-api-version: 7" \
31+
--data-binary @langgraph-demo.mp4
32+
# repeat for .webm (video/webm) and -poster.webp (image/webp), both runtimes
33+
```
34+
35+
3. Verify: `curl -I https://elgkdaxpsvqcrns1.public.blob.vercel-storage.com/demo/langgraph-demo.mp4``200`.
36+
37+
## Producing the clips
38+
39+
The clips are screen recordings of the live demos captured headlessly with
40+
Playwright (`recordVideo`), then trimmed/sped and encoded small with `ffmpeg`
41+
(H.264 mp4 + VP9 webm, first-frame `webp` poster, 1280×800). Keep each file
42+
well under ~1 MB.

apps/website/src/components/landing/DemoShowcase.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,15 @@ interface DemoMedia {
1818
href: string;
1919
}
2020

21+
// Demo media is hosted on Vercel Blob (store: ngaf-website-assets) rather than
22+
// committed to the repo — these clips are large binaries that would bloat git
23+
// history on every recut. Re-uploading with the same pathnames keeps these URLs
24+
// stable. See apps/website/scripts/upload-demo-media.md for the upload steps.
25+
const DEMO_CDN = 'https://elgkdaxpsvqcrns1.public.blob.vercel-storage.com/demo';
26+
2127
const MEDIA: DemoMedia[] = [
22-
{ key: 'langgraph', tabLabel: 'LangGraph', url: 'demo.threadplane.ai', videoMp4: '/demo/langgraph-demo.mp4', videoWebm: '/demo/langgraph-demo.webm', poster: '/demo/langgraph-demo-poster.webp', href: DEMOS.find((d) => d.key === 'langgraph')!.href },
23-
{ key: 'ag-ui', tabLabel: 'AG-UI', url: 'ag-ui.threadplane.ai', videoMp4: '/demo/ag-ui-demo.mp4', videoWebm: '/demo/ag-ui-demo.webm', poster: '/demo/ag-ui-demo-poster.webp', href: DEMOS.find((d) => d.key === 'ag-ui')!.href },
28+
{ key: 'langgraph', tabLabel: 'LangGraph', url: 'demo.threadplane.ai', videoMp4: `${DEMO_CDN}/langgraph-demo.mp4`, videoWebm: `${DEMO_CDN}/langgraph-demo.webm`, poster: `${DEMO_CDN}/langgraph-demo-poster.webp`, href: DEMOS.find((d) => d.key === 'langgraph')!.href },
29+
{ key: 'ag-ui', tabLabel: 'AG-UI', url: 'ag-ui.threadplane.ai', videoMp4: `${DEMO_CDN}/ag-ui-demo.mp4`, videoWebm: `${DEMO_CDN}/ag-ui-demo.webm`, poster: `${DEMO_CDN}/ag-ui-demo-poster.webp`, href: DEMOS.find((d) => d.key === 'ag-ui')!.href },
2430
];
2531

2632
export function DemoShowcase() {

0 commit comments

Comments
 (0)