Astro 适配器 API
Astro 可以轻松部署到任何云托管平台,以实现按需渲染,也叫做服务端渲染(SSR)。该能力由适配器集成提供,请参阅 按需渲染指南 了解如何使用现有的适配器。
什么是适配器?
Section titled “什么是适配器?”适配器是一种特殊类型的集成,它为请求时的服务器渲染提供了入口。适配器可以访问完整的集成 API,并执行两项操作:
- 实现托管平台的 API,以处理请求。
- 根据托管平台的约定配置构建过程。
创建一个集成并在 astro:config:done 钩子中调用 setAdapter() 函数。这允许你定义服务器入口点以及适配器支持的功能。
以下示例创建了一个具有服务器入口点并对 Astro 静态输出提供稳定支持的适配器:
export default function createIntegration() { return { name: '@example/my-adapter', hooks: { 'astro:config:done': ({ setAdapter }) => { setAdapter({ name: '@example/my-adapter', serverEntrypoint: '@example/my-adapter/server.js', supportedAstroFeatures: { staticOutput: 'stable' } }); }, }, };}setAdapter() 函数接受一个包含以下属性的对象:
类型: string
为你的适配器定义一个唯一的名称。这将用于日志记录。
serverEntrypoint
Section titled “serverEntrypoint”类型: string | URL
定义按需渲染的入口点。
supportedAstroFeatures
Section titled “supportedAstroFeatures”类型: AstroAdapterFeatureMap
astro@3.0.0
适配器所支持的 Astro 内置功能映射表。这使得 Astro 能够确定适配器支持哪些功能,从而提供相应的错误消息。
adapterFeatures
Section titled “adapterFeatures”类型: AstroAdapterFeatures
astro@3.0.0
一个对象,用于指定适配器支持哪些 会改变构建输出的适配器特性。
类型: any
一个 JSON 可序列化的值,将在运行时传递给适配器的服务器入口点。这对于将包含构建时配置(例如路径、密钥)的对象传递给服务器运行时代码非常有用。
以下示例定义了一个 args 对象,其中包含一个属性,用于标识 Astro 生成的资源所在的位置:
export default function createIntegration() { return { name: '@example/my-adapter', hooks: { 'astro:config:done': ({ config, setAdapter }) => { setAdapter({ name: '@example/my-adapter', serverEntrypoint: '@example/my-adapter/server.js', args: { assets: config.build.assets } }); }, }, };}client
Section titled “client”类型: { internalFetchHeaders?: Record<string, string> | () => Record<string, string>; assetQueryParams?: URLSearchParams; }
astro@5.15.0
Astro 客户端代码的配置对象。
internalFetchHeaders
Section titled “internalFetchHeaders”类型: Record<string, string> | () => Record<string, string>
定义要注入到 Astro 内部 fetch 调用中的请求头(例如 Actions、View Transitions、Server Islands、Prefetch)。这可以是一个 headers 对象或一个返回 headers 的函数。
以下示例从环境变量中检索 DEPLOY_ID,如果提供了该变量,则返回一个对象,其中 header 名称作为键,部署 ID 作为值:
export default function createIntegration() { return { name: '@example/my-adapter', hooks: { 'astro:config:done': ({ config, setAdapter }) => { setAdapter({ name: '@example/my-adapter', serverEntrypoint: '@example/my-adapter/server.js', client: { internalFetchHeaders: () => { const deployId = process.env.DEPLOY_ID; return deployId ? { 'Your-Header-ID': deployId } : {}; }, }, }); }, }, };}assetQueryParams
Section titled “assetQueryParams”类型: URLSearchParams
定义要追加到所有资源 URL (例如图片、样式表、脚本)的查询参数。这对于需要跟踪部署版本或其他元数据的适配器非常有用。
以下示例从环境变量中检索 DEPLOY_ID,如果提供了该变量,则返回一个对象,其中自定义搜索参数名称作为键,部署 ID 作为值:
export default function createIntegration() { return { name: '@example/my-adapter', hooks: { 'astro:config:done': ({ config, setAdapter }) => { setAdapter({ name: '@example/my-adapter', serverEntrypoint: '@example/my-adapter/server.js', client: { assetQueryParams: process.env.DEPLOY_ID ? new URLSearchParams({ yourParam: process.env.DEPLOY_ID }) : undefined, }, }); }, }, };}exports
Section titled “exports”类型: string[]
定义一个命名导出数组,与服务器入口点的 createExports() 函数 配合使用。
以下示例假设 createExports() 提供了一个名为 handler 的导出:
export default function createIntegration() { return { name: '@example/my-adapter', hooks: { 'astro:config:done': ({ config, setAdapter }) => { setAdapter({ name: '@example/my-adapter', serverEntrypoint: '@example/my-adapter/server.js', exports: ['handler'] }); }, }, };}previewEntrypoint
Section titled “previewEntrypoint”类型: string | URL
astro@1.5.0
定义适配器包中负责在运行 astro preview 时启动已构建服务器的模块的路径或 ID。
export default function createIntegration() { return { name: '@example/my-adapter', hooks: { 'astro:config:done': ({ config, setAdapter }) => { setAdapter({ name: '@example/my-adapter', serverEntrypoint: '@example/my-adapter/server.js', previewEntrypoint: '@example/my-adapter/preview.js', }); }, }, };}构建服务器入口点
Section titled “构建服务器入口点”你需要创建一个在服务端请求期间执行的文件,以便为特定的托管平台启用按需渲染。Astro 的适配器 API 旨在与任何类型的托管平台协同工作,并提供了一种灵活的方式来符合托管平台的 API。
createExports()
Section titled “createExports()”类型: (manifest: SSRManifest, options: any) => Record<string, any>
一个导出的函数,接受 SSR 清单作为第一个参数,包含适配器 args 的对象作为第二个参数。这应该提供你的托管平台所需的导出。
例如,某些无服务器托管平台希望你导出一个 handler() 函数。使用适配器 API,你可以通过在服务器入口点中实现 createExports() 来实现这一点:
import { App } from 'astro/app';
export function createExports(manifest) { const app = new App(manifest);
const handler = (event, context) => { // ... };
return { handler };}然后在你的集成中,调用 setAdapter() 的地方,在 exports 中提供此名称:
export default function createIntegration() { return { name: '@example/my-adapter', hooks: { 'astro:config:done': ({ setAdapter }) => { setAdapter({ name: '@example/my-adapter', serverEntrypoint: '@example/my-adapter/server.js', exports: ['handler'], }); }, }, };}你可以通过 createExports() 的第二个参数访问适配器定义的 args。当你在服务器入口点中需要访问构建时配置时,这非常有用。例如,你的服务器可能需要识别 Astro 生成的资源所在的位置:
import { App } from 'astro/app';
export function createExports(manifest, args) { const assetsPath = args.assets;
const handler = (event, context) => { // ... };
return { handler };}start()
Section titled “start()”类型: (manifest: SSRManifest, options: any) => Record<string, any>
一个导出的函数,接受 SSR 清单作为第一个参数,包含适配器 args 的对象作为第二个参数。
某些托管平台希望你自己启动服务器,例如通过监听端口。对于这些类型的托管平台,适配器 API 允许你导出一个 start() 函数,该函数将在运行打包脚本时被调用。
import { App } from 'astro/app';
export function start(manifest) { const app = new App(manifest);
addEventListener('fetch', event => { // ... });}astro/app
Section titled “astro/app”该模块用于渲染已通过 astro build 命令预构建的页面。Astro 使用标准的 Request 和 Response 对象。如果托管方使用不同格式的请求/响应 API,需要在适配器中进行转换处理。
App 构造函数接受必需的 SSR 清单参数,并可选择接受一个用于启用或禁用流式传输的参数,默认为 true。
import { App } from 'astro/app';import http from 'http';
export function start(manifest) { const app = new App(manifest);
addEventListener('fetch', event => { event.respondWith( app.render(event.request) ); });}该模块提供以下几个方法:
app.render()
Section titled “app.render()”类型: (request: Request, options?: RenderOptions) => Promise<Response>
一个方法,接受必需的 request 参数和可选的 RenderOptions 对象。此方法用于匹配符合请求的 Astro 页面,并返回一个 Promise 对象给 Response 。该方法对于不渲染页面的 API 路由同样适用。
const response = await app.render(request);RenderOptions
Section titled “RenderOptions”类型: {addCookieHeader?: boolean; clientAddress?: string; locals?: object; prerenderedErrorPageFetch?: (url: ErrorPagePath) => Promise<Response>; routeData?: RouteData;}
一个控制渲染的对象,包含以下属性:
addCookieHeader
Section titled “addCookieHeader”类型: boolean
默认值: false
是否自动将 Astro.cookie.set() 写入的所有 cookie 添加到响应头中。
当设置为 true 时,它们将作为逗号分隔的键值对添加到响应的 Set-Cookie 头中。你可以使用标准的 response.headers.getSetCookie() API 来单独读取它们。
当设置为 false(默认值)时,这些 cookie 只能从 App.getSetCookieFromResponse(response) 中获取。
const response = await app.render(request, { addCookieHeader: true });clientAddress
Section titled “clientAddress”类型: string
默认值: request[Symbol.for("astro.clientAddress")]
该客户端 IP 地址将作为 Astro.clientAddress 在页面中可用,并作为 API 路由和中间件中的 ctx.clientAddress。
下面的示例读取 x-forwarded-for 头,并将其作为 clientAddress 传递。该值将作为 Astro.clientAddress 提供给用户。
const clientAddress = request.headers.get("x-forwarded-for");const response = await app.render(request, { clientAddress });locals
Section titled “locals”类型: object
context.locals 对象 用于在请求的生命周期中存储和访问信息。
下面的示例读取名为 x-private-header 的头,并尝试将其解析为对象并将其传递给 locals,然后可以将其传递给任何 中间件函数。
const privateHeader = request.headers.get("x-private-header");let locals = {};try { if (privateHeader) { locals = JSON.parse(privateHeader); }} finally { const response = await app.render(request, { locals });}prerenderedErrorPageFetch()
Section titled “prerenderedErrorPageFetch()”类型: (url: ErrorPagePath) => Promise<Response>
默认值: fetch
astro@5.6.0
该函数允许你提供自定义的实现过程,用以获取预渲染的报错页面。
这可用于覆盖默认的 fetch() 行为,例如:当 fetch() 不可用时,又或是当你无法自行调用服务器时。
以下示例读取了磁盘中的 500.html 和 404.html,而不是执行 HTTP 调用:
return app.render(request, { prerenderedErrorPageFetch: async (url: string): Promise<Response> => { if (url.includes("/500")) { const content = await fs.promises.readFile("500.html", "utf-8"); return new Response(content, { status: 500, headers: { "Content-Type": "text/html" }, }); }
const content = await fs.promises.readFile("404.html", "utf-8"); return new Response(content, { status: 404, headers: { "Content-Type": "text/html" }, }); }});如果未提供,Astro 将回退至其默认行为,以获取报错页面。
routeData
Section titled “routeData”类型: RouteData
默认值: app.match(request)
定义路由信息。如果你已经知道要渲染的路由,这将非常有用。这样做将绕过内部调用 app.match() 来确定要渲染的路由。
const routeData = app.match(request);if (routeData) { return app.render(request, { routeData });} else { /* 特定于适配器的 404 响应 */ return new Response(..., { status: 404 });}app.match()
Section titled “app.match()”类型: (request: Request, allowPrerenderedRoutes = false) => RouteData | undefined
判断请求是否匹配 Astro 应用的路由规则。
if(app.match(request)) { const response = await app.render(request);}通常可以在不使用 .match 的情况下调用 app.render(request)。因为当配置了 404.astro 文件后,Astro 就会自动处理 404 的情况。如果想要自定义处理规则,请使用 app.match(request)。
默认情况下,即使匹配到预渲染的路由,也不会返回它们。你可以通过使用 true 作为第二个参数来更改此行为。
app.getAdapterLogger()
Section titled “app.getAdapterLogger()”类型: () => AstroIntegrationLogger
astro@v3.0.0
返回适配器运行时环境可用的 Astro 日志记录器实例。
const logger = app.getAdapterLogger();try { /* 某些可能抛出错误的逻辑 */} catch { logger.error("使用 Astro 日志记录器的自定义错误消息。");}app.getAllowedDomains()
Section titled “app.getAllowedDomains()”类型: () => Partial<RemotePattern>[] | undefined
astro@5.14.2
返回使用按需渲染时允许的传入请求的托管平台模式列表,在用户配置中定义。
app.removeBase()
Section titled “app.removeBase()”类型: (pathname: string) => string
astro@1.6.4
从给定路径中移除基础路径。当你需要从文件系统查找资源时,这非常有用。
app.setCookieHeaders()
Section titled “app.setCookieHeaders()”类型: (response: Response) => Generator<string, string[], any>
astro@1.4.0
返回一个生成器,从 Response 对象中生成单个 cookie 请求头值。这用于正确处理在请求处理期间可能设置的多个 cookie。
以下示例为从响应中获取的每个请求头附加一个 Set-Cookie:
for (const setCookieHeader of app.setCookieHeaders(response)) { response.headers.append('Set-Cookie', setCookieHeader);}App.getSetCookieFromResponse()
Section titled “App.getSetCookieFromResponse()”类型: (response: Response) => Generator<string, string[]>
astro@4.2.0
返回一个生成器,从 Response 对象中生成单个 cookie 请求头值。这与 app.setCookieHeaders() 的工作方式相同,但可以在任何时候使用,因为它是一个静态方法。
以下示例为从响应中获取的每个请求头附加一个 Set-Cookie:
for (const cookie of App.getSetCookieFromResponse(response)) { response.headers.append('Set-Cookie', cookie);}App.validateForwardedHost()
Section titled “App.validateForwardedHost()”类型: (forwardedHost: string, allowedDomains?: Partial<RemotePattern>[], protocol?: string = 'https') => boolean
astro@5.14.2
检查 forwardedHost 是否匹配任何给定的 allowedDomains。此静态方法接受第三个参数,允许你覆盖托管平台协议,默认为 https。
以下示例从头中检索 forwardedHost 并检查托管平台是否匹配允许的域名:
export function start(manifest) { addEventListener('fetch', (event) => { const forwardedHost = event.request.headers.get('X-Forwarded-Host'); if (App.validateForwardedHost(forwardedHost, manifest.allowedDomains)) { /* 执行某些操作 */ } });}App.sanitizeHost()
Section titled “App.sanitizeHost()”类型: (hostname: string | undefined) => string | undefined
astro@5.15.5
通过拒绝任何包含路径分隔符的名称来验证主机名。当主机名无效时,此静态方法将返回 undefined。
以下示例从头中检索 forwardedHost 并对其进行清理:
export function start(manifest) { addEventListener('fetch', (event) => { const forwardedHost = event.request.headers.get('X-Forwarded-Host'); const sanitized = App.sanitizeHost(forwardedHost); });}App.validateForwardedHeaders()
Section titled “App.validateForwardedHeaders()”类型: (forwardedProtocol?: string, forwardedHost?: string, forwardedPort?: string, allowedDomains?: Partial<RemotePattern>[]) => { protocol?: string; host?: string; port?: string }
astro@5.15.5
根据 allowedDomains 验证转发的协议、主机和端口。此静态方法返回验证后的值或对被拒绝的头返回 undefined。
以下示例根据接收到的清单中定义的授权域名验证转发的请求头:
export function start(manifest) { addEventListener('fetch', (event) => { const validated = App.validateForwardedHeaders( request.headers.get('X-Forwarded-Proto') ?? undefined, request.headers.get('X-Forwarded-Host') ?? undefined, request.headers.get('X-Forwarded-Port') ?? undefined, manifest.allowedDomains, ); });}astro/app/node
Section titled “astro/app/node”与 astro/app 类似,该模块用于渲染已通过 astro build 预构建的页面。这允许你创建一个 NodeApp,提供 App 中的所有方法以及适用于 Node 环境的附加方法。
NodeApp 构造函数接受必需的 SSR 清单参数,并可选择接受一个用于启用或禁用流式传输的参数,默认为 true。
import { NodeApp } from 'astro/app/node';import http from 'http';
export function start(manifest) { const nodeApp = new NodeApp(manifest);
addEventListener('fetch', event => { event.respondWith( nodeApp.render(event.request) ); });}提供以下附加方法:
nodeApp.render()
Section titled “nodeApp.render()”类型: (request: NodeRequest | Request, options?: RenderOptions) => Promise<Response>
astro@4.0.0
扩展 app.render(),除了标准的 Request 对象外,还可以接受 Node.js IncomingMessage 对象作为第一个参数。第二个参数是一个可选对象,允许你 控制渲染。
const response = await nodeApp.render(request);nodeApp.match()
Section titled “nodeApp.match()”类型: (req: NodeRequest | Request, allowPrerenderedRoutes?: boolean) => RouteData | undefined
扩展 app.match(),除了标准的 Request 对象外,还可以接受 Node.js IncomingMessage 对象。
if(nodeApp.match(request)) { const response = await nodeApp.render(request);}nodeApp.headersMap
Section titled “nodeApp.headersMap”类型: NodeAppHeadersJson | undefined
默认值: undefined
astro@5.11.0
包含 headers 请求头配置的数组。每个条目将路径名映射到应该为该路由应用的 headers 的列表。这对于将 CSP 指令等 headers 应用于预渲染路由非常有用。
nodeApp.setHeadersMap()
Section titled “nodeApp.setHeadersMap()”类型: (headers: NodeAppHeadersJson) => void
astro@5.11.0
将 headers 配置 加载到 NodeApp 实例中。
nodeApp.setHeadersMap([ { pathname: "/blog", headers: [ { key: "Content-Security-Policy", value: "default-src 'self'" }, ] }]);NodeApp.createRequest()
Section titled “NodeApp.createRequest()”类型: (req: NodeRequest, options?: { skipBody?: boolean; allowedDomains?: Partial<RemotePattern>[]; }) => Request
astro@4.2.0
将 NodeJS IncomingMessage 转换为标准的 Request 对象。此静态方法接受一个可选对象作为第二个参数,允许你定义是否应忽略请求体,默认为 false,以及 allowedDomains。
以下示例创建一个 Request 并将其传递给 app.render():
import { NodeApp } from 'astro/app/node';import { createServer } from 'node:http';
const server = createServer(async (req, res) => { const request = NodeApp.createRequest(req); const response = await app.render(request);})NodeApp.writeResponse()
Section titled “NodeApp.writeResponse()”类型: (source: Response, destination: ServerResponse) => Promise<ServerResponse<IncomingMessage> | undefined>
astro@4.2.0
将 Web 标准 Response 流式传输到 NodeJS 服务器响应中。此静态方法接受一个 Response 对象和初始 ServerResponse,然后返回 ServerResponse 对象的 promise。
以下示例创建一个 Request,将其传递给 app.render(),并写入响应:
import { NodeApp } from 'astro/app/node';import { createServer } from 'node:http';
const server = createServer(async (req, res) => { const request = NodeApp.createRequest(req); const response = await app.render(request); await NodeApp.writeResponse(response, res);})Astro 特性
Section titled “Astro 特性”Astro 特性能是适配器向 Astro 告知其是否支持某项功能以及适配器支持程度的一种方式。
使用这些属性时,Astro 将:
- 运行特定的验证;
- 向日志发出上下文信息;
这些操作基于支持或不支持的特性、支持级别、期望的日志量 和用户自己的配置运行。
以下配置告诉 Astro 该适配器对基于 Sharp 的内置图像服务具有实验性支持:
export default function createIntegration() { return { name: '@example/my-adapter', hooks: { 'astro:config:done': ({ setAdapter }) => { setAdapter({ name: '@example/my-adapter', serverEntrypoint: '@example/my-adapter/server.js', supportedAstroFeatures: { sharpImageService: 'experimental' } }); }, }, };}如果使用了 Sharp 图像服务,Astro 将根据适配器的支持情况向终端记录警告和错误:
[@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.还可以提供一条消息,向用户提供更多上下文:
export default function createIntegration() { return { name: '@example/my-adapter', hooks: { 'astro:config:done': ({ setAdapter }) => { setAdapter({ name: '@example/my-adapter', serverEntrypoint: '@example/my-adapter/server.js', supportedAstroFeatures: { sharpImageService: { support: 'limited', message: 'This adapter has limited support for Sharp. Certain features may not work as expected.' } } }); }, }, };}该对象包含以下可配置的功能:
staticOutput
Section titled “staticOutput”类型: AdapterSupport
定义适配器是否能够提供静态页面。
hybridOutput
Section titled “hybridOutput”类型: AdapterSupport
定义适配器是否能够提供包含静态和按需渲染页面混合的站点。
serverOutput
Section titled “serverOutput”类型: AdapterSupport
定义适配器是否能够提供按需渲染的页面。
i18nDomains
Section titled “i18nDomains”类型: AdapterSupport
astro@4.3.0
定义适配器是否能够支持 i18n 域名。
envGetSecret
Section titled “envGetSecret”类型: AdapterSupport
astro@4.10.0
定义适配器是否能够支持从 astro:env/server 导出的 getSecret()。启用后,此功能允许你的适配器检索用户在 env.schema 中配置的密钥。
以下示例通过向适配器传递 有效的 AdapterSupportsKind 值 来启用该功能:
export default function createIntegration() { return { name: '@example/my-adapter', hooks: { 'astro:config:done': ({ setAdapter }) => { setAdapter({ name: '@example/my-adapter', serverEntrypoint: '@example/my-adapter/server.js', supportedAstroFeatures: { envGetSecret: 'stable' } }); }, }, };}astro/env/setup 模块允许你为 getSecret() 提供一个实现。在 你的服务器入口 中,尽早调用 setGetEnv():
import { App } from 'astro/app';import { setGetEnv } from "astro/env/setup"
setGetEnv((key) => process.env[key])
export function createExports(manifest) { const app = new App(manifest);
const handler = (event, context) => { // ... };
return { handler };}如果适配器支持密钥,请确保在环境变量与请求绑定时,先调用 setGetEnv(),再调用 getSecret():
import type { SSRManifest } from 'astro';import { App } from 'astro/app';import { setGetEnv } from 'astro/env/setup';import { createGetEnv } from '../utils/env.js';
type Env = { [key: string]: unknown;};
export function createExports(manifest: SSRManifest) { const app = new App(manifest);
const fetch = async (request: Request, env: Env) => { setGetEnv(createGetEnv(env));
const response = await app.render(request);
return response; };
return { default: { fetch } };}sharpImageService
Section titled “sharpImageService”类型: AdapterSupport
astro@5.0.0
定义适配器是否支持使用内置 Sharp 图像服务进行图像转换。
一组改变输出文件内容的特性。当适配器选择使用这些特性时,它们将在特定钩子中获得额外信息,并且必须实现适当的逻辑来处理不同的输出。
edgeMiddleware
Section titled “edgeMiddleware”类型: boolean
定义构建时是否将打包任何按需渲染的中间件代码。
启用后,这会阻止中间件代码在构建期间被所有页面打包和导入:
export default function createIntegration() { return { name: '@example/my-adapter', hooks: { 'astro:config:done': ({ setAdapter }) => { setAdapter({ name: '@example/my-adapter', serverEntrypoint: '@example/my-adapter/server.js', adapterFeatures: { edgeMiddleware: true } }); }, }, };}然后,使用钩子 astro:build:ssr,它将给你一个 middlewareEntryPoint,即文件系统上物理文件的 URL。
export default function createIntegration() { return { name: '@example/my-adapter', hooks: { 'astro:config:done': ({ setAdapter }) => { setAdapter({ name: '@example/my-adapter', serverEntrypoint: '@example/my-adapter/server.js', adapterFeatures: { edgeMiddleware: true } }); },
'astro:build:ssr': ({ middlewareEntryPoint }) => { // 记得检查此属性是否存在,如果适配器未选择使用该功能,它将返回 `undefined` if (middlewareEntryPoint) { createEdgeMiddleware(middlewareEntryPoint) } } }, };}
function createEdgeMiddleware(middlewareEntryPoint) { // 使用你的打包器发出一个新的物理文件}buildOutput
Section titled “buildOutput”类型: "static" | "server"
默认值: "server"
astro@5.0.0
允许你强制使用特定的输出形状进行构建。这对于仅适用于特定输出类型的适配器非常有用。例如,你的适配器可能期望静态网站,但使用适配器来创建特定于托管平台的文件。如果未指定,默认为 server。
export default function createIntegration() { return { name: '@example/my-adapter', hooks: { 'astro:config:done': ({ setAdapter }) => { setAdapter({ name: '@example/my-adapter', serverEntrypoint: '@example/my-adapter/server.js', adapterFeatures: { buildOutput: 'static' } }); }, }, };}experimentalStaticHeaders
Section titled “experimentalStaticHeaders”类型: boolean
astro@5.9.3
适配器是否为静态页面设置响应头提供实验性支持。启用此功能后,Astro 将返回静态页面发出的 Headers 的映射。此映射 experimentalRouteToHeaders 在 astro:build:generated 钩子 中可用,用于生成诸如 _headers 之类的文件,允许你对默认 HTTP 请求头进行更改。
export default function createIntegration() { return { name: '@example/my-adapter', hooks: { 'astro:config:done': ({ setAdapter }) => { setAdapter({ name: '@example/my-adapter', serverEntrypoint: '@example/my-adapter/server.js', adapterFeatures: { experimentalStaticHeaders: true, }, }); }, 'astro:build:generated': ({ experimentalRouteToHeaders }) => { // 使用 `experimentalRouteToHeaders` 为你选择的虚拟主机生成配置文件 }, }, };}请求头的值可能会根据应用程序启用/使用的功能而变化。例如,如果 启用了 CSP,则 <meta http-equiv="content-security-policy"> 元素不会添加到静态页面。相反,其 content 在 experimentalRouteToHeaders 映射中可用。
适配器类型引用
Section titled “适配器类型引用”AdapterSupport
Section titled “AdapterSupport”类型: AdapterSupportsKind | AdapterSupportWithMessage
astro@5.0.0
描述特性支持级别的有效格式的联合类型。
AdapterSupportsKind
Section titled “AdapterSupportsKind”类型: "deprecated" | "experimental" | "limited" | "stable" | "unsupported"
定义适配器对特性的支持级别:
- 当你的适配器在未来版本中完全移除某个特性之前弃用对该特性的支持时,使用
"deprecated"。 - 当你的适配器添加了对某个特性的支持,但预计会出现问题或重大更改时,使用
"experimental"。 - 当你的适配器仅支持完整特性的子集时,使用
"limited"。 - 当你的适配器完全支持该特性时,使用
"stable"。 - 使用
"unsupported"警告用户他们的项目可能会遇到构建问题,因为你的适配器不支持此特性。
AdapterSupportWithMessage
Section titled “AdapterSupportWithMessage”
添加于:
astro@5.0.0
一个对象,允许你定义特性的支持程度和要在用户控制台中记录的消息。此对象包含以下属性:
support
Section titled “support”类型: Exclude<AdapterSupportsKind, “stable”>
定义适配器对功能的支持程度。
message
Section titled “message”类型: string
定义关于适配器对特性支持的自定义消息。
suppress
Section titled “suppress”类型: "default" | "all"
astro@5.9.0
一个选项,用于阻止显示关于适配器对特性支持的部分或所有已记录消息。
如果 Astro 的默认日志消息是多余的,或者与你的 自定义 message 结合使用时会让用户感到困惑,你可以使用 suppress: "default" 来抑制默认消息,仅记录你的消息:
export default function createIntegration() { return { name: '@example/my-adapter', hooks: { 'astro:config:done': ({ setAdapter }) => { setAdapter({ name: '@example/my-adapter', serverEntrypoint: '@example/my-adapter/server.js', supportedAstroFeatures: { sharpImageService: { support: 'limited', message: 'The adapter has limited support for Sharp. It will be used for images during build time, but will not work at runtime.', suppress: 'default' // 自定义消息比默认消息更详细 } } }); }, }, };}你也可以使用 suppress: "all" 来抑制有关特性支持的所有消息。当这些消息在特定上下文中对用户没有帮助时,这非常有用,例如当用户有配置设置意味着他们没有使用该特性时。例如,你可以选择阻止从适配器记录任何关于 Sharp 支持的消息:
export default function createIntegration() { return { name: '@example/my-adapter', hooks: { 'astro:config:done': ({ setAdapter }) => { setAdapter({ name: '@example/my-adapter', serverEntrypoint: '@example/my-adapter/server.js', supportedAstroFeatures: { sharpImageService: { support: 'limited', message: 'This adapter has limited support for Sharp. Certain features may not work as expected.', suppress: 'all' } } }); }, }, };}允许通过 astro add 安装
Section titled “允许通过 astro add 安装”astro add 命令 允许用户轻松地将集成和适配器添加到他们的项目中。要允许你的适配器通过此命令安装,将 astro-adapter 添加到 package.json 的 keywords 字段中:
{ "name": "example", "keywords": ["astro-adapter"],}当你 将适配器发布到 npm 后,运行 astro add example 将安装你的包以及 package.json 中指定的任何对等依赖,并指示用户手动更新其项目配置。