DavidHDev/react-bits · critical · Error
Unable to initialize WebGL.
Error message
Unable to initialize WebGL.
What it means
Tailwind variant of error 2. SplashCursor.getWebGLContext attempts webgl2 then webgl then experimental-webgl; this throw fires only when every context type is unavailable, meaning no WebGL at all.
Source
Thrown at src/ts-tailwind/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
- Probe for any GL context before mounting SplashCursor and skip otherwise.
- Use a real headless Chromium with SwiftShader/ANGLE for automated tests.
- Enable WebGL / update drivers in the user's browser (verify chrome://gpu).
- Render a non-WebGL cursor fallback when no GL context exists.
Example fix
// before
const { gl, ext } = getWebGLContext(canvas);
// after
function anyGL() {
const c = document.createElement('canvas');
return !!(c.getContext('webgl2') || c.getContext('webgl') || c.getContext('experimental-webgl'));
}
if (!anyGL()) return null; 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; }
} 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 before mounting the tailwind SplashCursor.
- Use a GL-capable headless browser in tests, not jsdom.
- Render a plain cursor fallback when no GL context exists.
- Confirm WebGL isn't blocklisted (chrome://gpu).
When it happens
Trigger: getContext('webgl2'), getContext('webgl'), and getContext('experimental-webgl') all return null at src/ts-tailwind/Animations/SplashCursor/SplashCursor.tsx:125-133.
Common situations: jsdom/happy-dom with no GL backend; WebGL disabled via browser flags or driver blocklist; locked-down kiosks; extremely old browsers; environments with no GL driver whatsoever.
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/3bb7ac5660fcda0f.
Report an issue: GitHub.