DavidHDev/react-bits · critical · Error
Unable to initialize WebGL.
Error message
Unable to initialize WebGL.
What it means
SplashCursor.getWebGLContext tries webgl2, then falls back to 'webgl' and 'experimental-webgl' before giving up. Unlike the InfiniteMenu errors, this only fires when the browser exposes no WebGL of any version. The fluid simulation cannot run without a GL context, so it aborts.
Source
Thrown at src/ts-default/Animations/SplashCursor/SplashCursor.tsx:133
function getWebGLContext(canvas: HTMLCanvasElement) {
const params = {
alpha: true,
depth: false,
stencil: false,
antialias: false,
preserveDrawingBuffer: false
};
let gl = canvas.getContext('webgl2', params) as WebGL2RenderingContext | null;
if (!gl) {
gl = (canvas.getContext('webgl', params) ||
canvas.getContext('experimental-webgl', params)) as WebGL2RenderingContext | null;
}
if (!gl) {
throw new Error('Unable to initialize WebGL.');
}
const isWebGL2 = 'drawBuffers' in gl;
let supportLinearFiltering = false;
let halfFloat: OES_texture_half_float | null = null;
if (isWebGL2) {
(gl as WebGL2RenderingContext).getExtension('EXT_color_buffer_float');
supportLinearFiltering = !!(gl as WebGL2RenderingContext).getExtension('OES_texture_float_linear');
} else {
halfFloat = gl.getExtension('OES_texture_half_float');
supportLinearFiltering = !!gl.getExtension('OES_texture_half_float_linear');
}
gl.clearColor(0, 0, 0, 1);
const halfFloatTexType = isWebGL2View on GitHub (pinned to c7109dccb4)
Solutions
- Use a real headless browser with GL (Chromium with SwiftShader/ANGLE) for tests instead of jsdom.
- Verify WebGL is enabled in the user's browser (chrome://gpu, about:support).
- Re-enable WebGL if disabled via blacklist by updating drivers or removing the blocklist override.
- Guard the effect: only mount SplashCursor when a GL context is available, else render nothing/static.
Example fix
// before
const { gl, ext } = getWebGLContext(canvas);
// after
function supportsWebGL() {
const c = document.createElement('canvas');
return !!(c.getContext('webgl2') || c.getContext('webgl') || c.getContext('experimental-webgl'));
}
if (!supportsWebGL()) return null; // skip mounting SplashCursor Defensive patterns
Strategy: validation
Validate before calling
function supportsAnyWebGL(): boolean {
const c = document.createElement('canvas');
try {
return !!(c.getContext('webgl2') || c.getContext('webgl') || c.getContext('experimental-webgl'));
} catch {
return false;
}
}
// before mounting SplashCursor:
if (!supportsAnyWebGL()) return null; Type guard
function getGL(canvas: HTMLCanvasElement): WebGLRenderingContext | WebGL2RenderingContext | null {
return (canvas.getContext('webgl2') ||
canvas.getContext('webgl') ||
canvas.getContext('experimental-webgl')) as WebGLRenderingContext | null;
} Prevention
- Detect any WebGL support at boot and skip SplashCursor when none exists.
- In tests use a GL-capable headless Chromium rather than jsdom.
- Confirm WebGL is enabled (not blocklisted) in the user's browser via chrome://gpu.
- Render a plain cursor as fallback when no GL context is available.
When it happens
Trigger: All three getContext calls (webgl2, webgl, experimental-webgl) return null at src/ts-default/Animations/SplashCursor/SplashCursor.tsx:127-133. Note the caller at line 108-109 catches via early-return if getWebGLContext throws, so the throw propagates only if the caller doesn't destructure-safeguard.
Common situations: jsdom/happy-dom in unit tests (no GL); WebGL fully disabled via browser flags or blocklist; extremely old browsers; secure/locked-down kiosks; software-only environments with no GL driver at all.
Related errors
- Unable to initialize WebGL.
- No WebGL 2 context!
- No WebGL 2 context!
- No WebGL 2 context!
- No WebGL 2 context!
AI-assisted analysis of DavidHDev/react-bits@c7109dccb4 (2026-08-13).
Data as JSON: /api/errors/ef551d093c780ea8.
Report an issue: GitHub.