dotnet/aspnetcore · error · Error

The '${beforeElementSelector}' selector is not supported.

Error message

The '${beforeElementSelector}' selector is not supported.

What it means

Thrown by attachRootComponentToElement when the elementSelector ends with '::before'. Blazor supports appending content '::after' a selector but does not support '::before' (CSS pseudo-elements are not real DOM nodes you can prepend into), so it is explicitly rejected.

Source

Thrown at src/Components/Web.JS/src/Rendering/Renderer.ts:43

  let browserRenderer = browserRenderers[browserRendererId];
  if (!browserRenderer) {
    browserRenderer = new BrowserRenderer(browserRendererId);
    browserRenderers[browserRendererId] = browserRenderer;
  }

  browserRenderer.attachRootComponentToLogicalElement(componentId, logicalElement, appendContent);
}

export function attachRootComponentToElement(elementSelector: string, componentId: number, browserRendererId: number): void {
  const afterElementSelector = '::after';
  const beforeElementSelector = '::before';
  let appendContent = false;

  if (elementSelector.endsWith(afterElementSelector)) {
    elementSelector = elementSelector.slice(0, -afterElementSelector.length);
    appendContent = true;
  } else if (elementSelector.endsWith(beforeElementSelector)) {
    throw new Error(`The '${beforeElementSelector}' selector is not supported.`);
  }

  const element = getAndRemovePendingRootComponentContainer(elementSelector)
    || document.querySelector(elementSelector);
  if (!element) {
    throw new Error(`Could not find any element matching selector '${elementSelector}'.`);
  }

  // 'allowExistingContents' to keep any prerendered content until we do the first client-side render
  // Only client-side Blazor supplies a browser renderer ID
  attachRootComponentToLogicalElement(browserRendererId, toLogicalElement(element, /* allow existing contents */ true), componentId, appendContent);
}

export function getRendererer(browserRendererId: number): BrowserRenderer | undefined {
  return browserRenderers[browserRendererId];
}

export function renderBatch(browserRendererId: number, batch: RenderBatch): void {

View on GitHub (pinned to 294cab2f9b)

Solutions

  1. Use a real container element and append/prepend via your own DOM manipulation instead of '::before'.
  2. Use '::after' (supported) when you only need to append.
  3. Restructure markup so the insertion point is an actual element rather than a pseudo-element.
Defensive patterns

Strategy: validation

Validate before calling

// Reject '::before' selectors before attach.
function assertSelector(s: string) {
  if (s.endsWith('::before')) throw new Error("'::before' is not supported; use a real container");
}

Prevention

When it happens

Trigger: Server attaching a root component with a selector suffixed '::before' (e.g. via component descriptor or RegisterForJavaScript with a prepend target).

Common situations: Assuming symmetric '::after'/'::before' support; copy-paste of an '::after' selector pattern with '::before'; older docs/tutorials implying prepend is supported.

Related errors


AI-assisted analysis of dotnet/aspnetcore@294cab2f9b (2026-08-06). Data as JSON: /api/errors/31328c14c3122ab3. Report an issue: GitHub.