withastro/astro · error · Error
Unable to render ${displayName}! This component likely uses
Error message
Unable to render ${displayName}!
This component likely uses ${probableRendererNames},
but Astro encountered an error during server-side rendering.
Please ensure that ${displayName}:
1. Does not unconditionally access browser-specific globals like `window` or `document`.
If this is unavoidable, use the `client:only` hydration directive.
2. Does not conditionally return `null` or `undefined` when rendered on the server.
3. If using multiple JSX frameworks at the same time (e.g. React + Preact), pass the correct `include`/`exclude` options to integrations.
If you're still stuck, please open an issue on GitHub or join us at https://astro.build/chat. What it means
Astro could determine which renderer(s) should handle the component (by extension-derived probable renderer names), but server-side rendering failed or is ambiguous. With exactly one probable renderer it re-runs renderToStaticMarkup to surface that renderer's real error; with several probable renderers (e.g. .jsx with both React and Preact installed) it throws this consolidated guidance message enumerating the classic causes.
Source
Thrown at packages/astro/src/runtime/server/render/component.ts:256
validRenderers.length,
),
hint: AstroErrorData.NoMatchingRenderer.hint(
formatList(probableRendererNames.map((r) => '`' + r + '`')),
),
});
} else if (matchingRenderers.length === 1) {
// We already know that renderer.ssr.check() has failed
// but this will throw a much more descriptive error!
renderer = matchingRenderers[0];
({ html, attrs } = await renderer.ssr.renderToStaticMarkup.call(
{ result },
Component,
propsWithoutTransitionAttributes,
children,
metadata,
));
} else {
throw new Error(`Unable to render ${metadata.displayName}!
This component likely uses ${formatList(probableRendererNames)},
but Astro encountered an error during server-side rendering.
Please ensure that ${metadata.displayName}:
1. Does not unconditionally access browser-specific globals like \`window\` or \`document\`.
If this is unavoidable, use the \`client:only\` hydration directive.
2. Does not conditionally return \`null\` or \`undefined\` when rendered on the server.
3. If using multiple JSX frameworks at the same time (e.g. React + Preact), pass the correct \`include\`/\`exclude\` options to integrations.
If you're still stuck, please open an issue on GitHub or join us at https://astro.build/chat.`);
}
}
} else {
if (metadata.hydrate === 'only') {
html = await renderSlotToString(result, slots?.fallback);
} else {
const componentRenderStartTime = performance.now();View on GitHub (pinned to 52e6c34790)
Solutions
- Guard browser APIs: run them only when !import.meta.env.SSR, or inside useEffect/onMount lifecycle hooks
- Ensure the component returns valid markup in every branch (throw on missing props instead of returning undefined)
- When multiple JSX renderers are installed, give each integration include/exclude patterns so only one matches the file
- As a last resort use client:only="<framework>" so the component renders exclusively in the browser
Example fix
// before
import { initMap } from 'map-lib';
initMap(); // crashes during SSR
// after
import { initMap } from 'map-lib';
if (!import.meta.env.SSR) {
initMap();
} Defensive patterns
Strategy: validation
Validate before calling
// guard browser-only initialization inside the component
if (!import.meta.env.SSR) {
initBrowserLib();
} Type guard
function canUseBrowserApis(): boolean {
return typeof window !== 'undefined';
} Prevention
- Keep window/document/localStorage access out of module top-level scope; run it in onMount/useEffect or behind !import.meta.env.SSR
- Never return undefined from framework components during SSR; throw or render a placeholder instead
- Configure include/exclude on each JSX-framework integration when several are installed
When it happens
Trigger: Component code touching window, document, or localStorage at module top level or during render on the server; a component whose SSR output is null/undefined in a way the renderer rejects; React and Preact (or multiple JSX renderers) configured simultaneously without include/exclude so neither claims the component cleanly.
Common situations: Browser-only libraries (maps, charts, analytics) imported at the top of a component; components that early-return undefined when props are missing during SSR; monorepos or starter templates shipping react + preact together.
Related errors
- Unable to render ${displayName} because it is ${Component}!
- ResponseSentError
- OnlyResponseCanBeReturned
- NoMatchingRenderer
- The view transitions client API was called during a server s
AI-assisted analysis of withastro/astro@52e6c34790 (2026-08-18).
Data as JSON: /api/errors/f5d6302e399d8ecb.
Report an issue: GitHub.