Experimental Astro Vite plugin
Questi contenuti non sono ancora disponibili nella tua lingua.
@astrojs/vite-plugin-astro lets you use Astro components in any Vite project, without an Astro project around them. Your own server decides what to render: a Hono route, an Express handler, or a worker’s fetch() that renders a component and returns the HTML.
Components work as they do in Astro: scoped styles, <script> tags, and islands of React, Preact, Solid, Svelte, or Vue components that hydrate in the browser.
@astrojs/vite-plugin-astro and @astrojs/runtime are experimental. Their APIs may change in any minor release until they reach 1.0.
Installation
Section titled “Installation”Install the plugin and the runtime:
npm install @astrojs/vite-plugin-astro @astrojs/runtimepnpm add @astrojs/vite-plugin-astro @astrojs/runtimeyarn add @astrojs/vite-plugin-astro @astrojs/runtimeThen add the plugin to your Vite config:
import astro from '@astrojs/vite-plugin-astro';import { defineConfig } from 'vite';
export default defineConfig({ plugins: [astro()],});You can now import .astro files from your server code.
Rendering a component
Section titled “Rendering a component”Import a component in your server code, and render it with renderToResponse() or renderToString() from @astrojs/runtime.
The following example uses a Hono route to render a Page.astro component, with a name prop taken from the URL:
import { renderToResponse } from '@astrojs/runtime';import { Hono } from 'hono';import Page from './components/Page.astro';
const app = new Hono();
app.get('/hello/:name', (c) => renderToResponse(Page, { props: { name: c.req.param('name') } }),);
export default app;Page.astro receives the name prop and can use component props as in any Astro project:
---const { name } = Astro.props;---<html lang="en"> <head> <meta charset="utf-8" /> <title>Hello, {name}</title> </head> <body> <h1>Hello, {name}!</h1> </body></html>
<style> h1 { color: rebeccapurple; }</style>By default, the result is a full HTML document: <!DOCTYPE html> is added, and the stylesheets of the component and its children are added to the <head>. To render part of a page, such as a fragment for htmx or a component inside a page your server renders some other way, pass partial: true.
The following example renders a Card.astro component as an HTML fragment:
import { renderToString } from '@astrojs/runtime';import Card from './components/Card.astro';
const html = await renderToString(Card, { props: { title: 'Hello' }, partial: true });Rendering happens on the server only: call these functions from server code that Vite loads, not from code that runs in the browser.
Adding islands
Section titled “Adding islands”To render components from a UI framework, pass its renderer to astro() and add the framework’s own Vite plugin.
The following example installs the React renderer, the React Vite plugin, and React:
npm install @astrojs/react-renderer @vitejs/plugin-react react react-dompnpm add @astrojs/react-renderer @vitejs/plugin-react react react-domyarn add @astrojs/react-renderer @vitejs/plugin-react react react-domThen, add the renderer and the Vite plugin to your Vite configuration file:
import react from '@astrojs/react-renderer';import astro from '@astrojs/vite-plugin-astro';import viteReact from '@vitejs/plugin-react';import { defineConfig } from 'vite';
export default defineConfig({ plugins: [astro({ renderers: [react()] }), viteReact()],});The renderer tells Astro how to render and hydrate the framework’s components. The framework’s Vite plugin compiles its files, as it would in any Vite project.
You can now use the framework components with any client directive. The following example adds a React Counter to an Astro component, and hydrates it as soon as the page loads:
---import Counter from './Counter.tsx';const { name } = Astro.props;---<body> <h1>Hello, {name}!</h1> <Counter client:load /></body>The rendered HTML includes everything needed to hydrate the island: you don’t need to add any scripts yourself.
The following table lists the renderer and the Vite plugin to use for each framework:
| Framework | Renderer | Vite plugin |
|---|---|---|
| React | react() from @astrojs/react-renderer |
@vitejs/plugin-react |
| Preact | preact() from @astrojs/preact-renderer |
@preact/preset-vite |
| Solid | solid() from @astrojs/solid-js-renderer |
vite-plugin-solid, with ssr: true |
| Svelte | svelte() from @astrojs/svelte-renderer |
@sveltejs/vite-plugin-svelte |
| Vue | vue() from @astrojs/vue-renderer |
@vitejs/plugin-vue |
The order of the plugins doesn’t matter.
To use several JSX frameworks together, tell each one which files are its own with an include option. Pass it to each framework’s Vite plugin, and also to the react() and preact() renderers. solid() takes no options. The following example uses React and Solid components from separate folders:
import react from '@astrojs/react-renderer';import solid from '@astrojs/solid-js-renderer';import astro from '@astrojs/vite-plugin-astro';import viteReact from '@vitejs/plugin-react';import { defineConfig } from 'vite';import viteSolid from 'vite-plugin-solid';
export default defineConfig({ plugins: [ astro({ renderers: [react({ include: ['**/react/*'] }), solid()] }), viteReact({ include: ['**/react/*'] }), viteSolid({ include: ['**/solid/*'], ssr: true }), ],});Developing
Section titled “Developing”Run your server with vite dev, the same way as in any Vite project, for example with @hono/vite-dev-server or your platform’s Vite plugin. Components are compiled when they are requested, and the dev server serves the client code of your islands.
Editing a component updates the page in the browser: style changes are applied without a reload, and other changes reload the page.
Building
Section titled “Building”To build your project, tell Vite where your server code starts with the build input of the ssr environment. You can also choose the output directory of each build.
The following example sets src/app.ts as the entrypoint of the server build, and writes the server and client builds to separate folders:
import astro from '@astrojs/vite-plugin-astro';import { defineConfig } from 'vite';
export default defineConfig({ plugins: [astro()], environments: { ssr: { build: { outDir: 'dist/server', rolldownOptions: { input: { app: 'src/app.ts' } }, }, }, client: { build: { outDir: 'dist/client' } }, },});Running vite build then writes your server code to dist/server/, and the browser code of your components to dist/client/. The client build contains the stylesheets, the islands, the framework’s client code, and the components’ <script> tags. The rendered HTML links to these files.
Serve dist/client/ as static files, as you would for any Vite project with a server. Hosting platforms that deploy a Vite project’s client output as static assets do this for you.
The Astro global
Section titled “The Astro global”In a component rendered by renderToResponse() or renderToString(), the Astro global has the properties that only depend on the component and the render call:
| Property | Value |
|---|---|
Astro.props |
The props passed to the render function, or by the parent component. |
Astro.slots |
The component’s slots. |
Astro.self |
The component itself, for recursive components. |
Astro.request |
The request passed to the render function. Defaults to a GET request for http://localhost/. |
Astro.url |
The URL of Astro.request. |
Astro.site |
The site option of astro(), as a URL. |
Astro.generator |
The Astro version. |
To make request data available to a component, pass the request, or pass the data as props:
app.get('/profile', async (c) => { const user = await getUser(c); return renderToResponse(Profile, { request: c.req.raw, props: { user } });});Limitations
Section titled “Limitations”The following Astro features are not available in components rendered with @astrojs/vite-plugin-astro:
- Pages and routing:
src/pages/,getStaticPaths(), and prerendering. Your server decides which component to render for each request. - Request-level APIs:
Astro.cookies,Astro.params,Astro.redirect(),Astro.locals, actions, sessions, and internationalization helpers. - Server islands (
server:defer). - View transitions (
<ClientRouter />). - Astro’s built-in modules, such as
astro:assets,astro:content, andastro:env. - Content Security Policy, inlining of scripts and stylesheets, and
build.assetsPrefix. - Integrations. Use Vite plugins instead.
Stylesheets are always linked in production, and scoped styles use the attribute strategy.
TypeScript
Section titled “TypeScript”To import .astro files from TypeScript, declare their type:
declare module '*.astro' { import type { AstroComponentFactory } from '@astrojs/runtime/types'; const Component: AstroComponentFactory; export default Component;}Reference
Section titled “Reference”astro() options
Section titled “astro() options”The astro() plugin accepts an optional configuration object whose properties are all also optional.
astro({ site: 'https://example.com', renderers: [react()],});Type: string
The URL your site is deployed to, available as Astro.site.
renderers
Section titled “renderers”Type: AstroRenderer[]
Default: []
The renderers of the UI frameworks your components use. When a component could be handled by more than one renderer, they are tried in this order.
clientDirectives
Section titled “clientDirectives”Type: { name: string; entrypoint: string | URL }[]
Default: []
Custom client directives, in the same shape as the integration API’s addClientDirective().
compressHTML
Section titled “compressHTML”Type: boolean | 'jsx'
Default: 'jsx'
How whitespace in component templates is compressed. See compressHTML.
trailingSlash
Section titled “trailingSlash”Type: 'always' | 'never' | 'ignore'
Default: 'ignore'
See trailingSlash.
publicDir
Section titled “publicDir”Type: string
Default: './public'
The directory of files served as-is, relative to root. A <script src> that points to a file in this directory must use is:inline.
Type: string
Default: Vite’s root
The project root, relative to Vite’s root.
The base URL is Vite’s base: astro() has no base option.
renderToResponse()
Section titled “renderToResponse()”Type: (Component: AstroComponentFactory, options?: RenderOptions) => Promise<Response>
Renders a component to a Response with a Content-Type: text/html header.
renderToString()
Section titled “renderToString()”Type: (Component: AstroComponentFactory, options?: RenderOptions) => Promise<string>
Renders a component to an HTML string.
RenderOptions
Section titled “RenderOptions”renderToResponse() and renderToString() accept an optional object with the following properties.
Type: Record<string, any>
Default: {}
The component’s props, available as Astro.props.
Type: Record<string, string>
Default: {}
HTML for each slot, by slot name. Use default for the default slot.
request
Section titled “request”Type: Request
Default: a GET request for http://localhost/
Available as Astro.request and Astro.url.
partial
Section titled “partial”Type: boolean
Default: false
When false, renders a full document: <!DOCTYPE html> is added, and the stylesheets of the component tree are added to the <head>. When true, renders the component’s HTML only.