From c3ccf9179fae44dd273424d15ab651a191647370 Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Mon, 14 Sep 2026 13:20:02 -0600 Subject: [PATCH] fix(www): skip the careers-page globe when WebGL is unavailable (#50350) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary - `cobe`'s `createGlobe()` resolves the canvas context internally as `getContext('webgl2') || getContext('webgl') || 'experimental-webgl'` (a context-name *string*, not an actual context). When both `webgl2` and `webgl` are unavailable, it falls through to that string, but modern browsers no longer support the `experimental-webgl` context name, so the resulting context is `null` and cobe crashes internally reading `.enable(...)` on it. - `apps/www/components/Globe.tsx` (used only on `/careers`) had no guard for this, so a browser/device with WebGL disabled or unavailable (GPU blocklist, corporate policy, privacy setting) crashes the entire careers page via `globalErrorBoundary`. - Fix: detect WebGL support ourselves (`getContext('webgl2') || getContext('webgl')`) before mounting the globe, and skip rendering it (no globe, rest of the page renders fine) when unsupported. ## Evidence (Sentry, past week) - [WWW-41](https://supabase.sentry.io/issues/7731263201/) — `TypeError: Cannot read properties of null (reading 'enable')` on `/careers`, leaf frame inside `cobe`/`phenomenon`. ## Test plan - [ ] Manually confirmed `Globe.tsx` is only imported by `apps/www/pages/careers.tsx` - [ ] No automated test added (this is a purely decorative, non-interactive canvas element with no existing test coverage); happy to add one if reviewers want it 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01RUrmUfMBpPqkgerh9onNTM --- _Generated by [Claude Code](https://claude.ai/code/session_01RUrmUfMBpPqkgerh9onNTM)_ --------- Co-authored-by: Claude Co-authored-by: Ali Waseem --- apps/www/components/Globe.tsx | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/apps/www/components/Globe.tsx b/apps/www/components/Globe.tsx index 933080d908e..39f190e5d04 100644 --- a/apps/www/components/Globe.tsx +++ b/apps/www/components/Globe.tsx @@ -2,11 +2,25 @@ import createGlobe from 'cobe' import { useTheme } from 'next-themes' import { useEffect, useRef } from 'react' +// cobe crashes internally when neither webgl2 nor webgl is available instead +// of failing gracefully, so we check ourselves before mounting it. +const isWebGLAvailable = (canvas: HTMLCanvasElement) => { + try { + return !!(canvas.getContext('webgl2') || canvas.getContext('webgl')) + } catch { + return false + } +} + const Globe = () => { const { resolvedTheme } = useTheme() const canvasRef = useRef(null) useEffect(() => { + if (!canvasRef.current || !isWebGLAvailable(canvasRef.current)) { + return + } + let rotation = 0 let width = 0 let previousWidth = 0