{"record":{"id":"31328c14c3122ab3","repo":"dotnet/aspnetcore","slug":"the-beforeelementselector-selector-is-not-sup","errorCode":null,"errorMessage":"The '${beforeElementSelector}' selector is not supported.","messagePattern":"The '(.+?)' selector is not supported\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/Components/Web.JS/src/Rendering/Renderer.ts","lineNumber":43,"sourceCode":"  let browserRenderer = browserRenderers[browserRendererId];\n  if (!browserRenderer) {\n    browserRenderer = new BrowserRenderer(browserRendererId);\n    browserRenderers[browserRendererId] = browserRenderer;\n  }\n\n  browserRenderer.attachRootComponentToLogicalElement(componentId, logicalElement, appendContent);\n}\n\nexport function attachRootComponentToElement(elementSelector: string, componentId: number, browserRendererId: number): void {\n  const afterElementSelector = '::after';\n  const beforeElementSelector = '::before';\n  let appendContent = false;\n\n  if (elementSelector.endsWith(afterElementSelector)) {\n    elementSelector = elementSelector.slice(0, -afterElementSelector.length);\n    appendContent = true;\n  } else if (elementSelector.endsWith(beforeElementSelector)) {\n    throw new Error(`The '${beforeElementSelector}' selector is not supported.`);\n  }\n\n  const element = getAndRemovePendingRootComponentContainer(elementSelector)\n    || document.querySelector(elementSelector);\n  if (!element) {\n    throw new Error(`Could not find any element matching selector '${elementSelector}'.`);\n  }\n\n  // 'allowExistingContents' to keep any prerendered content until we do the first client-side render\n  // Only client-side Blazor supplies a browser renderer ID\n  attachRootComponentToLogicalElement(browserRendererId, toLogicalElement(element, /* allow existing contents */ true), componentId, appendContent);\n}\n\nexport function getRendererer(browserRendererId: number): BrowserRenderer | undefined {\n  return browserRenderers[browserRendererId];\n}\n\nexport function renderBatch(browserRendererId: number, batch: RenderBatch): void {","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/3600ca084e9c8b5f4174fc5e747f4c52d2100806/src/Components/Web.JS/src/Rendering/Renderer.ts#L25-L61","documentation":"Thrown by attachRootComponentToElement when the element selector ends with '::before'. Blazor supports '::after' to append content after an element, but '::before' is explicitly rejected because appending into a ::before pseudo-position is not meaningful for component rendering. Only ::after is supported as a positional suffix.","triggerScenarios":"Calling attachRootComponentToElement (or configuring a root component selector) with a string ending in '::before', e.g. '#host::before'.","commonSituations":"Developer assumes ::before and ::after are symmetric and tries ::before; a typo; copying CSS pseudo-element intuition into Blazor selectors.","solutions":["Remove the '::before' suffix, or switch to '::after' if you need appended content.","Use a plain CSS selector for the host element and structure the DOM so the component lands where needed.","Add a real child element as an insertion point instead of a pseudo-element."],"exampleFix":"// before (throws)\nattachRootComponentToElement('#host::before', componentId, browserRendererId);\n\n// after\nattachRootComponentToElement('#host', componentId, browserRendererId);\n// or append after the host\nattachRootComponentToElement('#host::after', componentId, browserRendererId);","handlingStrategy":"validation","validationCode":"if (selector.endsWith('::before')) {\n  throw new Error('::before selectors are unsupported; use ::after or a plain selector.');\n}\nattachRootComponentToElement(selector, componentId, browserRendererId);","typeGuard":"function isSupportedSelector(sel: string): boolean {\n  return !sel.endsWith('::before');\n}","tryCatchPattern":null,"preventionTips":["Only use ::after (or no pseudo suffix) for root component selectors.","Review CSS-selector intuition: ::before is intentionally unsupported here.","Add an integration test that asserts selectors are in the allowed set."],"tags":["blazor","rendering","selector","dom"],"backgroundTag":null,"analyzedSha":"3600ca084e9c8b5f4174fc5e747f4c52d2100806","analyzedAt":"2026-08-11T16:32:30.678Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}