withastro/astro · error · Error

Unable to render ${displayName} because it is ${Component}!

Error message

Unable to render ${displayName} because it is ${Component}!
Did you forget to import the component or is it possible there is a typo?

What it means

`renderFrameworkComponent` is called for every framework (React/Vue/Svelte/etc.) component. If the `Component` reference is falsy AND the element does not declare `client:only`, Astro throws — it has no component to render and no instruction to skip server rendering. The message reports the displayName and the falsy value.

Source

Thrown at packages/astro/src/runtime/server/render/component.ts:83

}

const ASTRO_SLOT_EXP = /<\/?astro-slot\b[^>]*>/g;
const ASTRO_STATIC_SLOT_EXP = /<\/?astro-static-slot\b[^>]*>/g;

function removeStaticAstroSlot(html: string, supportsAstroStaticSlot = true) {
	const exp = supportsAstroStaticSlot ? ASTRO_STATIC_SLOT_EXP : ASTRO_SLOT_EXP;
	return html.replace(exp, '');
}

async function renderFrameworkComponent(
	result: SSRResult,
	displayName: string,
	Component: unknown,
	_props: Record<string | number, any>,
	slots: any = {},
): Promise<RenderInstance> {
	if (!Component && 'client:only' in _props === false) {
		throw new Error(
			`Unable to render ${displayName} because it is ${Component}!\nDid you forget to import the component or is it possible there is a typo?`,
		);
	}

	const { renderers, clientDirectives } = result;
	const metadata: AstroComponentMetadata = {
		astroStaticSlot: true,
		displayName,
	};

	const { hydration, isPage, props, propsWithoutTransitionAttributes } = extractDirectives(
		_props,
		clientDirectives,
	);
	let html = '';
	let attrs: Record<string, string> | undefined = undefined;

	if (hydration) {

View on GitHub (pinned to d081033d5f)

Solutions

  1. Import the component correctly (matching default vs named export).
  2. Fix typos in the component identifier.
  3. If the component truly can only run in the browser, add `client:only="<framework>"` so Astro skips server rendering.

Example fix

// before — named import doesn't exist, binding is undefined
import { NotExported } from './Button.tsx';
<NotExported />

// after
import Button from './Button.tsx';
<Button />
Defensive patterns

Strategy: type-guard

Validate before calling

function assertFrameworkComponent(Comp: unknown, displayName: string): void {
  if (!Comp && !arguments[2]) {
    throw new Error(`Cannot render '${displayName}': component is undefined`);
  }
}

Type guard

const isRenderableComponent = (v: unknown): boolean =>
  typeof v === 'function' || typeof v === 'string' || typeof v === 'object';

// In template: only render when defined
{Comp ? <Comp /> : null}

Prevention

When it happens

Trigger: A framework component variable is `undefined`/`null` (missing import, typo, failed resolution) and the tag is not `client:only`; importing a named export that doesn't exist so the binding is undefined; conditional component that resolved to undefined.

Common situations: Forgot to import the framework component; named/default import mismatch; renamed export without updating the import; integration/render-processor that stripped the binding.

Related errors


AI-assisted analysis of withastro/astro@d081033d5f (2026-08-12). Data as JSON: /api/errors/af5ee23d8e6e6b5c. Report an issue: GitHub.