Astro
Astro Adapter API
Astro Adapter API
Astro is designed to make it easy to deploy to any cloud provider for on-demand rendering, also known as server-side rendering (SSR). This ability is provided by adapters, which are integrations. See the on-demand rendering guide to learn how to use an existing adapter.
What is an adapter?
An adapter is a special kind of integration that provides an entrypoint for server rendering at request time. An adapter has access to the full Integration API and does two things:
- Implements host-specific APIs for handling requests.
- Configures the build according to host conventions.
Building an adapter
Create an integration and call the setAdapter() function in the astro:config:done hook. This allows you to define a server entrypoint and the features supported by your adapter.
The following example creates an adapter with a server entrypoint and stable support for Astro static output:
},
},
};
}
The setAdapter() function accepts an object containing the following properties:
name
Type: string
Defines a unique name for your adapter. This will be used for logging.
entrypointResolution
Type: "explicit" | "auto"
Default: "explicit"
:::caution[Deprecated]
entrypointResolution: "explicit" is deprecated. entrypointResolution: "auto" will become the default, and only, behavior in a future major version.
See how to migrate. :::
Specifies the method Astro will use to resolve the server entrypoint: "auto" (recommended) or "explicit" (default, but deprecated):
"auto"(recommended): You are responsible for providing a valid module as an entrypoint using eitherserverEntrypointor, if you need further customization at the Vite level usingvite.build.rollupOptions.input."explicit"(deprecated): You must provide the exports required by the host in the server entrypoint using acreateExports()function before passing them tosetAdapter()as anexportslist. This supports adapters built using the Astro 5 version of the Adapter API. By default, all adapters will receive this value to allow backwards compatibility. However, no new adapters should be created with this value. Existing adapters should override this default value with"auto"as soon as they are able to migrate to the new v6 API.
The following example defines the entrypointResolution and serverEntrypoint to tell Astro that a custom entrypoint is provided:
},
},
};
}
The following example defines the entrypointResolution and Rollup options to tell Astro that a custom entrypoint is provided:
},
},
};
}
serverEntrypoint
Type: string | URL
Defines the entrypoint for on-demand rendering.
supportedAstroFeatures
Type: AstroAdapterFeatureMap
A map of Astro's built-in features supported by the adapter. This allows Astro to determine which features an adapter supports, so appropriate error messages can be provided.
adapterFeatures
Type: AstroAdapterFeatures
An object that specifies which adapter features that change the build output are supported by the adapter.
client
Type: { internalFetchHeaders?: Record<string, string> | () => Record<string, string>; assetQueryParams?: URLSearchParams; }
A configuration object for Astro's client-side code.
client.internalFetchHeaders
Type: Record<string, string> | () => Record<string, string>
Defines the headers to inject into Astro's internal fetch calls (e.g. Actions, View Transitions, Server Islands, Prefetch). This can be an object of headers or a function that returns headers.
The following example retrieves a DEPLOY_ID from the environment variables and, if provided, returns an object with the header name as key and the deploy id as value:
return deployId ? { 'Your-Header-ID': deployId } : {};
},
},
});
},
},
};
}
client.assetQueryParams
Type: URLSearchParams
Defines the query parameters to append to all asset URLs (e.g. images, stylesheets, scripts). This is useful for adapters that need to track deployment versions or other metadata.
The following example retrieves a DEPLOY_ID from the environment variables and, if provided, returns an object with a custom search parameter name as key and the deploy id as value:
},
},
};
}
previewEntrypoint
Type: string | URL
Defines the path or ID of a module in the adapter's package that is responsible for starting up the built server when astro preview is run.
},
},
};
}
args
Type: any
:::caution[Deprecated]
This property is deprecated and will be removed in a future major version. Learn how to update your adapter with entrypointResolution: "auto".
:::
A JSON-serializable value that will be passed to the adapter's server entrypoint at runtime. This is useful to pass an object containing build-time configuration (e.g. paths, secrets) to your server runtime code.
The following example defines an args object with a property that identifies where assets generated by Astro are located:
},
},
};
}
exports
Type: string[]
:::caution[Deprecated]
This property is deprecated and will be removed in a future major version. Learn how to update your adapter with entrypointResolution: "auto".
:::
Defines an array of named exports to use in conjunction with the createExports() function of your server entrypoint.
The following example assumes that createExports() provides an export named handler:
},
},
};
}
Custom prerenderer
Adapters can provide a custom prerenderer to control how pages are prerendered by using the setPrerenderer() function in the astro:build:start hook.
The following example shows how an adapter can set a custom prerenderer:
},
async render(request, { routeData }) {
// request: Request, options: { routeData: RouteData }
// Custom rendering logic, e.g. make HTTP requests to a preview server
const response = await fetch(`http://localhost:4321${new URL(request.url).pathname}`);
return response;
},
async teardown() {
// Stop the preview server
}
}));
},
'astro:config:done': ({ setAdapter }) => {
setAdapter({
name: '@example/my-adapter',
entrypointResolution: 'auto',
serverEntrypoint: '@example/my-adapter/server.js',
});
},
},
};
}
The factory function receives the default prerenderer, allowing you to wrap or extend its behavior. This is useful when you only need to customize specific aspects of prerendering.
Building a server entrypoint
You will need to create a file that executes during server-side requests to enable on-demand rendering with your particular host. Astro's adapter API attempts to work with any type of host and gives a flexible way to conform to the host APIs.
You can import and use createApp() to access methods that allow you to work with standard Request and Response objects.
This file should conform to what the host expects. For example, some serverless hosts expect you to export an handler() function:
const app = createApp();
const RESOLVED_VIRTUAL_MODULE_ID = '\0' + VIRTUAL_MODULE_ID;
function createConfigPlugin(config) {
return {
name: VIRTUAL_MODULE_ID,
resolveId: {
filter: {
id: new RegExp(`^${VIRTUAL_MODULE_ID}$`),
},
handler() {
return RESOLVED_VIRTUAL_MODULE_ID;
},
},
load: {
filter: {
id: new RegExp(`^${RESOLVED_VIRTUAL_MODULE_ID}$`),
},
handler() {
return `
export const assets = ${JSON.stringify(config.build.assets)};
`;
},
},
};
}
return {
name: '@example/my-adapter',
hooks: {
'astro:config:setup': ({ config, updateConfig }) => {
_config = config;
updateConfig({
vite: {
plugins: [createConfigPlugin(_config)]
}
})
},
'astro:config:done': ({ config, setAdapter }) => {
_config = config;
setAdapter({
name: '@example/my-adapter',
entrypointResolution: 'auto',
serverEntrypoint: '@example/my-adapter/server.js',
});
},
},
};
}
You can create internal types if needed:
declare module 'virtual:@example/my-adapter:config' {
export const assets: string;
}
You can then import the virtual module:
const app = createApp();
const port = config.port ?? 4321;
const server = createServer(host, port);
return server;
};
Astro features
Astro features are a way for an adapter to tell Astro whether they are able to support a feature, and also the adapter’s level of support.
When using these properties, Astro will:
- run specific validation;
- emit contextual information to the logs;
These operations are run based on the features supported or not supported, their level of support, the desired amount of logging, and the user's own configuration.
The following configuration tells Astro that this adapter has experimental support for the Sharp-powered built-in image service:
},
},
};
}
If the Sharp image service is used, Astro will log a warning and error to the terminal based on your adapter's support:
[@example/my-adapter] The feature is experimental and subject to issues or changes.
[@example/my-adapter] The currently selected adapter `@example/my-adapter` is not compatible with the service "Sharp". Your project will NOT be able to build.
A message can additionally be provided to give more context to the user:
},
},
};
}
This object contains the following configurable features:
staticOutput
Type: AdapterSupport
Defines whether the adapter is able to serve static pages.
hybridOutput
Type: AdapterSupport
Defines whether the adapter is able to serve sites that include a mix of static and on-demand rendered pages.
serverOutput
Type: AdapterSupport
Defines whether the adapter is able to serve on-demand rendered pages.
i18nDomains
Type: AdapterSupport
Defines whether the adapter is able to support i18n domains.
envGetSecret
Type: AdapterSupport
Defines whether the adapter is able to support getSecret() exported from astro:env/server. When enabled, this feature allows your adapter to retrieve secrets configured by users in env.schema.
The following example enables the feature by passing a valid AdapterSupportsKind value to the adapter:
},
},
};
}
The astro/env/setup module allows you to provide an implementation for getSecret(). In your server entrypoint, call setGetEnv() as soon as possible:
return await app.render(request);
}
}
sharpImageService
Type: AdapterSupport
Defines whether the adapter supports image transformation using the built-in Sharp image service.
Adapter features
A set of features that changes the output of the emitted files. When an adapter opts in to these features, they will get additional information inside specific hooks and must implement the proper logic to handle the different output.
middlewareMode
Type: MiddlewareMode
Default: "classic"
Determines at which stage of the page lifecycle the middleware is executed, and how the middleware code is emitted in the build output.
The classic mode matches the default behavior of Astro. On prerendered pages, middleware is run at build time, and when the page is requested, the middleware is not run again. On dynamic pages, middleware is run at request time only. The middleware code is part of your server bundle.
In edge mode, the middleware code can be deployed independently from the server bundle, for example, as an edge function.
},
},
};
}
Then, consume the hook astro:build:ssr, which will give you a middlewareEntryPoint, an URL to the physical file on the file system.
},
'astro:build:ssr': ({ middlewareEntryPoint }) => {
// remember to check if this property exits, it will be `undefined` if the adapter doesn't opt in to the feature
if (middlewareEntryPoint) {
createEdgeMiddleware(middlewareEntryPoint)
}
}
},
};
}
function createEdgeMiddleware(middlewareEntryPoint) {
// emit a new physical file using your bundler
}
buildOutput
Type: "static" | "server"
Default: "server"
Allows you to force a specific output shape for the build. This can be useful for adapters that only work with a specific output type. For example, your adapter might expect a static website so it can create host-specific files. Defaults to server if not specified.
},
},
};
}
staticHeaders
Type: boolean
Default: false
Whether or not the adapter provides support for setting response headers for static pages. When this feature is enabled, Astro will return a map of the Headers emitted by the static pages. This map is available as routeToHeaders in the astro:build:generated hook and can be used to generate platform-specific output that controls HTTP headers, for example, to create a _headers file for platforms that support it.
},
'astro:build:generated': ({ routeToHeaders }) => {
// use `routeToHeaders` to generate a configuration file
// for your virtual host of choice
},
},
};
}
The value of the headers might change based on the features enabled/used by the application. For example, if CSP is enabled, the <meta http-equiv="content-security-policy"> element is not added to the static page. Instead, its content is available in the routeToHeaders map.
preserveBuildClientDir
Type: boolean
Default: false
When true, static builds will preserve the client/server directory structure instead of outputting directly to outDir. This ensures static builds use build.client for assets, maintaining consistency with server builds.
This is useful for adapters that require a specific directory structure regardless of the build output type, such as deploying to platforms with specific file organization requirements.
},
},
};
}
preserveBuildServerDir
Type: boolean
Default: false
When true, static builds will preserve the client/server directory structure for server output instead of outputting directly to outDir. This ensures static builds use build.server for server files, maintaining consistency with server builds.
This is useful for adapters that require a consistent dist/client/ and dist/server/ layout regardless of the build output type, such as when a static site may still contain server islands or image endpoints that need a server entry.
},
},
};
}
Adapter types reference
The following types can be imported from the astro module:
AdapterSupport
Type: AdapterSupportsKind | AdapterSupportWithMessage
A union of valid formats to describe the support level for a feature.
AdapterSupportsKind
Type: "deprecated" | "experimental" | "limited" | "stable" | "unsupported"
Defines the level of support for a feature by your adapter:
- Use
"deprecated"when your adapter deprecates support for a feature before removing it completely in a future version. - Use
"experimental"when your adapter adds support for a feature, but issues or breaking changes are expected. - Use
"limited"when your adapter only supports a subset of the full feature. - Use
"stable"when the feature is fully supported by your adapter. - Use
"unsupported"to warn users that they may encounter build issues in their project, as this feature is not supported by your adapter.
AdapterSupportWithMessage
An object that allows you to define a support level for a feature and a message to be logged in the user console. This object contains the following properties:
AdapterSupportWithMessage.support
Type: Exclude<AdapterSupportsKind, "stable">
Defines the level of support for a feature by your adapter.
AdapterSupportWithMessage.message
Type: string
Defines a custom message to log regarding the support of a feature by your adapter.
AdapterSupportWithMessage.suppress
Type: "default" | "all"
An option to prevent showing some or all logged messages about an adapter's support for a feature.
If Astro's default log message is redundant, or confusing to the user in combination with your custom message, you can use suppress: "default" to suppress the default message and only log your message:
},
},
};
}
You can also use suppress: "all" to suppress all messages about support for the feature. This is useful when these messages are unhelpful to users in a specific context, such as when they have a configuration setting that means they are not using that feature. For example, you can choose to prevent logging any messages about Sharp support from your adapter:
},
},
};
}
MiddlewareMode
Type: "classic" | "edge"
A union of valid formats to describe the mode in which middleware is run.
CreatePreviewServer
Type: (params: PreviewServerParams) => PreviewServer | Promise<PreviewServer>
Describes the function an adapter should export to start a preview server when astro preview is run.
PreviewServer
Type: { host?: string; port: number; closed(): Promise<void>; stop(): Promise<void>; }
Describes an instance of a preview server for the adapter.
PreviewServer.host
Type: string | undefined
Defines the host the preview server is listening on.
PreviewServer.port
Type: number
Defines the port the preview server is listening on.
PreviewServer.closed()
Type: () => Promise<void>
Defines a function that resolves when the preview server has closed.
PreviewServer.stop()
Type: () => Promise<void>
Defines a function to stop the preview server and perform any necessary cleanup.
PreviewServerParams
Type: object
Describes the configuration for the preview server.
PreviewServerParams.outDir
Type: URL
The configured output directory for the build.
PreviewServerParams.client
Type: URL
The configured client assets directory for the build.
PreviewServerParams.server
Type: URL
The configured directory for server JavaScript when building to SSR.
PreviewServerParams.serverEntrypoint
Type: URL
The built server entry module generated by Astro.
PreviewServerParams.host
Type: string | undefined
Specifies the configured host on which the server preview should listen.
PreviewServerParams.port
Type: number
Defines the configured port on which the server preview should listen.
PreviewServerParams.base
Type: string
Specifies the configured base path to deploy to.
PreviewServerParams.logger
Type: AstroIntegrationLogger
Defines an instance of the Astro logger that can be used to write logs when the preview server is running.
PreviewServerParams.headers
Type: OutgoingHttpHeaders | undefined
Describes the configured HTTP response headers.
PreviewServerParams.allowedHosts
Type: string[] | true | undefined
Describes the configured allowed hosts that the preview server should respond to.
PreviewServerParams.root
Type: URL
Specifies the configured root directory of the project.
Allow installation via astro add
The astro add command allows users to easily add integrations and adapters to their project. To allow your adapter to be installed with this command, add astro-adapter to the keywords field in your package.json:
{
"name": "example",
"keywords": ["astro-adapter"],
}
Once you publish your adapter to npm, running astro add example will install your package with any peer dependencies specified in your package.json and instruct users to update their project config manually.