تخطَّ إلى المحتوى

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.

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.

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:

my-renderer/index.js
export default function createIntegration() {
return {
name: "@example/my-renderer",
hooks: {
"astro:config:setup": ({ addRenderer }) => {
addRenderer({
name: "@example/my-renderer",
clientEntrypoint: "@example/my-renderer/client.js",
serverEntrypoint: "@example/my-renderer/server.js",
});
},
},
};
}

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():

my-renderer/server.ts
import type { AstroComponentMetadata, NamedSSRLoadedRendererValue } from 'astro';
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,
};
export default renderer;

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:

my-renderer/client.ts
export default (element: HTMLElement) =>
async (
Component: any,
props: Record<string, unknown>,
slots: Record<string, string>,
{ client }: { client: string },
) => {
const rendered = Component({ ...props, slots });
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 });
};

The following types can be imported from the astro module:

import type {
AstroComponentMetadata,
AstroRenderer,
NamedSSRLoadedRendererValue,
SSRLoadedRenderer,
SSRLoadedRendererValue,
} from "astro";

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.

Type: string

Defines the component name, used for error messages and debugging.

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 });
}

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").

Type: string

Defines the URL of the component’s source file.

Type: { value: string; namespace?: boolean }

Describes the component’s export Astro will load on the client for hydrated components.

AstroComponentMetadata.componentExport.namespace
Section titled “AstroComponentMetadata.componentExport.namespace”

Type: boolean

Indicates whether the export is a namespace export.

AstroComponentMetadata.componentExport.value
Section titled “AstroComponentMetadata.componentExport.value”

Type: string

Defines the name of the export (e.g. "default" for default exports).

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.

Type: { name: string; clientEntrypoint?: string | URL; serverEntrypoint: string | URL; }

Describes a component renderer added by an integration.

Type: string

Defines the unique renderer’s public name.

Type: string | URL

Defines the import path of the renderer that runs on the client whenever your component is used.

Type: string | URL

Defines the import path of the renderer that runs during server-side requests or static builds whenever your component is used.

Extends SSRLoadedRendererValue with a required name property.

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.

Type: SSRLoadedRendererValue

Defines the functions and configuration used by the server for this framework.

Type: object

Contains the functions and configuration necessary to render components on the server from a specific UI framework.

Type: string

Specifies the name identifier for the renderer.

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()

Section titled “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

Section titled “SSRLoadedRendererValue.supportsAstroStaticSlot”

Type: boolean

أُضيفت في: astro@2.5.0

Indicates whether the renderer supports Astro’s static slot optimization. When true, Astro prevents the removal of nested slots within islands.

SSRLoadedRendererValue.renderHydrationScript()

Section titled “SSRLoadedRendererValue.renderHydrationScript()”

Type: () => string

أُضيفت في: astro@4.1.0

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.

ساهم المجتمع راعي