- 起步
- 核心概念
- 教程
- 基础内容
- 内置功能
- 集成
- 操作指南
- 使用指南
- 配置
- 参考
- 社区资源
- 其他
- 为文档做出贡献
- 手动安装 Astro
- 升级到 Astro v4
- 升级到 Astro v3
- 升级到 Astro v2
- Legacy v0.x Upgrade Guide
- 从 Create React App(CRA)迁移
- 关于本教程
- 第一单元:前期准备
- 准备开发环境
- 创建你的第一个 Astro 项目
- 你的第一行 Astro 代码
- 创建在线代码仓库
- 将你的网站部署到网络
- 第二单元:页面
- 创建你的第一个 Astro 页面
- 编写你的第一篇 Markdown 博客文章
- 添加「关于你」的动态内容
- 给你的「关于」页面添加样式
- 应用全局样式
- 第三单元:组件
- 创建一个可重复使用的导航组件
- 创建社交媒体 footer
- 自己动手搭建导航 Header
- 编写你的第一个浏览器脚本
- 第四单元:布局
- 编写你的第一个布局
- 创建并传递数据到博客布局
- 布局结合,两全其美
- 第五单元 - Astro API
- 创建文章存档页
- 生成标签页面
- 编写标签索引页面
- 添加 RSS 订阅源
- 第六单元 - Astro 群岛
- 搭建你的第一个 Astro 岛屿
- 回到干燥的陆地。让你的博客从白天到黑夜,无需岛屿!
- 恭喜你!
- @astrojs/mdx
- 添加阅读时间
- 创建开发者工具栏应用
- @astrojs/alpinejs
- @astrojs/lit
- @astrojs/preact
- @astrojs/react
- @astrojs/solid-js
- @astrojs/svelte
- @astrojs/vue
- @astrojs/cloudflare
- @astrojs/netlify
- @astrojs/node
- @astrojs/vercel
- @astrojs/db
- @astrojs/markdoc
- @astrojs/partytown
- @astrojs/sitemap
- @astrojs/tailwind
- 使用流式处理来提升页面性能
- 从 Gatsby 迁移
- 从 Next.js 迁移
- 从 NuxtJS 迁移
- 从 Docusaurus 迁移到 Astro
- 从 Eleventy 迁移到 Astro
- 从 GitBook 迁移到 Astro
- 从Gridsome迁移到Astro
- 从 Hugo 迁移
- 从 Jekyll 迁移
- 从 Pelican 迁移
- 从 SvelteKit 迁移
- 从VuePress迁移
- 从 WordPress 迁移
- 状态共享
- Storyblok 与 Astro
- Contentful 与 Astro
- ButterCMS & Astro
- Builder.io & Astro
- Cosmic 与 Astro
- DatoCMS 与 Astro
- Front Matter CMS 与 Astro
- Ghost & Astro
- Hashnode & Astro
- Hygraph 与 Astro
- Keystatic & Astro
- Kontent.ai 与 Astro
- 无头模式的 Statamic 与 Astro
- Strapi 与 Astro
- Tina CMS 与 Astro
- Umbraco & Astro
- 无头(headless)模式的 WordPress 与 Astro
- ApostropheCMS 与 Astro
- Caisy & Astro
- CloudCannon与Astro
- Crystallize 与 Astro
- Decap CMS 与 Astro
- Directus 与 Astro
- KeystoneJS 与 Astro
- microCMS & Astro
- Payload CMS 与 Astro
- Prepr CMS & Astro
- Prismic & Astro
- Sanity & Astro
- Sitecore 体验管理器 & Astro
- Spinal & Astro
- 创作内容
- Firebase 与 Astro
- Supabase 与 Astro
- Turso 和 Astro
- Xata 与 Astro
- Appwrite & Astro
- 部署你的 Astro 站点至 Netlify
- 部署你的 Astro 站点至 Vercel
- 如何将你的 Astro 网站部署到 Deno
- 部署你的 Astro 站点至 GitHub Pages
- 部署你的 Astro 站点至 GitLab Pages
- 部署你的 Astro 站点至 Cloudflare Pages
- 将你的 Astro 网站部署到 AWS
- 将你的 Astro 网站通过 Flightcontrol 部署到 AWS
- 将你的 Astro 网站通过 SST 部署到 AWS
- 将你的 Astro 网站部署至 Google Cloud
- 部署你的 Astro 站点至 Google Firebase 托管
- 将你的 Astro 网站部署到 Heroku
- 将你的 Astro 网站部署到 Microsoft Azure
- 部署你的 Astro 站点至 Buddy
- 将你的 Astro 网站部署到 Edgio
- 将你的 Astro 站点部署到 Fly.io
- 将你的 Astro 网站部署到 Render
- 将你的 Astro 网站部署到 Stormkit
- 将你的 Astro 网站部署到 Surge
- 通过 Cleavr 部署你的 Astro 网站
- 将你的 Astro 站点部署到 Kinsta 应用托管
- 将你的 Astro 网站部署到 Space
- 将你的 Astro 站点部署到 Zeabur
- 将你的 Astro 网站部署到 Zerops
- 添加 RSS 摘要
- 安装一个 Vite 或 Rollup 插件
- 构建自定义图像组件
- 使用 API 路由构建表单
- 在 Astro 页面中构建 HTML 表单
- 在 Astro 中使用 Bun
- 调用服务器端点
- 校验验证码
- 用 Docker 来构建你的 Astro 网站
- 动态导入图片
- 为链接添加图标
- 添加 i18n 功能
- 添加最后修改时间
- 在 Astro 组件中共享状态
- 使用 Tailwind Typography 美化渲染后的 Markdown
- Unknown compiler error.
- Astro.redirect is not available in static mode.
- Astro.clientAddress is not available in current adapter.
- Astro.clientAddress cannot be used inside prerendered routes.
- Astro.clientAddress is not available in static mode.
- No static path found for requested path.
- Invalid type returned by Astro page.
- Missing value for client:media directive.
- No matching renderer found.
- No client entrypoint specified in renderer.
- Missing hint on client:only directive.
- Invalid value returned by a getStaticPaths path.
- Invalid entry inside getStaticPath's return value
- Invalid value returned by getStaticPaths.
- getStaticPaths RSS helper is not available anymore.
- Missing params property on getStaticPaths route.
- Invalid value for getStaticPaths route parameter.
- getStaticPaths() function required for dynamic routes.
- Invalid slot name.
- Cannot use Server-side Rendering without an adapter.
- No import found for component.
- Invalid prerender export.
- Invalid component arguments.
- Page number param not found.
- Image missing required "alt" property.
- Error while loading image service.
- Missing image dimensions
- Failed to retrieve remote image dimensions
- Unsupported image format
- Unsupported image conversion
- Prerendered dynamic endpoint has path collision.
- Expected src to be an image.
- Expected image options.
- Cannot set both densities and widths
- Image not found.
- Could not process image metadata.
- Image not found.
- Could not transform image.
- Unable to set response.
- The middleware didn't return a Response.
- The middleware returned something that is not a Response object.
- The endpoint did not return a Response.
- Value assigned to locals is not accepted.
- Astro.response.headers must not be reassigned.
- Can't load the middleware.
- Local images must be imported.
- Astro.glob() used outside of an Astro file.
- Astro.glob() did not match any files.
- A redirect must be given a location with the Location header.
- Invalid dynamic route.
- Could not find Sharp.
- Unknown Vite Error.
- Could not import file.
- Invalid glob pattern.
- Astro couldn't find the correct page to render
- The provided locale does not exist.
- Index page not found.
- You can't use the current function with the current strategy
- Prerendered routes aren't supported when internationalization domains are enabled.
- 启用了手动国际化路由但没有提供中间件。
- Astro can't render the route.
- Unhandled rejection
- i18n Not Enabled
- Route not found.
- Unknown CSS Error
- CSS Syntax Error
- Unknown Markdown Error.
- Failed to parse Markdown frontmatter.
- Invalid frontmatter injection.
- MDX integration missing.
- Unknown configuration error.
- Specified configuration file not found.
- Legacy configuration detected.
- Unknown CLI Error.
- Failed to generate content types.
- Unknown Content Collection Error.
- Content entry frontmatter does not match schema.
- Invalid content entry slug.
- Content Schema should not contain slug.
- Collection does not exist
- Content and data cannot be in same collection.
- Collection contains entries of a different type.
- Data collection entry failed to parse.
- Duplicate content entry slug.
- Actions must be used with server output.
- Unsupported transform in content config.
Astro 适配器 API
Astro 可以轻松部署到任何云托管平台,以实现服务端渲染(SSR)。该能力由适配器集成提供,请参阅 SSR 指南 了解如何使用现有的适配器。
什么是适配器
适配器是一种特殊类型的集成,它为服务器端渲染提供了入口。适配器包含两项主要功能:
- 实现托管平台的 API,以处理请求。
- 根据托管平台的约定配置构建过程。
构建适配器
由于适配器是一种集成,因此它拥有集成提供的全部能力。
必须 通过在 astro:config:done
钩子中调用 setAdapter
API 来使用适配器,例如:
export default function createIntegration() {
return {
name: '@matthewp/my-adapter',
hooks: {
'astro:config:done': ({ setAdapter }) => {
setAdapter({
name: '@matthewp/my-adapter',
serverEntrypoint: '@matthewp/my-adapter/server.js',
supportedAstroFeatures: {
staticOutput: 'stable'
}
});
},
},
};
}
setAdapter
的传入参数定义如下:
interface AstroAdapter {
name: string;
serverEntrypoint?: string;
previewEntrypoint?: string;
exports?: string[];
args?: any;
adapterFeatures?: AstroAdapterFeatures;
supportedAstroFeatures?: AstroFeatureMap;
}
export interface AstroAdapterFeatures {
/**
* 创建一个与 Astro 中间件通信的边缘函数
*/
edgeMiddleware: boolean;
/**
* 仅 SSR 可用。每个路由都会成为自己的函数/文件
*/
functionPerRoute: boolean;
}
export type SupportsKind = 'unsupported' | 'stable' | 'experimental' | 'deprecated';
export type AstroFeatureMap = {
/**
* 该适配器是否能够为静态页面提供服务
*/
staticOutput?: SupportsKind;
/**
* 该适配器是否能够为静态页面或通过服务器渲染的页面提供服务。
*/
hybridOutput?: SupportsKind;
/**
* 此适配器是否能够为 SSR 页面提供服务
*/
serverOutput?: SupportsKind;
/**
* 此适配器对 assets 的支持程度
*/
assets?: AstroAssetsFeature;
};
export interface AstroAssetsFeature {
supportKind?: SupportsKind;
/**
* 此适配器是否在与库 `sharp` 兼容的环境中部署文件
*/
isSharpCompatible?: boolean;
/**
* 此适配器是否在与库 `squoosh` 兼容的环境中部署文件
*/
isSquooshCompatible?: boolean;
}
这些属性分别是:
- name:适配器的唯一名称,用于日志记录。
- serverEntrypoint:服务端渲染的入口。
- exports:导出数组,与
createExports
配套使用(在下文中说明)。 - adapterFeatures:一个对象,用于启用适配器必须支持的特定功能。这些功能将改变构建输出,适配器必须实现适当的逻辑来处理不同的输出。
- supportedAstroFeatures:Astro 内置功能的映射。这允许 Astro 确定适配器无法或不愿意支持的功能,以便提供适当的错误消息。
服务端入口
Astro 的适配器 API 尝试适配多种类型的托管方,并提供了灵活的配置方式。
Exports
一些无服务架构的托管方会希望你导出一个handler
函数:
export function handler(event, context) {
// ...
}
在适配器 API 中,你可以在 serverEntrypoint
中实现 createExports
方法:
import { App } from 'astro/app';
export function createExports(manifest) {
const app = new App(manifest);
const handler = (event, context) => {
// ...
};
return { handler };
}
在此之后,你需要在 setAdapter
的 exports
属性中配置该 handler
:
export default function createIntegration() {
return {
name: '@matthewp/my-adapter',
hooks: {
'astro:config:done': ({ setAdapter }) => {
setAdapter({
name: '@matthewp/my-adapter',
serverEntrypoint: '@matthewp/my-adapter/server.js', exports: ['handler'],
});
},
},
};
}
Start
有些托管方希望你自行管理服务的启动,例如通过监听一个端口的方式。对于这类托管方,可以导出一个 start
函数,该函数会在绑定脚本执行时被调用。
import { App } from 'astro/app';
export function start(manifest) {
const app = new App(manifest);
addEventListener('fetch', event => {
// ...
});
}
astro/app
该模块用于渲染已通过 astro build
命令预构建的页面。Astro 使用标准的 Request 和 Response 对象。如果托管方使用不同格式的请求/响应 API,需要在适配器中进行转换处理。
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(request: Request, options?: RenderOptions)
此方法用于匹配符合请求的 Astro 页面,并返回一个 Promise 对象给 Response 。该方法对于不渲染页面的 API 路由同样适用。
const response = await app.render(request);
RenderOptions
app.render()
方法接受一个必填的 request
参数,以及一个可选的 RenderOptions
对象,用于 addCookieHeader
、clientAddress
、locals
和 routeData
。
addCookieHeader
是否自动将 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
该客户端 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
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 });
}
routeData
如果你已经知道要渲染的路由,请为 routeData
提供一个值。这样做将绕过内部调用 app.match
来确定要渲染的路由。
const routeData = app.match(request);
if (routeData) {
return app.render(request, { routeData });
} else {
/* 特定于适配器的 404 响应 */
return new Response(..., { status: 404 });
}
app.match(request)
该方法用于判断请求是否匹配 Astro 应用的路由规则。
if(app.match(request)) {
const response = await app.render(request);
}
通常可以在不使用 .match
的情况下调用 app.render(request)
。因为当配置了 404.astro
文件后,Astro 就会自动处理 404 的情况。如果想要自定义处理规则,请使用 app.match(request)
。
使用 astro add
安装适配器
用户可以使用 astro add
命令 轻松地在他们的项目中添加集成和适配器。如果希望其他用户可以使用该命令安装 你的 适配器,请在 package.json
文件的 keywords
项中添加 astro-adapter
属性:
{
"name": "example",
"keywords": ["astro-adapter"],
}
当将适配器发布到 npm 后,执行 astro add example
命令,即可安装适配器以及在 package.json
文件中指定的对等依赖。我们将指导用户手动更新他们的项目配置。
Astro features
添加于: astro@3.0.0
Astro features 是适配器告诉 Astro 它们是否能够支持某个特性的一种方式,也是适配器支持程度的一种方式。
当使用这些属性时,Astro 将:
- 运行特定的验证;
- 抛出(emit)上下文日志;
这些操作是基于支持或不支持的特性、支持程度以及用户使用的配置来运行的。
以下配置告诉 Astro,该适配器对 assets 有实验性支持,但该适配器与内置服务 Sharp 和 Squoosh 不兼容:
my-adapter.mjsexport default function createIntegration() {
return {
name: '@matthewp/my-adapter',
hooks: {
'astro:config:done': ({ setAdapter }) => {
setAdapter({
name: '@matthewp/my-adapter',
serverEntrypoint: '@matthewp/my-adapter/server.js', supportedAstroFeatures: { assets: { supportKind: "experimental", isSharpCompatible: false, isSquooshCompatible: false } }
});
},
},
};
}
Astro 将在终端中记录警告:
/* 该功能是实验性的,可能会出现问题或更改。*/
[@matthewp/my-adapter] The feature is experimental and subject to issues or changes.
或者,如果用于 assets 的服务与适配器不兼容,则会抛出错误:
/* 当前选择的适配器 `@matthewp/my-adapter` 与 "Sharp" 服务不兼容。你的项目将无法构建。*/
[@matthewp/my-adapter] The currently selected adapter `@matthewp/my-adapter` is not compatible with the service "Sharp". Your project will NOT be able to build.
Adapter features
一组可以改变产出文件输出的特性。当适配器选择这些特性时,它们将在特定的钩子中获得额外的信息。
functionPerRoute
这是一个仅在使用 SSR 时启用的功能。默认情况下,Astro 会产出一个 entry.mjs
文件,该文件负责在每个请求上产出渲染的页面。
当 functionPerRoute
为 true
时,Astro 会为项目中定义的每个路由创建一个单独的文件。
每个文件都只会渲染一个页面。页面将在 dist/pages/
目录下(或者在 outDir
所指定目录中的 /pages/
目录下)产出,产出的文件将保持与 src/pages/
目录相同的文件路径。
构建出的 pages/
目录下的文件,将会与 src/pages/
目录下的页面文件的目录结构保持一致,例如:
文件夹dist/
文件夹pages/
文件夹blog/
- entry._slug_.astro.mjs
- entry.about.astro.mjs
- entry.index.astro.mjs
通过将 true
传递给适配器来启用此功能。
export default function createIntegration() {
return {
name: '@matthewp/my-adapter',
hooks: {
'astro:config:done': ({ setAdapter }) => {
setAdapter({
name: '@matthewp/my-adapter',
serverEntrypoint: '@matthewp/my-adapter/server.js', adapterFeatures: { functionPerRoute: true }
});
},
},
};
}
然后,使用 astro:build:ssr
钩子,它将为你提供一个 entryPoints
对象,该对象将页面路由映射到构建后的物理文件。
export default function createIntegration() {
return {
name: '@matthewp/my-adapter',
hooks: {
'astro:config:done': ({ setAdapter }) => {
setAdapter({
name: '@matthewp/my-adapter',
serverEntrypoint: '@matthewp/my-adapter/server.js',
adapterFeatures: {
functionPerRoute: true
}
});
},
'astro:build:ssr': ({ entryPoints }) => { for (const [route, entryFile] of entryPoints) { // 对路由和条目文档执行某些操作 } }
},
};
}
无服务器(Serverless)环境
在无服务器(Serverless)环境中设置 functionPerRoute: true
会为每个路由创建一个 JavaScript 文件(handler)。根据你的托管平台,处理程序可能会有不同的名称:lambda、function、page 等。
每个路由都会在处理程序(handler)运行时受到 冷启动 的影响,这可能会导致一些延迟。这种延迟受到不同因素的影响。
当设置 functionPerRoute: false
时,只有一个单一的处理程序(handler)负责渲染所有路由。当此处理程序(handler)首次触发时,你将受到冷启动的影响。然后,所有其他路由都应该没有延迟。但是,你将无法享受由 functionPerRoute: true
提供的代码拆分(code splitting)所带来的好处。
edgeMiddleware
定义在构建时是否会打包任何 SSR 中间件代码。
启用此功能时,会阻止在构建期间将中间件代码打包并导入到所有页面中:
my-adapter.mjsexport default function createIntegration() {
return {
name: '@matthewp/my-adapter',
hooks: {
'astro:config:done': ({ setAdapter }) => {
setAdapter({
name: '@matthewp/my-adapter',
serverEntrypoint: '@matthewp/my-adapter/server.js', adapterFeatures: { edgeMiddleware: true }
});
},
},
};
}
然后,使用 astro:build:ssr
钩子,它将为你提供一个 middlewareEntryPoint
,一个指向文件系统上物理文件的 URL
。
export default function createIntegration() {
return {
name: '@matthewp/my-adapter',
hooks: {
'astro:config:done': ({ setAdapter }) => {
setAdapter({
name: '@matthewp/my-adapter',
serverEntrypoint: '@matthewp/my-adapter/server.js',
adapterFeatures: {
edgeMiddleware: true
}
});
},
'astro:build:ssr': ({ middlewareEntryPoint }) => { // 请记住检查此属性是否退出,如果适配器未选择加入该功能,则它将是 `undefined` if (middlewareEntryPoint) { createEdgeMiddleware(middlewareEntryPoint) }
}
},
};
}
function createEdgeMiddleware(middlewareEntryPoint) {
// 通过你的打包工具生成一个新的物理文件
}
Reference如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论