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
- Import the component correctly (matching default vs named export).
- Fix typos in the component identifier.
- 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
- Import framework components with the correct default/named form.
- Add `client:only="<framework>"` for browser-only components instead of leaving them undefined.
- Use strict TypeScript to catch undefined bindings at compile time.
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
- Unable to render ${result.pathname} because it contains an u
- Unable to render ${metadata.displayName}! This component li
- Unable to render ${result.pathname} because it contains an u
- The renderer you passed isn't valid. A renderer is usually a
- The renderer name must be provided when adding a server rend
AI-assisted analysis of withastro/astro@d081033d5f (2026-08-12).
Data as JSON: /api/errors/af5ee23d8e6e6b5c.
Report an issue: GitHub.