fix(webgl): degrade gracefully when the browser has no WebGL - #282
Merged
Conversation
The MiniTV renders from the root layout, so its three.js canvas mounts on every route. On a browser with hardware acceleration off (also: sandboxed contexts, blocklisted drivers, embedded webviews) getContext returns null, WebGLRenderer throws, and with nothing catching it React unwound the whole tree into Next.js' "This page couldn't load" screen. A decorative 120px television was taking the site down for those users. Adds a cached support probe and a guard component pairing that probe with an error boundary — the probe catches the common case before three.js/ogl construct anything, the boundary catches context loss, driver crashes, exhausted context slots and shaders that won't compile on a given machine. Applied to all four WebGL mount points. The fallback is silent: the scene does not render, everything around it does. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub. 2 Skipped Deployments
|
2 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
MiniTVrenders from the root layout, so its three.js canvas mounts everywhere; whengetContext("webgl")returns null,new WebGLRenderer()throws and React unwinds the whole tree into Next.js' global error screen.WebGLGuardthat pairs it with an error boundary, and applies it to every WebGL mount point. The fallback is silent — the scene doesn't render, everything around it does.Changes
src/lib/webgl.ts— cached probe (webgl2 → webgl → experimental-webgl). Releases the probe context viaWEBGL_lose_contextso it doesn't consume one of the browser's ~16 slots.src/components/webgl/WebGLGuard.tsx— probe + error boundary. The probe handles the common case before three.js/ogl construct anything; the boundary handles context loss, driver crashes, exhausted context slots, and shaders that won't compile on a given machine.src/components/tv/Gnar3DTVScene.tsx— guarded (covers bothMiniTVand the TV hero).src/components/nogglesrails/NogglesRailsGlobe.tsx,src/components/lootbox/AnimatedChest3D.tsx— guarded.src/components/tv/FaultyTerminal.tsx— guarded inside its effect rather than by wrapping, since ogl builds its renderer there and the component's own output is just a container div.src/lib/webgl.test.ts,tests/e2e/webgl-fallback.spec.ts— regression coverage.Test plan
pnpm test— 148 passed (7 new unit cases covering the null-context, throwing-getContext, webgl1-fallback, context-release and caching branches).pnpm exec tsc --noEmitclean;pnpm lintclean apart from one pre-existing warning inBountiesView.tsx;prettier --checkpasses.getContextstubbed to return null for all WebGL ids. Before (fix stashed): homepage shows "This page couldn't load" withError creating WebGL context. After: homepage renders fully with zero page errors, verified at 1440x900 and 390x844. The TV set itself keeps playing —GnarsTVSetis DOM/video, not WebGL.Note: Playwright's headless shell has no WebGL at all, so
webgl-fallback.spec.tspasses headless for the right reason, but the WebGL-working path only exercises under--headedand was verified separately rather than committed as a headed CI test.Generated with Claude Code