Getting a Context

Getting a WebGL 2 Context and Falling Back to WebGL 1

getContext('webgl2') returns a context or null; 'webgl' returns the older WebGL 1 context. A canvas keeps the first kind of context it hands out, so decide once, then query what you got:

Requesting WebGL 2, falling back to WebGL 1, and reporting the GPUJavaScript
const canvas = document.querySelector('canvas');
let gl = canvas.getContext('webgl2', { antialias: true });
const isWebGL2 = gl !== null;
if (!gl) gl = canvas.getContext('webgl');   // GLSL ES 1.00 shaders only
if (!gl) throw new Error('WebGL is unavailable: show a static image instead');
console.log('WebGL 2:', isWebGL2, '|', gl.getParameter(gl.SHADING_LANGUAGE_VERSION));
const info = gl.getExtension('WEBGL_debug_renderer_info');   // may be masked or absent
if (info) console.log(gl.getParameter(info.UNMASKED_RENDERER_WEBGL));
console.log('MAX_TEXTURE_SIZE', gl.getParameter(gl.MAX_TEXTURE_SIZE));
Output
WebGL 2: true | WebGL GLSL ES 3.00 (OpenGL ES GLSL ES 3.0 Chromium)
ANGLE (NVIDIA, NVIDIA GeForce GTX 1650 (0x00001F82) Direct3D11 vs_5_0 ps_5_0, D3D11)
MAX_TEXTURE_SIZE 16384

With WebGL 2 at 96.44% of global usage (caniuse.com 3,038 ), a WebGL 1 branch with GLSL ES 1.00 shaders rarely pays; Three.js 30,815 dropped WebGL 1 in release 163. Still handle null and context loss (Context and WebGL 2).

Requesting WebGL 2, falling back to WebGL 1, and reporting what the browser gaveHTMLLive
<!doctype html>
<style>
  body { margin: 0; font: 13px system-ui, sans-serif; background: #f7f4ee; color: #333; }
  .row { display: flex; gap: 12px; max-width: 600px; align-items: center; }
  canvas { width: 240px; height: 200px; background: #fff; border: 1px solid #ddd; flex: none; }
  table { border-collapse: collapse; flex: 1; }
  td { padding: 4px 6px; border-bottom: 1px solid #e3ddd0; vertical-align: top; word-break: break-word; }
  td:first-child { color: #777; font-size: 11px; white-space: nowrap; }
</style>
<div class="row">
  <canvas id="view" width="480" height="400"></canvas>
  <table id="report"></table>
</div>
<script>
const canvas = document.getElementById('view');
let gl = canvas.getContext('webgl2', { antialias: true });
const isWebGL2 = gl !== null;
if (!gl) gl = canvas.getContext('webgl');          // GLSL ES 1.00 shaders only
if (!gl) throw new Error('WebGL is unavailable: show a static image instead');

// Pick shader sources that match the context we actually received.
const vs = isWebGL2
  ? `#version 300 es
     in vec2 aPos; in vec3 aColor; out vec3 vColor;
     void main() { vColor = aColor; gl_Position = vec4(aPos, 0.0, 1.0); }`
  : `attribute vec2 aPos; attribute vec3 aColor; varying vec3 vColor;
     void main() { vColor = aColor; gl_Position = vec4(aPos, 0.0, 1.0); }`;
const fs = isWebGL2
  ? `#version 300 es
     precision mediump float; in vec3 vColor; out vec4 outColor;
     void main() { outColor = vec4(vColor, 1.0); }`
  : `precision mediump float; varying vec3 vColor;
     void main() { gl_FragColor = vec4(vColor, 1.0); }`;

const program = gl.createProgram();
for (const [type, src] of [[gl.VERTEX_SHADER, vs], [gl.FRAGMENT_SHADER, fs]]) {
  const shader = gl.createShader(type);
  gl.shaderSource(shader, src.trim());   // #version must be the very first line
  gl.compileShader(shader);
  gl.attachShader(program, shader);
}
gl.linkProgram(program);
gl.useProgram(program);

gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer());
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
   0.0,  0.8,   0.12, 0.37, 0.55,
  -0.8, -0.7,   0.87, 0.47, 0.13,
   0.8, -0.7,   0.25, 0.55, 0.30]), gl.STATIC_DRAW);
const aPos = gl.getAttribLocation(program, 'aPos');
const aColor = gl.getAttribLocation(program, 'aColor');
gl.enableVertexAttribArray(aPos);
gl.vertexAttribPointer(aPos, 2, gl.FLOAT, false, 20, 0);
gl.enableVertexAttribArray(aColor);
gl.vertexAttribPointer(aColor, 3, gl.FLOAT, false, 20, 8);
gl.clearColor(1, 1, 1, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.TRIANGLES, 0, 3);

// Report what we got.
const info = gl.getExtension('WEBGL_debug_renderer_info');   // may be masked or absent
const rows = [
  ['Context', isWebGL2 ? 'WebGL 2 (OpenGL ES 3.0)' : 'WebGL 1 fallback (OpenGL ES 2.0)'],
  ['VERSION', gl.getParameter(gl.VERSION)],
  ['SHADING_LANGUAGE_VERSION', gl.getParameter(gl.SHADING_LANGUAGE_VERSION)],
  ['Renderer', info ? gl.getParameter(info.UNMASKED_RENDERER_WEBGL) : '(masked)'],
  ['MAX_TEXTURE_SIZE', gl.getParameter(gl.MAX_TEXTURE_SIZE)],
  ['antialias', gl.getContextAttributes().antialias],
];
document.getElementById('report').innerHTML =
  rows.map(([k, v]) => `<tr><td>${k}</td><td>${v}</td></tr>`).join('');
</script>