{"record":{"id":"cd1e374ff15e1bbe","repo":"dotnet/aspnetcore","slug":"unable-to-focus-an-svg-element-that-does-not-have","errorCode":null,"errorMessage":"Unable to focus an SVG element that does not have a tabindex.","messagePattern":"Unable to focus an SVG element that does not have a tabindex\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/Components/Web.JS/src/DomWrapper.ts","lineNumber":18,"sourceCode":"// Licensed to the .NET Foundation under one or more agreements.\n// The .NET Foundation licenses this file to you under the MIT license.\n\nimport '@microsoft/dotnet-js-interop';\n\nexport const domFunctions = {\n  focus,\n  focusBySelector,\n};\n\nfunction focus(element: HTMLOrSVGElement, preventScroll: boolean): void {\n  if (element instanceof HTMLElement) {\n    element.focus({ preventScroll });\n  } else if (element instanceof SVGElement) {\n    if (element.hasAttribute('tabindex')) {\n      element.focus({ preventScroll });\n    } else {\n      throw new Error('Unable to focus an SVG element that does not have a tabindex.');\n    }\n  } else {\n    throw new Error('Unable to focus an invalid element.');\n  }\n}\n\nfunction focusBySelector(selector: string) {\n  const element = document.querySelector(selector) as HTMLElement;\n  if (element) {\n    // If no explicit tabindex is defined, mark it as programmatically-focusable.\n    // This does actually add a new HTML attribute, but it shouldn't interfere with\n    // diffing because diffing only deals with the attributes you have in your code.\n    if (!element.hasAttribute('tabindex')) {\n      element.tabIndex = -1;\n    }\n\n    element.focus({ preventScroll: true });\n  }","sourceCodeStart":1,"sourceCodeEnd":36,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/3600ca084e9c8b5f4174fc5e747f4c52d2100806/src/Components/Web.JS/src/DomWrapper.ts#L1-L36","documentation":"Thrown by the focus() helper in DomWrapper.ts when the target is an SVGElement without a tabindex attribute. Unlike HTMLElement, SVG elements are not focusable by default; Blazor's focus refuses to call element.focus() on such an element because the call would silently do nothing.","triggerScenarios":"Blazor's @focus or a manual focus call targeting an SVG element (e.g. <rect>, <path>, <svg>-based icon button) that lacks a tabindex attribute. Also triggered by focusBySelector-style helpers routed through focus() for SVG targets.","commonSituations":"Focusing an icon or vector graphic for accessibility/keyboard nav without first making it focusable; calling focus on a chart shape, SVG button, or canvas overlay that is an SVG element; keyboard handling on SVG-only widgets.","solutions":["Add tabindex (typically tabindex=\"0\" for tab-order, or tabindex=\"-1\" for programmatic focus) to the SVG element before focusing.","If the SVG is decorative, focus a parent HTMLElement (e.g. a wrapping <button>) instead.","When building an SVG control, expose a focusable HTMLElement layer (button/link) for keyboard interaction.","Pre-check element type and tabindex before invoking focus."],"exampleFix":"<!-- before -->\n<svg><rect id=\"target\" /></svg>\n<script>document.getElementById('target').focus();</script> <!-- throws -->\n\n<!-- after -->\n<svg><rect id=\"target\" tabindex=\"0\" /></svg>\n<script>document.getElementById('target').focus();</script>","handlingStrategy":"type-guard","validationCode":"// Ensure focusability before focusing SVG.\nfunction focusSafe(el) {\n  if (el instanceof SVGElement && !el.hasAttribute('tabindex')) {\n    el.setAttribute('tabindex', '-1');\n  }\n  el.focus();\n}","typeGuard":"function isFocusable(el) {\n  if (el instanceof HTMLElement) return true;\n  if (el instanceof SVGElement) return el.hasAttribute('tabindex');\n  return false;\n}","tryCatchPattern":"try {\n  el.focus();\n} catch (e) {\n  if (/SVG element that does not have a tabindex/.test(e.message)) {\n    el.setAttribute('tabindex', '-1');\n    el.focus();\n  } else throw e;\n}","preventionTips":["Add tabindex to interactive SVG elements in markup.","Focus a wrapping HTMLElement for SVG icons.","Pre-check element type and tabindex before calling focus.","Use focusBySelector where the framework auto-assigns tabindex."],"tags":["dom","focus","svg","accessibility","tabindex"],"backgroundTag":null,"analyzedSha":"3600ca084e9c8b5f4174fc5e747f4c52d2100806","analyzedAt":"2026-08-11T16:32:30.678Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}