Astro
Astro Renderer API
Astro Renderer API
Astro is designed to support any UI framework. This ability is powered by renderers, which are integrations. See the front-end frameworks guide to learn how to use UI components from different frameworks in Astro.
What is a renderer?
A renderer is a special kind of integration that tells Astro how to detect and render component syntaxes it does not handle natively, such as UI framework components. A renderer consists of two parts:
- a server module imported during development and production builds to render components to HTML.
- an optional client module imported in the browser to hydrate components with client directives.
Building a renderer
When you need to add support for a new component syntax in Astro, create an integration and call addRenderer() in the astro:config:setup hook. This allows you to define the server entrypoint that Astro should use for rendering components. Optionally, you can also define the client entrypoint used for hydration.
The following example shows how to register a renderer in an Astro integration:
},
},
};
}
Building a server entrypoint
You will need to create a file that runs during server-side rendering and defines how to render the component syntax. The server module must default-export an object that implements the SSRLoadedRendererValue interface.
The following example shows a minimal server-side renderer implementing check() and renderToStaticMarkup():
async function check(Component: unknown) {
return typeof Component === 'function' && Component.name === 'MyCustomComponent';
}
async function renderToStaticMarkup(
Component: any,
props: Record<string, unknown>,
slots: Record<string, string>,
metadata?: AstroComponentMetadata,
) {
const rendered = Component(props);
return {
attrs: metadata?.hydrate ? { 'data-my-renderer': 'true' } : undefined,
html: `<${rendered.tag}>${rendered.text}${slots.default ?? ''}</${rendered.tag}>`,
};
}
const renderer: NamedSSRLoadedRendererValue = {
name: 'my-renderer',
check,
renderToStaticMarkup,
};
Building a client entrypoint
When your renderer supports client directives, create a client entrypoint that defines how to hydrate components in the browser. The client module must default-export a function that receives the island element and returns an async hydrator function.
Astro dispatches a custom astro:unmount event on the island's root element each time an island is removed from the page. You can listen for this event in your client entrypoint to clean up any mounted application state.
The following example shows a minimal client entrypoint that hydrates components in the browser:
if (client === 'only') {
element.innerHTML = '';
}
const node = document.createElement(rendered.tag);
node.textContent = rendered.text;
element.appendChild(node);
element.addEventListener('astro:unmount', () => node.remove(), { once: true });
};
Renderer types reference
The following types can be imported from the astro module:
AstroComponentMetadata
Type: { displayName: string; hydrate?: 'load' | 'idle' | 'visible' | 'media' | 'only'; hydrateArgs?: any; componentUrl?: string; componentExport?: { value: string; namespace?: boolean }; astroStaticSlot: true; }
Contains information about the component being rendered, including its hydration directive.
AstroComponentMetadata.displayName
Type: string
Defines the component name, used for error messages and debugging.
AstroComponentMetadata.hydrate
Type: 'load' | 'idle' | 'visible' | 'media' | 'only'
Defines the client directive used on the component. If no value is provided, the component will not be hydrated on the client.
Renderers can use this value to conditionally include client-side hydration state. For example, a renderer can skip serializing transfer state for components that will not be hydrated:
async function renderToStaticMarkup(Component, props, children, metadata) {
const willHydrate = !!metadata?.hydrate;
// Skip serializing hydration state if the component won't be hydrated
return render(Component, props, { includeTransferState: willHydrate });
}
AstroComponentMetadata.hydrateArgs
Type: any
Specifies the additional arguments passed to the hydration directive.
For example, this could be the media query string for client:media (i.e. "(max-width: 768px)") or the renderer hint for client:only (i.e. "react").
AstroComponentMetadata.componentUrl
Type: string
Defines the URL of the component's source file.
AstroComponentMetadata.componentExport
Type: { value: string; namespace?: boolean }
Describes the component's export Astro will load on the client for hydrated components.
AstroComponentMetadata.componentExport.namespace
Type: boolean
Indicates whether the export is a namespace export.
AstroComponentMetadata.componentExport.value
Type: string
Defines the name of the export (e.g. "default" for default exports).
AstroComponentMetadata.astroStaticSlot
Type: true
Indicates that Astro supports the static slot optimization for this component. Renderers that set supportsAstroStaticSlot to true can use this in combination with hydrate to determine how to render slots.
AstroRenderer
Type: { name: string; clientEntrypoint?: string | URL; serverEntrypoint: string | URL; }
Describes a component renderer added by an integration.
AstroRenderer.name
Type: string
Defines the unique renderer's public name.
AstroRenderer.clientEntrypoint
Type: string | URL
Defines the import path of the renderer that runs on the client whenever your component is used.
AstroRenderer.serverEntrypoint
Type: string | URL
Defines the import path of the renderer that runs during server-side requests or static builds whenever your component is used.
NamedSSRLoadedRendererValue
Extends SSRLoadedRendererValue with a required name property.
SSRLoadedRenderer
Type: Pick<AstroRenderer, 'name' | 'clientEntrypoint'> & { ssr: SSRLoadedRendererValue; }
Describes a renderer available for the server to use. This is a subset of AstroRenderer with additional properties.
SSRLoadedRenderer.ssr
Type: SSRLoadedRendererValue
Defines the functions and configuration used by the server for this framework.
SSRLoadedRendererValue
Type: object
Contains the functions and configuration necessary to render components on the server from a specific UI framework.
SSRLoadedRendererValue.name
Type: string
Specifies the name identifier for the renderer.
SSRLoadedRendererValue.check()
Type: (Component: any, props: any, slots: Record<string, string>, metadata?: AstroComponentMetadata) => Promise<boolean>
Determines whether the renderer can handle a component. This function is called for each registered renderer until one returns true.
SSRLoadedRendererValue.renderToStaticMarkup()
Type: (Component: any, props: any, slots: Record<string, string>, metadata?: AstroComponentMetadata) => Promise<{ html: string; attrs?: Record<string, string>; }>
Renders a framework component on the server and returns the resulting HTML string along with any optional attributes to be passed to the client entrypoint.
SSRLoadedRendererValue.supportsAstroStaticSlot
Type: boolean
Indicates whether the renderer supports Astro's static slot optimization. When true, Astro prevents the removal of nested slots within islands.
SSRLoadedRendererValue.renderHydrationScript()
Type: () => string
Returns an HTML string to inject once per page before the first hydrated component handled by this renderer. This is useful for renderers that need page-level hydration setup.