My page content, wrapped in a layout!
Published on {publishDate}
Viewed by {viewCount} folks
Written on: {frontmatter.date}
``` 你可以使用 `MarkdownLayoutProps` 助手设置布局的 [`Props` 型](/en/guides/typescript/#component-props): ¥You can set a layout’s [`Props` type](/en/guides/typescript/#component-props) with the `MarkdownLayoutProps` helper: src/layouts/BlogPostLayout.astro ```diff --- +import type { MarkdownLayoutProps } from 'astro'; +type Props = MarkdownLayoutProps<{ +// Define frontmatter props here + title: string; + author: string; + date: string; +}>; // Now, `frontmatter`, `url`, and other Markdown layout properties // are accessible with type safety const { frontmatter, url } = Astro.props; ---Written on: {frontmatter.date}
``` ### Markdown 布局属性 [Section titled “Markdown 布局属性”](#markdown-布局属性) ¥Markdown Layout Props Markdown 布局将能够通过 `Astro.props` 访问以下信息: ¥A Markdown layout will have access to the following information via `Astro.props`: * `file` - 此文件的绝对路径(例如 `/home/user/projects/.../file.md`)。 * `url` - 页面的 URL(例如 `/en/guides/markdown-content`)。 * `frontmatter` - Markdown 或 MDX 文档中的所有前言。 * `frontmatter.file` - 与顶层 `file` 属性相同。 * `frontmatter.url` - 与顶层 `url` 属性相同。 * `headings` - Markdown 或 MDX 文档中的标题 (`h1 -> h6`) 列表以及相关元数据。该列表遵循以下类型:`{ depth: number; slug: string; text: string }[]`。 * `rawContent()` - 以字符串形式返回原始 Markdown 文档的函数。 * `compiledContent()` - 返回编译为 HTML 字符串的 Markdown 文档的异步函数。 Note A Markdown layout will have access to all the Markdown file’s [available properties](/en/guides/markdown-content/#available-properties) from `Astro.props` **with two key differences:** * Heading information (i.e. `h1 -> h6` elements) is available via the `headings` array, rather than a `getHeadings()` function. * `file` and `url` are *also* available as nested `frontmatter` properties (i.e. `frontmatter.url` and `frontmatter.file`). ### 手动导入布局 (MDX) [Section titled “手动导入布局 (MDX)”](#手动导入布局-mdx) ¥Importing Layouts Manually (MDX) 你还可以使用 MDX 文件前言中的特殊 Markdown 布局属性,以相同的方式将 `frontmatter` 和 `headings` 属性直接传递给指定的布局组件。 ¥You can also use the special Markdown layout property in the frontmatter of MDX files to pass `frontmatter` and `headings` props directly to a specified layout component in the same way. 要将前置内容中不存在(或无法存在)的信息传递给 MDX 布局,你可以导入并使用 `{fancyJsHelper()}
``` 使用任何布局时(通过 frontmatter `layout` 属性或通过导入布局),你必须在布局中包含 `` 标签,因为 Astro 将不再自动将其添加到你的 MDX 页面。 ¥When using any layout (either through the frontmatter `layout` property or by importing a layout), you must include the `` tag in your layout as Astro will no longer add it automatically to your MDX page. Learn more about Astro’s Markdown and MDX support in our [Markdown guide](/en/guides/markdown-content/). ## 嵌套布局 [Section titled “嵌套布局”](#嵌套布局) ¥Nesting Layouts 布局组件不需要包含整个页面的 HTML。你可以将布局分解为更小的组件,并组合布局组件以创建更灵活的页面模板。当你想要跨多个布局共享某些代码时,此模式非常有用。 ¥Layout components do not need to contain an entire page worth of HTML. You can break your layouts into smaller components, and combine layout components to create even more flexible, page templates. This pattern is useful when you want to share some code across multiple layouts. 例如,`BlogPostLayout.astro` 布局组件可以设置帖子标题、日期和作者的样式。然后,站点范围的 `BaseLayout.astro` 可以处理页面模板的其余部分,例如导航、页脚、SEO 元标记、全局样式和字体。你还可以将从帖子收到的属性传递到另一个布局,就像任何其他嵌套组件一样。 ¥For example, a `BlogPostLayout.astro` layout component could style a post’s title, date and author. Then, a site-wide `BaseLayout.astro` could handle the rest of your page template, like navigation, footers, SEO meta tags, global styles, and fonts. You can also pass props received from your post to another layout, just like any other nested component. src/layouts/BlogPostLayout.astro ```astro --- import BaseLayout from './BaseLayout.astro'; const { frontmatter } = Astro.props; ---Unable to sign up. Please try again later.
)} ``` 如需更多自定义,你可以使用 [使用 `isInputError()` 实用程序](#displaying-form-input-errors) 检查错误是否由无效输入引起。 ¥For more customization, you can [use the `isInputError()` utility](#displaying-form-input-errors) to check whether an error is caused by invalid input. 以下示例在提交无效电子邮件时在 `email` 输入字段下渲染错误横幅: ¥The following example renders an error banner under the `email` input field when an invalid email is submitted: src/pages/index.astro ```diff --- import { actions, isInputError } from 'astro:actions'; const result = Astro.getActionResult(actions.newsletter); +const inputErrors = isInputError(result?.error) ? result.error.fields : {}; --- ``` #### 发生错误时保留输入值 [Section titled “发生错误时保留输入值”](#发生错误时保留输入值) ¥Preserve input values on error 每当提交表单时,输入都会被清除。要保留输入值,你可以启用 [启用视图转换](/en/guides/view-transitions/#enabling-view-transitions-spa-mode) 并将 `transition:persist` 指令应用于每个输入: ¥Inputs will be cleared whenever a form is submitted. To persist input values, you can [enable view transitions](/en/guides/view-transitions/#enabling-view-transitions-spa-mode) and apply the `transition:persist` directive to each input: ```astro ``` ### 使用表单操作结果更新 UI [Section titled “使用表单操作结果更新 UI”](#使用表单操作结果更新-ui) ¥Update the UI with a form action result 要使用操作的返回值在成功时向用户显示通知,请将操作传递给 `Astro.getActionResult()`。使用返回的 `data` 属性来渲染你想要显示的 UI。 ¥To use an action’s return value to display a notification to the user on success, pass the action to `Astro.getActionResult()`. Use the returned `data` property to render the UI you want to display. 此示例使用 `addToCart` 操作返回的 `productName` 属性显示成功消息。 ¥This example uses the `productName` property returned by an `addToCart` action to show a success message. src/pages/products/\[slug].astro ```astro --- import { actions } from 'astro:actions'; const result = Astro.getActionResult(actions.addToCart); --- {result && !result.error && (Added {result.data.productName} to cart
)} ``` ### 高级:通过会话保留操作结果 [Section titled “高级:通过会话保留操作结果”](#高级通过会话保留操作结果) ¥Advanced: Persist action results with a session **Added in:** `astro@5.0.0` 操作结果显示为 POST 提交。这意味着当用户关闭并重新访问页面时,结果将重置为 `undefined`。如果用户尝试刷新页面,他们还将看到 “确认表单重新提交?” 对话框。 ¥Action results are displayed as a POST submission. This means that the result will be reset to `undefined` when a user closes and revisits the page. The user will also see a “confirm form resubmission?” dialog if they attempt to refresh the page. 要自定义此行为,你可以添加中间件来手动处理操作的结果。你可以选择使用 cookie 或会话存储来持久保存操作结果。 ¥To customize this behavior, you can add middleware to handle the result of the action manually. You may choose to persist the action result using a cookie or session storage. 从 `astro:actions` 开始,从 [creating a middleware file](/en/guides/middleware/) and importing [the `getActionContext()` utility](/en/reference/modules/astro-actions/#getactioncontext) 开始。此函数返回一个 `action` 对象,其中包含有关传入操作请求的信息,包括操作处理程序以及该操作是否从 HTML 表单调用。`getActionContext()` 还返回 `setActionResult()` 和 `serializeActionResult()` 函数以编程方式设置 `Astro.getActionResult()` 返回的值: ¥Start by [creating a middleware file](/en/guides/middleware/) and importing [the `getActionContext()` utility](/en/reference/modules/astro-actions/#getactioncontext) from `astro:actions`. This function returns an `action` object with information about the incoming action request, including the action handler and whether the action was called from an HTML form. `getActionContext()` also returns the `setActionResult()` and `serializeActionResult()` functions to programmatically set the value returned by `Astro.getActionResult()`: src/middleware.ts ```ts import { defineMiddleware } from 'astro:middleware'; import { getActionContext } from 'astro:actions'; export const onRequest = defineMiddleware(async (context, next) => { const { action, setActionResult, serializeActionResult } = getActionContext(context); if (action?.calledFrom === 'form') { const result = await action.handler(); // ... handle the action result setActionResult(action.name, serializeActionResult(result)); } return next(); }); ``` 持久化 HTML 表单结果的常见做法是 [POST / Redirect / GET pattern](https://en.wikipedia.org/wiki/Post/Redirect/Get)。此重定向会在页面刷新时删除 “确认表单重新提交?” 对话框,并允许操作结果在整个用户会话期间保持不变。 ¥A common practice to persist HTML form results is the [POST / Redirect / GET pattern](https://en.wikipedia.org/wiki/Post/Redirect/Get). This redirect removes the “confirm form resubmission?” dialog when the page is refreshed, and allows action results to be persisted throughout the user’s session. 此示例将 POST / Redirect / GET 模式应用于安装了 [Netlify 服务器适配器](/en/guides/integrations-guide/netlify/) 的会话存储的所有表单提交。操作结果使用 [Netlify Blob](https://docs.netlify.com/blobs/overview/) 写入会话存储,并在重定向后使用会话 ID 检索: ¥This example applies the POST / Redirect / GET pattern to all form submissions using session storage with the [Netlify server adapter](/en/guides/integrations-guide/netlify/) installed. Action results are written to a session store using [Netlify Blob](https://docs.netlify.com/blobs/overview/), and retrieved after a redirect using a session ID: src/middleware.ts ```ts import { defineMiddleware } from 'astro:middleware'; import { getActionContext } from 'astro:actions'; import { randomUUID } from "node:crypto"; import { getStore } from "@netlify/blobs"; export const onRequest = defineMiddleware(async (context, next) => { // Skip requests for prerendered pages if (context.isPrerendered) return next(); const { action, setActionResult, serializeActionResult } = getActionContext(context); // Create a Blob store to persist action results with Netlify Blob const actionStore = getStore("action-session"); // If an action result was forwarded as a cookie, set the result // to be accessible from `Astro.getActionResult()` const sessionId = context.cookies.get("action-session-id")?.value; const session = sessionId ? await actionStore.get(sessionId, { type: "json", }) : undefined; if (session) { setActionResult(session.actionName, session.actionResult); // Optional: delete the session after the page is rendered. // Feel free to implement your own persistence strategy await actionStore.delete(sessionId); context.cookies.delete("action-session-id"); return next(); } // If an action was called from an HTML form action, // call the action handler and redirect to the destination page if (action?.calledFrom === "form") { const actionResult = await action.handler(); // Persist the action result using session storage const sessionId = randomUUID(); await actionStore.setJSON(sessionId, { actionName: action.name, actionResult: serializeActionResult(actionResult), }); // Pass the session ID as a cookie // to be retrieved after redirecting to the page context.cookies.set("action-session-id", sessionId); // Redirect back to the previous page on error if (actionResult.error) { const referer = context.request.headers.get("Referer"); if (!referer) { throw new Error( "Internal: Referer unexpectedly missing from Action POST request.", ); } return context.redirect(referer); } // Redirect to the destination page on success return context.redirect(context.originPathname); } return next(); }); ``` ## 使用操作时的安全性 [Section titled “使用操作时的安全性”](#使用操作时的安全性) ¥Security when using actions 操作可根据操作名称作为公共端点访问。例如,操作 `blog.like()` 可从 `/_actions/blog.like` 访问。这对于单元测试操作结果和调试生产错误很有用。但是,这意味着你必须使用与 API 端点和按需渲染页面相同的授权检查。 ¥Actions are accessible as public endpoints based on the name of the action. For example, the action `blog.like()` will be accessible from `/_actions/blog.like`. This is useful for unit testing action results and debugging production errors. However, this means you **must** use same authorization checks that you would consider for API endpoints and on-demand rendered pages. ### 从操作处理程序授权用户 [Section titled “从操作处理程序授权用户”](#从操作处理程序授权用户) ¥Authorize users from an action handler 要授权操作请求,请向你的操作处理程序添加身份验证检查。你可能希望使用 [身份验证库](/en/guides/authentication/) 来处理会话管理和用户信息。 ¥To authorize action requests, add an authentication check to your action handler. You may want to use [an authentication library](/en/guides/authentication/) to handle session management and user information. 操作公开完整的 `APIContext` 对象以访问使用 `context.locals` 从中间件传递的属性。当用户未获得授权时,你可以使用 `UNAUTHORIZED` 代码引发 `ActionError`: ¥Actions expose the full `APIContext` object to access properties passed from middleware using `context.locals`. When a user is not authorized, you can raise an `ActionError` with the `UNAUTHORIZED` code: src/actions/index.ts ```ts import { defineAction, ActionError } from 'astro:actions'; export const server = { getUserSettings: defineAction({ handler: async (_input, context) => { if (!context.locals.user) { throw new ActionError({ code: 'UNAUTHORIZED' }); } return { /* data on success */ }; } }) } ``` ### 来自中间件的门控操作 [Section titled “来自中间件的门控操作”](#来自中间件的门控操作) ¥Gate actions from middleware **Added in:** `astro@5.0.0` Astro 建议从你的操作处理程序授权用户会话,以尊重每个操作的权限级别和速率限制。但是,你也可以从中间件将所有操作(或操作子集)的请求控制到门控。 ¥Astro recommends authorizing user sessions from your action handler to respect permission levels and rate-limiting on a per-action basis. However, you can also gate requests to all actions (or a subset of actions) from middleware. 使用中间件中的 `getActionContext()` 函数检索有关任何入站操作请求的信息。这包括操作名称以及该操作是使用客户端远程过程调用 (RPC) 函数(例如 `actions.blog.like()`)还是 HTML 表单调用的。 ¥Use the `getActionContext()` function from your middleware to retrieve information about any inbound action requests. This includes the action name and whether that action was called using a client-side remote procedure call (RPC) function (e.g. `actions.blog.like()`) or an HTML form. 以下示例拒绝所有没有有效会话令牌的操作请求。如果检查失败,则返回 “禁止” 响应。注意:此方法可确保仅在存在会话时才可访问操作,但不能替代安全授权。 ¥The following example rejects all action requests that do not have a valid session token. If the check fails, a “Forbidden” response is returned. Note: this method ensures that actions are only accessible when a session is present, but is *not* a substitute for secure authorization. src/middleware.ts ```ts import { defineMiddleware } from 'astro:middleware'; import { getActionContext } from 'astro:actions'; export const onRequest = defineMiddleware(async (context, next) => { const { action } = getActionContext(context); // Check if the action was called from a client-side function if (action?.calledFrom === 'rpc') { // If so, check for a user session token if (!context.cookies.has('user-session')) { return new Response('Forbidden', { status: 403 }); } } context.cookies.set('user-session', /* session token */); return next(); }); ``` ## 从 Astro 组件和服务器端点调用操作 [Section titled “从 Astro 组件和服务器端点调用操作”](#从-astro-组件和服务器端点调用操作) ¥Call actions from Astro components and server endpoints 你可以使用 `Astro.callAction()` 封装器(或使用 [服务器端点](/en/guides/endpoints/#server-endpoints-api-routes) 时使用 `context.callAction()`)直接从 Astro 组件脚本调用操作。这通常用于在其他服务器代码中重用操作中的逻辑。 ¥You can call actions directly from Astro component scripts using the `Astro.callAction()` wrapper (or `context.callAction()` when using a [server endpoint](/en/guides/endpoints/#server-endpoints-api-routes)). This is common to reuse logic from your actions in other server code. 将操作作为第一个参数传递,将任何输入参数作为第二个参数传递。这将返回你在客户端上调用操作时收到的相同 `data` 和 `error` 对象: ¥Pass the action as the first argument and any input parameters as the second argument. This returns the same `data` and `error` objects you receive when calling actions on the client: src/pages/products.astro ```astro --- import { actions } from 'astro:actions'; const searchQuery = Astro.url.searchParams.get('search'); if (searchQuery) { const { data, error } = await Astro.callAction(actions.findProduct, { query: searchQuery }); // handle result } --- ``` # Astro DB > 了解如何使用 Astro DB,这是一个专为 Astro 设计的完全托管的 SQL 数据库。 Astro DB 是一个完全托管的 SQL 数据库,专为 Astro 生态系统设计。在 Astro 中本地开发并部署到任何与 libSQL 兼容的数据库。 ¥Astro DB is a fully-managed SQL database designed for the Astro ecosystem. Develop locally in Astro and deploy to any libSQL-compatible database. Astro DB 是配置、开发和查询数据的完整解决方案。每当你运行 `astro dev` 来管理数据时,都会在 `.astro/content.db` 中创建本地数据库,而无需 Docker 或网络连接。 ¥Astro DB is a complete solution to configuring, developing, and querying your data. A local database is created in `.astro/content.db` whenever you run `astro dev` to manage your data without the need for Docker or a network connection. ## 安装 [Section titled “安装”](#安装) ¥Installation 使用内置的 `astro add` 命令安装 [`@astrojs/db` 整合](/en/guides/integrations-guide/db/): ¥Install the [`@astrojs/db` integration](/en/guides/integrations-guide/db/) using the built-in `astro add` command: * npm ```sh npx astro add db ``` * pnpm ```sh pnpm astro add db ``` * Yarn ```sh yarn astro add db ``` ## 定义你的数据库 [Section titled “定义你的数据库”](#定义你的数据库) ¥Define your database 使用 `astro add` 命令安装 `@astrojs/db` 将自动在你的项目中创建一个 `db/config.ts` 文件,你将在其中定义数据库表: ¥Installing `@astrojs/db` with the `astro add` command will automatically create a `db/config.ts` file in your project where you will define your database tables: db/config.ts ```ts import { defineDb } from 'astro:db'; export default defineDb({ tables: { }, }) ``` ### 表格 [Section titled “表格”](#表格) ¥Tables Astro DB 中的数据使用 SQL 表存储。表将数据结构化为行和列,其中列强制执行每行值的类型。 ¥Data in Astro DB is stored using SQL tables. Tables structure your data into rows and columns, where columns enforce the type of each row value. 通过提供现有 libSQL 数据库中数据的结构或你将在新数据库中收集的数据来定义 `db/config.ts` 文件中的表。这将允许 Astro 生成 TypeScript 接口以从你的项目中查询该表。当你使用属性自动补齐和类型检查访问数据时,结果是完全支持 TypeScript。 ¥Define your tables in your `db/config.ts` file by providing the structure of the data in your existing libSQL database, or the data you will collect in a new database. This will allow Astro to generate a TypeScript interface to query that table from your project. The result is full TypeScript support when you access your data with property autocompletion and type-checking. 要配置数据库表,请从 `astro:db` 导入并使用 `defineTable()` 和 `column` 实用程序。然后,为你的表定义一个名称(区分大小写)以及每列中的数据类型。 ¥To configure a database table, import and use the `defineTable()` and `column` utilities from `astro:db`. Then, define a name (case-sensitive) for your table and the type of data in each column. 此示例配置一个 `Comment` 表,其中包含 `author` 和 `body` 所需的文本列。然后,通过 `defineDb()` 导出使其可用于你的项目。 ¥This example configures a `Comment` table with required text columns for `author` and `body`. Then, makes it available to your project through the `defineDb()` export. db/config.ts ```ts import { defineDb, defineTable, column } from 'astro:db'; const Comment = defineTable({ columns: { author: column.text(), body: column.text(), } }) export default defineDb({ tables: { Comment }, }) ``` See the [table configuration reference](/en/guides/integrations-guide/db/#table-configuration-reference) for a complete reference of table options. ### 列 [Section titled “列”](#列) ¥Columns Astro DB 支持以下列类型: ¥Astro DB supports the following column types: db/config.ts ```ts import { defineTable, column } from 'astro:db'; const Comment = defineTable({ columns: { // A string of text. author: column.text(), // A whole integer value. likes: column.number(), // A true or false value. flagged: column.boolean(), // Date/time values queried as JavaScript Date objects. published: column.date(), // An untyped JSON object. metadata: column.json(), } }); ``` See the [table columns reference](/en/guides/integrations-guide/db/#table-configuration-reference) for more details. ### 表格参考 [Section titled “表格参考”](#表格参考) ¥Table References 表之间的关系是数据库设计中的常见模式。例如,`Blog` 表可能与 `Comment`、`Author` 和 `Category` 的其他表密切相关。 ¥Relationships between tables are a common pattern in database design. For example, a `Blog` table may be closely related to other tables of `Comment`, `Author`, and `Category`. 你可以定义这些表之间的关系,并使用引用列将它们保存到数据库模式中。要建立关系,你需要: ¥You can define these relations between tables and save them into your database schema using **reference columns**. To establish a relationship, you will need: * 引用表上的标识符列。这通常是具有 `primaryKey` 属性的 `id` 列。 * 基表上的一列用于存储引用的 `id`。这使用 `references` 属性建立关系。 此示例显示了 `Comment` 表的 `authorId` 列引用 `Author` 表的 `id` 列。 ¥This example shows a `Comment` table’s `authorId` column referencing an `Author` table’s `id` column. db/config.ts ```ts const Author = defineTable({ columns: { id: column.number({ primaryKey: true }), name: column.text(), } }); const Comment = defineTable({ columns: { authorId: column.number({ references: () => Author.columns.id }), body: column.text(), } }); ``` ## 为开发播种数据库 [Section titled “为开发播种数据库”](#为开发播种数据库) ¥Seed your database for development 在开发过程中,Astro 将使用你的 DB 配置根据你的模式生成本地类型。每次启动开发服务器时,这些都将从你的种子文件中新鲜生成,并允许你使用类型安全和自动补齐来查询和处理数据形状。 ¥In development, Astro will use your DB config to generate local types according to your schemas. These will be generated fresh from your seed file each time the dev server is started, and will allow you to query and work with the shape of your data with type safety and autocompletion. 除非你在开发期间 [连接到远程数据库](#connecting-to-remote-databases),否则你将无法在开发期间访问生产数据。这可以保护你的数据,同时允许你使用具有类型安全性的工作数据库进行测试和开发。 ¥You will not have access to production data during development unless you [connect to a remote database](#connecting-to-remote-databases) during development. This protects your data while allowing you to test and develop with a working database with type-safety. 要将用于测试和调试的开发数据植入 Astro 项目,请创建一个 `db/seed.ts` 文件。导入 `db` 对象和 `astro:db` 中定义的表。`insert` 将一些初始数据放入每个表中。此开发数据应与数据库模式和生产数据的形式相匹配。 ¥To seed development data for testing and debugging into your Astro project, create a `db/seed.ts` file. Import both the `db` object and your tables defined in `astro:db`. `insert` some initial data into each table. This development data should match the form of both your database schema and production data. 以下示例为 `Comment` 表和 `Author` 表定义了两行开发数据: ¥The following example defines two rows of development data for a `Comment` table, and an `Author` table: db/seed.ts ```ts import { db, Comment, Author } from 'astro:db'; export default async function() { await db.insert(Author).values([ { id: 1, name: "Kasim" }, { id: 2, name: "Mina" }, ]); await db.insert(Comment).values([ { authorId: 1, body: 'Hope you like Astro DB!' }, { authorId: 2, body: 'Enjoy!'}, ]) } ``` 每当此文件发生更改时,你的开发服务器将自动重新启动数据库,每次都会重新生成你的类型并从 `seed.ts` 中播种此开发数据。 ¥Your development server will automatically restart your database whenever this file changes, regenerating your types and seeding this development data from `seed.ts` fresh each time. ## 连接 libSQL 数据库以进行生产 [Section titled “连接 libSQL 数据库以进行生产”](#连接-libsql-数据库以进行生产) ¥Connect a libSQL database for production Astro DB 可以连接到任何本地 libSQL 数据库或任何公开 libSQL 远程协议的服务器,无论是托管的还是自托管的。 ¥Astro DB can connect to any local libSQL database or to any server that exposes the libSQL remote protocol, whether managed or self-hosted. 要将 Astro DB 连接到 libSQL 数据库,请设置从数据库提供程序获取的以下环境变量: ¥To connect Astro DB to a libSQL database, set the following environment variables obtained from your database provider: * `ASTRO_DB_REMOTE_URL`:到本地或远程 libSQL DB 位置的连接 URL。这可能包括 [URL 配置选项](#remote-url-configuration-options),例如同步和加密作为参数。 * `ASTRO_DB_APP_TOKEN`:你的 libSQL 服务器的身份验证令牌。这是远程数据库所必需的,而 [本地数据库,如文件或内存](#url-scheme-and-host) 数据库则不需要 根据你的服务,你可能可以访问 CLI 或 Web UI 来检索这些值。以下部分将演示如何连接到 Turso 并设置这些值作为示例,但你可以自由使用任何提供程序。 ¥Depending on your service, you may have access to a CLI or web UI to retrieve these values. The following section will demonstrate connecting to Turso and setting these values as an example, but you are free to use any provider. ### 开始使用 Turso [Section titled “开始使用 Turso”](#开始使用-turso) ¥Getting started with Turso Turso 是 [libSQL](https://github.com/tursodatabase/libsql) 背后的公司,[libSQL](https://github.com/tursodatabase/libsql) 是为 Astro DB 提供支持的 SQLite 的开源分支。它们提供了一个完全托管的 libSQL 数据库平台,并且与 Astro 完全兼容。 ¥Turso is the company behind [libSQL](https://github.com/tursodatabase/libsql), the open-source fork of SQLite that powers Astro DB. They provide a fully managed libSQL database platform and are fully compatible with Astro. 以下步骤将指导你完成安装 Turso CLI、登录(或注册)、创建新数据库、获取所需环境变量以及将架构推送到远程数据库的过程。 ¥The steps below will guide you through the process of installing the Turso CLI, logging in (or signing up), creating a new database, getting the required environmental variables, and pushing the schema to the remote database. 1. Install the [Turso CLI](https://docs.turso.tech/cli/installation). 2. [Log in or sign up](https://docs.turso.tech/cli/authentication) to Turso. 3. Create a new database. In this example the database name is `andromeda`. ```sh turso db create andromeda ``` 4. Run the `show` command to see information about the newly created database: ```sh turso db show andromeda ``` Copy the `URL` value and set it as the value for `ASTRO_DB_REMOTE_URL`. .env ```dotenv ASTRO_DB_REMOTE_URL=libsql://andromeda-houston.turso.io ``` 5. Create a new token to authenticate requests to the database: ```sh turso db tokens create andromeda ``` Copy the output of the command and set it as the value for `ASTRO_DB_APP_TOKEN`. .env ```diff ASTRO_DB_REMOTE_URL=libsql://andromeda-houston.turso.io +ASTRO_DB_APP_TOKEN=eyJhbGciOiJF...3ahJpTkKDw ``` 6. Push your DB schema and metadata to the new Turso database. ```sh astro db push --remote ``` 7. Congratulations, now you have a database connected! Give yourself a break. 👾 ```sh turso relax ``` 要探索 Turso 的更多功能,请查看 [Turso 文档](https://docs.turso.tech)。 ¥To explore more features of Turso, check out the [Turso docs](https://docs.turso.tech). ### 连接到远程数据库 [Section titled “连接到远程数据库”](#连接到远程数据库) ¥Connecting to remote databases Astro DB 允许你连接到本地和远程数据库。默认情况下,Astro 使用本地数据库文件执行 `dev` 和 `build` 命令,每次都重新创建表并插入开发种子数据。 ¥Astro DB allows you to connect to both local and remote databases. By default, Astro uses a local database file for `dev` and `build` commands, recreating tables and inserting development seed data each time. 要连接到托管的远程数据库,请使用 `--remote` 标志。此标志启用对远程数据库的可读和可写访问,允许你在生产环境中使用 [接受并保留用户数据](#insert)。 ¥To connect to a hosted remote database, use the `--remote` flag. This flag enables both readable and writable access to your remote database, allowing you to [accept and persist user data](#insert) in production environments. Note While remote connections are generally possible with any deployment platform using static or server rendering mode, there are currently some limitations. Non-Node runtimes like Cloudflare and Deno don’t currently support DB on server-rendered routes when using libSQL. Support for these platforms is planned for future implementation. 配置你的构建命令以使用 `--remote` 标志: ¥Configure your build command to use the `--remote` flag: package.json ```json { "scripts": { "build": "astro build --remote" } } ``` 你还可以在命令行中直接使用该标志: ¥You can also use the flag directly in the command line: ```bash # Build with a remote connection astro build --remote # Develop with a remote connection astro dev --remote ``` Caution Be careful when using `--remote` in development. This connects to your live production database, and all changes (inserts, updates, deletions) will be persisted. `--remote` 标志在构建期间和服务器上都使用与远程数据库的连接。确保在本地开发环境和部署平台中设置必要的环境变量。 ¥The `--remote` flag uses the connection to the remote DB both locally during the build and on the server. Ensure you set the necessary environment variables in both your local development environment and your deployment platform. 部署 Astro DB 项目时,请确保你的部署平台的构建命令设置为 `npm run build`(或你的包管理器的等效命令),以利用在你的 `package.json` 中配置的 `--remote` 标志。 ¥When deploying your Astro DB project, make sure your deployment platform’s build command is set to `npm run build` (or the equivalent for your package manager) to utilize the `--remote` flag configured in your `package.json`. ### 远程 URL 配置选项 [Section titled “远程 URL 配置选项”](#远程-url-配置选项) ¥Remote URL configuration options `ASTRO_DB_REMOTE_URL` 环境变量配置数据库的位置以及其他选项(如同步和加密)。 ¥The `ASTRO_DB_REMOTE_URL` environment variable configures the location of your database as well as other options like sync and encryption. #### URL 方案和主机 [Section titled “URL 方案和主机”](#url-方案和主机) ¥URL scheme and host libSQL 支持 HTTP 和 WebSockets 作为远程服务器的传输协议。它还支持使用本地文件或内存数据库。可以使用连接 URL 中的以下 URL 方案配置这些: ¥libSQL supports both HTTP and WebSockets as the transport protocol for a remote server. It also supports using a local file or an in-memory DB. Those can be configured using the following URL schemes in the connection URL: * `memory:` 将使用内存数据库。在这种情况下,主机必须为空。 * `file:` 将使用本地文件。主机是文件的路径(`file:path/to/file.db`)。 * `libsql:` 将通过库首选的协议使用远程服务器(这可能因版本而异)。主机是服务器的地址(`libsql://your.server.io`)。 * `http:` 将通过 HTTP 使用远程服务器。`https:` 可用于启用安全连接。主机与 `libsql:` 相同。 * `ws:` 将通过 WebSockets 使用远程服务器。`wss:` 可用于启用安全连接。主机与 `libsql:` 相同。 libSQL 连接的详细信息(例如加密密钥、复制、同步间隔)可以配置为远程连接 URL 中的查询参数。 ¥Details of the libSQL connection (e.g. encryption key, replication, sync interval) can be configured as query parameters in the remote connection URL. 例如,要让加密的本地文件作为 libSQL 服务器的嵌入式副本工作,你可以设置以下环境变量: ¥For example, to have an encrypted local file work as an embedded replica to a libSQL server, you can set the following environment variables: .env ```dotenv ASTRO_DB_REMOTE_URL=file://local-copy.db?encryptionKey=your-encryption-key&syncInterval=60&syncUrl=libsql%3A%2F%2Fyour.server.io ASTRO_DB_APP_TOKEN=token-to-your-remote-url ``` Caution Using a database file is an advanced feature, and care should be taken when deploying to prevent overriding your database and losing your production data. Additionally, this method will not work in serverless deployments, as the file system is not persisted in those environments. #### `encryptionKey` [Section titled “encryptionKey”](#encryptionkey) libSQL 原生支持加密数据库。传递此搜索参数将使用给定的密钥启用加密: ¥libSQL has native support for encrypted databases. Passing this search parameter will enable encryption using the given key: .env ```dotenv ASTRO_DB_REMOTE_URL=file:path/to/file.db?encryptionKey=your-encryption-key ``` #### `syncUrl` [Section titled “syncUrl”](#syncurl) 嵌入式副本是 libSQL 客户端的一项功能,可在本地文件或内存中创建数据库的完整同步副本,以实现超快速读取。写入被发送到 `syncUrl` 上定义的远程数据库并与本地副本同步。 ¥Embedded replicas are a feature of libSQL clients that creates a full synchronized copy of your database on a local file or in memory for ultra-fast reads. Writes are sent to a remote database defined on the `syncUrl` and synchronized with the local copy. 使用此属性传递单独的连接 URL,以将数据库转换为另一个数据库的嵌入副本。这只应与方案 `file:` 和 `memory:` 一起使用。参数必须是 URL 编码的。 ¥Use this property to pass a separate connection URL to turn the database into an embedded replica of another database. This should only be used with the schemes `file:` and `memory:`. The parameter must be URL encoded. 例如,要在 `libsql://your.server.io` 上拥有数据库的内存嵌入式副本,你可以设置连接 URL 如下: ¥For example, to have an in-memory embedded replica of a database on `libsql://your.server.io`, you can set the connection URL as such: .env ```dotenv ASTRO_DB_REMOTE_URL=memory:?syncUrl=libsql%3A%2F%2Fyour.server.io ``` #### `syncInterval` [Section titled “syncInterval”](#syncinterval) 嵌入式副本同步之间的间隔(以秒为单位)。默认情况下,它仅在启动时和写入后同步。 ¥Interval between embedded replica synchronizations in seconds. By default it only synchronizes on startup and after writes. 此属性仅在 `syncUrl` 也设置时使用。例如,要设置内存嵌入式副本以每分钟同步一次,请设置以下环境变量: ¥This property is only used when `syncUrl` is also set. For example, to set an in-memory embedded replica to synchronize every minute set the following environment variable: .env ```dotenv ASTRO_DB_REMOTE_URL=memory:?syncUrl=libsql%3A%2F%2Fyour.server.io&syncInterval=60 ``` ## 查询数据库 [Section titled “查询数据库”](#查询数据库) ¥Query your database 你可以使用提供的 `db` ORM 和查询构建器从项目中的任何 [Astro 页面](/en/basics/astro-pages/#astro-pages)、[endpoint](/en/guides/endpoints/) 或 [action](/en/guides/actions/) 查询数据库。 ¥You can query your database from any [Astro page](/en/basics/astro-pages/#astro-pages), [endpoint](/en/guides/endpoints/), or [action](/en/guides/actions/) in your project using the provided `db` ORM and query builder. ### Drizzle ORM [Section titled “Drizzle ORM”](#drizzle-orm) ```ts import { db } from 'astro:db'; ``` Astro DB 包含内置 [Drizzle ORM](https://orm.drizzle.team/) 客户端。使用客户端无需设置或手动配置。当你运行 Astro 时,Astro DB `db` 客户端会自动配置为与你的数据库(本地或远程)通信。当你引用不存在的列或表时,它会使用你的确切数据库架构定义进行类型安全的 SQL 查询,并出现 TypeScript 错误。 ¥Astro DB includes a built-in [Drizzle ORM](https://orm.drizzle.team/) client. There is no setup or manual configuration required to use the client. The Astro DB `db` client is automatically configured to communicate with your database (local or remote) when you run Astro. It uses your exact database schema definition for type-safe SQL queries with TypeScript errors when you reference a column or table that doesn’t exist. ### 选择 [Section titled “选择”](#选择) ¥Select 以下示例选择 `Comment` 表的所有行。这将返回来自 `db/seed.ts` 的完整种子开发数据数组,然后可用于你的页面模板: ¥The following example selects all rows of a `Comment` table. This returns the complete array of seeded development data from `db/seed.ts` which is then available for use in your page template: src/pages/index.astro ```astro --- import { db, Comment } from 'astro:db'; const comments = await db.select().from(Comment); ---Author: {author}
{body}
Author: {Author.name}
{Comment.body}
Welcome {session.user?.name}
) : (Not logged in
) }{session.user?.name}
``` 你还可以使用 `auth` 对象通过中间件保护你的路由。以下示例检查尝试访问已登录仪表板路由的用户是否经过身份验证,如果没有,则将其重定向到主页。 ¥You can also use the `auth` object to protect your routes using middleware. The following example checks whether a user trying to access a logged-in dashboard route is authenticated, and redirects them to the home page if not. src/middleware.ts ```ts import { auth } from "../../../auth"; // import your Better Auth instance import { defineMiddleware } from "astro:middleware"; export const onRequest = defineMiddleware(async (context, next) => { const isAuthed = await auth.api .getSession({ headers: context.request.headers, }) if (context.url.pathname === "/dashboard" && !isAuthed) { return context.redirect("/"); } return next(); }); ``` ### 下一步 [Section titled “下一步”](#下一步-1) ¥Next Steps * [Better Auth Astro 指南](https://www.better-auth.com/docs/integrations/astro) * [Better Auth Astro 示例](https://github.com/better-auth/better-auth/tree/main/examples/astro-example) * [Better Auth 文档](https://www.better-auth.com/docs) * [Better Auth GitHub 存储库](https://github.com/better-auth/better-auth) ## 店员 [Section titled “店员”](#店员) ¥Clerk Clerk 是一套完整的可嵌入 UI、灵活的 API 和管理仪表板,用于对你的用户进行身份验证和管理。[Astro 官方 Clerk SDK](https://clerk.com/docs/references/astro/overview) 可用。 ¥Clerk is a complete suite of embeddable UIs, flexible APIs, and admin dashboards to authenticate and manage your users. An [official Clerk SDK for Astro](https://clerk.com/docs/references/astro/overview) is available. ### 安装 [Section titled “安装”](#安装-2) ¥Installation 使用你选择的包管理器安装 `@clerk/astro`。 ¥Install `@clerk/astro` using the package manager of your choice. * npm ```shell npm install @clerk/astro ``` * pnpm ```shell pnpm add @clerk/astro ``` * Yarn ```shell yarn add @clerk/astro ``` ### 配置 [Section titled “配置”](#配置-2) ¥Configuration 按照 [Clerk 自己的 Astro 快速入门指南](https://clerk.com/docs/quickstarts/astro) 在你的 Astro 项目中设置 Clerk 集成和中间件。 ¥Follow [Clerk’s own Astro Quickstart guide](https://clerk.com/docs/quickstarts/astro) to set up Clerk integration and middleware in your Astro project. ### 用法 [Section titled “用法”](#用法-2) ¥Usage Clerk 提供的组件允许你根据用户的身份验证状态控制页面的可见性。向已注销的用户显示登录按钮,而不是向已登录的用户显示内容: ¥Clerk provides components that allow you to control the visibility of pages based on your user’s authentication state. Show logged out users a sign in button instead of the content available to users who are logged in: src/pages/index.astro ```astro --- import Layout from 'src/layouts/Base.astro'; import { SignedIn, SignedOut, UserButton, SignInButton } from '@clerk/astro/components'; export const prerender = false; // Not needed in 'server' mode ---Already have an account? Sign in
New here? Create an account
We are happy to see you here
Here you can edit or delete your friend's data.
Age: {friend.age}
Is best friend: {friend.isBestFriend ? "Yes" : "No"}
The time is: {currentTime}
``` ## 使用 Neon 进行数据库分支 [Section titled “使用 Neon 进行数据库分支”](#使用-neon-进行数据库分支) ¥Database branching with Neon Neon 的分支功能允许你创建数据库的副本以进行开发或测试。通过为每个分支创建不同的环境变量,在你的 Astro 项目中使用它: ¥Neon’s branching feature lets you create copies of your database for development or testing. Use this in your Astro project by creating different environment variables for each branch: .env.development ```ini NEON_DATABASE_URL=your_development_branch_url ``` .env.production ```ini NEON_DATABASE_URL=your_production_branch_url ``` ## 资源 [Section titled “资源”](#资源) ¥Resources * [Neon 文档](https://neon.tech/docs/introduction) * [Neon 无服务器驱动程序 GitHub](https://github.com/neondatabase/serverless) * [将 Astro 站点或应用连接到 Neon Postgres](https://neon.tech/docs/guides/astro) # 使用 Sentry 监控你的 Astro 网站 > 如何使用 Sentry 监控你的 Astro 网站 [Sentry](https://sentry.io) 提供全面的应用监控和错误跟踪服务,旨在帮助开发者实时识别、诊断和解决问题。 ¥[Sentry](https://sentry.io) offers a comprehensive application monitoring and error tracking service designed to help developers identify, diagnose, and resolve issues in real-time. 在我们的博客上阅读有关 [Astro 与 Sentry 的合作关系](https://astro.build/blog/sentry-official-monitoring-partner/) 和 Sentry 的 Spotlight 开发工具栏应用的更多信息,该应用为你的 Astro 开发环境带来了丰富的调试覆盖。Spotlight 在本地开发期间直接在你的浏览器中显示错误、跟踪和重要上下文。 ¥Read more on our blog about [Astro’s partnership with Sentry](https://astro.build/blog/sentry-official-monitoring-partner/) and Sentry’s Spotlight dev toolbar app that brings a rich debug overlay into your Astro development environment. Spotlight shows errors, traces, and important context right in your browser during local development. Sentry 的 Astro SDK 可自动报告 Astro 应用中的错误和跟踪数据。 ¥Sentry’s Astro SDK enables automatic reporting of errors and tracing data in your Astro application. ## 项目配置 [Section titled “项目配置”](#项目配置) ¥Project Configuration 完整的先决条件列表可在 [Astro 的 Sentry 指南](https://docs.sentry.io/platforms/javascript/guides/astro/#prerequisites) 中找到。 ¥A full list of prerequisites can be found in [the Sentry guide for Astro](https://docs.sentry.io/platforms/javascript/guides/astro/#prerequisites). ## 安装 [Section titled “安装”](#安装) ¥Install Sentry 使用应用运行时中的 SDK 捕获数据。 ¥Sentry captures data by using an SDK within your application’s runtime. 通过在 Astro CLI 中为你选择的包管理器运行以下命令来安装 SDK: ¥Install the SDK by running the following command for the package manager of your choice in the Astro CLI: * npm ```shell npx astro add @sentry/astro ``` * pnpm ```shell pnpm astro add @sentry/astro ``` * Yarn ```shell yarn astro add @sentry/astro ``` astro CLI 安装 SDK 包并将 Sentry 集成添加到你的 `astro.config.mjs` 文件中。 ¥The astro CLI installs the SDK package and adds the Sentry integration to your `astro.config.mjs` file. ## 配置 [Section titled “配置”](#配置) ¥Configure 要配置 Sentry 集成,你需要在 `astro.config.mjs` 文件中提供以下凭据。 ¥To configure the Sentry integration, you need to provide the following credentials in your `astro.config.mjs` file. 1. 客户端密钥 (DSN) - 你可以在 Sentry 项目设置的 Client keys (DSN) 下找到 DSN。 2. 项目名称 - 你可以在 Sentry 项目设置的 General settings 下找到项目名称。 3. 身份验证令牌 - 你可以在 Sentry 组织设置的 Auth tokens 下创建 auth token。 Note If you are creating a new Sentry project, select Astro as your platform to get all the necessary information to configure the SDK. astro.config.mjs ```diff import { defineConfig } from 'astro/config'; +import sentry from '@sentry/astro'; export default defineConfig({ integrations: [ +sentry({ + dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0', + sourceMapsUploadOptions: { + project: 'example-project', + authToken: process.env.SENTRY_AUTH_TOKEN, + }, + }), ], }); ``` 配置 `sourceMapsUploadOptions` 并添加 `dsn` 后,SDK 将自动捕获并将错误和性能事件发送到 Sentry。 ¥Once you’ve configured your `sourceMapsUploadOptions` and added your `dsn`, the SDK will automatically capture and send errors and performance events to Sentry. ## 测试你的设置 [Section titled “测试你的设置”](#测试你的设置) ¥Test your setup 将以下 `