Storyblok 和 Astro
Storyblok 是一个基于组件的无头 CMS,允许你使用称为 Bloks 的可重用组件来管理你的内容。
¥Storyblok is a component-based headless CMS that allows you to manage your content using reusable components called Bloks.
与 Astro 集成
Section titled 与 Astro 集成¥Integrating with Astro
在本部分中,你将使用 Storyblok 集成 将 Storyblok 连接到 Astro。
¥In this section, you will use the Storyblok integration to connect Storyblok to Astro.
¥Prerequisites
首先,你需要具备以下条件:
¥To get started, you will need to have the following:
-
Astro 项目 - 如果你还没有 Astro 项目,我们的 安装指南 将立即帮助你启动并运行。
-
Storyblok 账户和空间 - 如果你还没有账户,免费注册 并创建一个新空间。
-
Storyblok 预览令牌 - 此令牌将用于获取内容的草稿和已发布版本。你可以在 Storyblok 空间设置的“访问令牌”选项卡中查找并生成 API 令牌。
¥Setting up credentials
要将 Storyblok 凭据添加到 Astro,请使用以下变量在项目的根目录中创建 .env
文件:
¥To add your Storyblok credentials to Astro, create a .env
file in the root of your project with the following variable:
现在,你应该能够在项目中使用这些环境变量。
¥Now, you should be able to use these environment variables in your project.
你的根目录现在应该包含这个新文件:
¥Your root directory should now include this new file:
Directorysrc/
- …
- .env
- astro.config.mjs
- package.json
¥Installing dependencies
要将 Astro 与你的 Storyblok 空间连接,请使用以下命令为你首选的包管理器安装官方 Storyblok 集成:
¥To connect Astro with your Storyblok space, install the official Storyblok integration using the command below for your preferred package manager:
配置 Storyblok
Section titled 配置 Storyblok¥Configuring Storyblok
修改 Astro 配置文件以包含 Storyblok 集成:
¥Modify your Astro config file to include the Storyblok integration:
Storyblok 集成需要具有以下属性的对象:
¥The Storyblok integration requires an object with the following properties:
-
accessToken
- 这引用了你在上一步中添加的 Storyblok API 令牌。 -
components
- 将 Storyblok 组件名称映射到本地组件路径的对象。这是在 Astro 中渲染 Storyblok Bloks 所必需的。 -
apiOptions
- 包含 Storyblok API 选项 的对象。
将 Bloks 连接到 Astro 组件
Section titled 将 Bloks 连接到 Astro 组件¥Connecting Bloks to Astro components
要将 Bloks 连接到 Astro,请在 src
目录中创建一个名为 storyblok
的新文件夹。此文件夹将包含与 Storyblok Blok 库中的 Bloks 匹配的所有 Astro 组件。
¥To connect your Bloks to Astro, create a new folder named storyblok
in the src
directory. This folder will contain all the Astro components that will match your Bloks in your Storyblok Blok library.
在此示例中,你的 Storyblok 库中有一个 blogPost
Blok 内容类型,其中包含以下字段:
¥In this example, you have a blogPost
Blok content type in your Storyblok library with the following fields:
-
title
- 文本字段 -
description
- 文本字段 -
content
- 富文本字段
我们的目标是创建等效的 Astro 组件,该组件将使用这些字段来渲染其内容。为此,请在 src/storyblok
内创建一个名为 BlogPost.astro
的新文件,其中包含以下内容:
¥Our goal is to create the equivalent Astro component that will use these fields to render its content. To do this, create a new file named BlogPost.astro
inside src/storyblok
with the following content:
blok
属性包含你将从 Storyblok 接收的数据。它还包含 Storyblok 中 blogPost
内容类型 Blok 中定义的字段。
¥The blok
property contains the data that you will receive from Storyblok. It also contains the fields that were defined in the blogPost
content type Blok in Storyblok.
为了渲染我们的内容,集成提供了实用功能,例如:
¥To render our content, the integration provides utility functions such as:
-
storyblokEditable
- 它将必要的属性添加到元素中,以便你可以在 Storyblok 中编辑它们。 -
renderRichText
- 它将富文本字段转换为 HTML。
你的根目录应该包含这个新文件:
¥Your root directory should include this new file:
Directorysrc/
Directorystoryblok/
- BlogPost.astro
- .env
- astro.config.mjs
- package.json
最后,要将 blogPost
Blok 连接到 BlogPost
组件,请向 Astro 配置文件中的组件对象添加一个新属性。
¥Finally, to connect the blogPost
Blok to the BlogPost
component, add a new property to your components object in your Astro config file.
-
关键是 Storyblok 中 Blok 的名称。在本例中,它是
blogPost
。 -
该值是组件的路径。在本例中,它是
storyblok/BlogPost
。
¥Fetching data
要测试设置,请在 Storyblok 中创建一个名为 test-post
的 blogPost
内容类型的新故事。在 Astro 中,在 src/pages/
目录中创建一个名为 test-post.astro
的新页面,其中包含以下内容:
¥To test the setup, in Storyblok create a new story with the blogPost
content type named test-post
.
In Astro, create a new page in the src/pages/
directory named test-post.astro
with the following content:
要查询数据,请使用 useStoryblokApi
钩子。这将使用你的集成配置初始化一个新的客户端实例。
¥To query your data, use the useStoryblokApi
hook. This will initialize a new client instance using your integration configuration.
要渲染你的内容,请将 Story 的 content
属性作为 blok
prop 传递给 StoryblokComponent
。该组件将渲染在 content
属性内定义的 Bloks。在这种情况下,它将渲染 BlogPost
组件。
¥To render your content, pass the content
property of the Story to the StoryblokComponent
as a blok
prop. This component will render the Bloks that are defined inside the content
property. In this case, it will render the BlogPost
component.
使用 Astro 和 Storyblok 制作博客
Section titled 使用 Astro 和 Storyblok 制作博客¥Making a blog with Astro and Storyblok
设置集成后,你现在可以使用 Astro 和 Storyblok 创建博客。
¥With the integration set up, you can now create a blog with Astro and Storyblok.
¥Prerequisites
-
故事块空间 - 对于本教程,我们建议使用新空间。如果你已经拥有包含 Bloks 的空间,请随意使用它们,但你需要修改代码以匹配 Blok 名称和内容类型。
-
与 Storyblok 集成的 Astro 项目 - 请参阅 与 Astro 集成 以了解如何设置集成的说明。
¥Creating a blok library
要创建 Bloks,请转到 Storyblok 应用并单击“Block Library”选项卡。单击 + New blok 按钮并创建以下 Bloks:
¥To create Bloks, go to the Storyblok app and click on the Block Library tab. Click on the + New blok button and create the following Bloks:
-
blogPost
- 具有以下字段的内容类型 Blok:-
title
- 文本字段 -
description
- 文本字段 -
content
- 富文本字段
-
-
blogPostList
- 一个空的可嵌套的 Blok -
page
- 具有以下字段的内容类型 Blok:body
- 可嵌套的布洛克
¥Creating content
要添加新内容,请单击“内容”选项卡转到内容部分。使用你在上一步中创建的 Blok 库,创建以下故事:
¥To add new content, go to the content section by clicking on the Content tab. Using the Blok library that you created in the previous step, create the following stories:
-
home
- 与page
Blok 相关的内容类型故事。在body
字段内,添加blogPostList
块。 -
blog/no-javascript
- 博客文件夹内内容类型为blogPost
的故事。 -
blog/astro-is-amazing
- 博客文件夹内内容类型为blogPost
的故事。
现在你已准备好内容,返回你的 Astro 项目并开始构建你的博客。
¥Now that you have your content ready, return to your Astro project and start building your blog.
将 Bloks 连接到组件
Section titled 将 Bloks 连接到组件¥Connecting Bloks to components
要将新创建的 Bloks 连接到 Astro 组件,请在 src
目录中创建一个名为 storyblok
的新文件夹并添加以下文件:
¥To connect your newly created Bloks to Astro components, create a new folder named storyblok
in your src
directory and add the following files:
Page.astro
是一个可嵌套的块内容类型组件,它将递归渲染 page
块的 body
属性内的所有块。它还将 storyblokEditable
属性添加到父元素,这将允许我们在 Storyblok 中编辑页面。
¥Page.astro
is a nestable Block content type component that will recursively render all the Bloks inside the body
property of the page
Blok. It also adds the storyblokEditable
attributes to the parent element which will allow us to edit the page in Storyblok.
BlogPost.astro
将渲染 blogPost
块的 title
、description
和 content
属性。
¥BlogPost.astro
will render the title
, description
and content
properties of the blogPost
Blok.
要将 content
属性从富文本字段转换为 HTML,你可以使用 renderRichText
辅助函数。
¥To transform the content
property from a rich text field to HTML, you can use the renderRichText
helper function.
BlogPostList.astro
是一个可嵌套的 Blok 内容类型组件,它将渲染博客文章预览列表。
¥BlogPostList.astro
is a nestable Blok content type component that will render a list of blog post previews.
它使用 useStoryblokApi
钩子来获取内容类型为 blogPost
的所有故事。它使用 version
查询参数在开发模式下获取故事的草稿版本,在生产构建时使用已发布的版本。
¥It uses the useStoryblokApi
hook to fetch all the stories with the content type of blogPost
. It uses the version
query parameter to fetch the draft versions of the stories when in development mode and the published versions when building for production.
Astro.props
用于在 Storyblok 中设置编辑器。如果需要,还可以在此处将其他属性传递给你的组件。
¥Astro.props
is used to set up the editor in Storyblok. Additional props can also be passed to your component here, if needed.
最后,将你的组件添加到 astro.config.mjs
中 storyblok
配置对象的 components
属性中。键是 Storyblok 中 Blok 的名称,值是组件相对于 src
的路径。
¥Finally, add your components to the components
property of the storyblok
config object in astro.config.mjs
. The key is the name of the Blok in Storyblok, and the value is the path to the component relative to src
.
¥Generating pages
要为特定 page
创建路由,你可以直接从 Storyblok API 获取其内容并将其传递给 StoryblokComponent
组件。请记住确保你已将 Page
组件添加到 astro.config.mjs 中。
¥To create a route for a specific page
, you can fetch its content directly from the Storyblok API and pass it to the StoryblokComponent
component. Remember to make sure you have added the Page
component to your astro.config.mjs.
在 src/pages/
中创建 index.astro
文件来渲染 home
页面:
¥Create an index.astro
file in src/pages/
to render the home
page:
要为所有博客文章生成页面,请创建一个 .astro
页面来创建动态路由。此方法因你使用的是静态站点生成(默认)还是服务器端渲染而异。
¥To generate pages for all of your blog posts, create a .astro
page that will create dynamic routes. This approach varies depending on whether you’re using static site generation (the default) or server-side rendering.
静态站点生成
Section titled 静态站点生成¥Static site generation
如果你使用 Astro 的默认静态站点生成,你将使用 动态路由 和 getStaticPaths
函数来生成项目页面。
¥If you are using Astro’s default static site generation, you will use dynamic routes and the getStaticPaths
function to generate your project pages.
创建一个新目录 src/pages/blog/
并添加一个名为 [...slug].astro
的新文件,代码如下:
¥Create a new directory src/pages/blog/
and add a new file called [...slug].astro
with the following code:
该文件将为每个故事生成一个页面,其中包含从 Storyblok API 获取的 slug 和内容。
¥This file will generate a page for each story, with the slug and content fetched from the Storyblok API.
服务端渲染
Section titled 服务端渲染¥Server-side rendering
如果你有 选择进入 SSR 模式,你将使用动态路由从 Storyblok 获取页面数据。
¥If you’ve opted into SSR mode, you will use dynamic routes to fetch the page data from Storyblok.
创建一个新目录 src/pages/blog/
并添加一个名为 [...slug].astro
的新文件,代码如下:
¥Create a new directory src/pages/blog/
and add a new file called [...slug].astro
with the following code:
该文件将从 Storyblok 获取并渲染与动态 slug
参数匹配的页面数据。
¥This file will fetch and render the page data from Storyblok that matches the dynamic slug
parameter.
由于你使用的是重定向到 /404
,因此在 src/pages
中创建 404 页面:
¥Since you are using a redirect to /404
, create a 404 page in src/pages
:
如果没有找到故事,请求将被重定向到 404 页面。
¥If the story is not found, the request will be redirected to the 404 page.
发布你的网站
Section titled 发布你的网站¥Publishing your site
要部署你的网站,请访问我们的 部署指南 并按照你首选托管提供商的说明进行操作。
¥To deploy your website, visit our deployment guides and follow the instructions for your preferred hosting provider.
根据 Storyblok 更改进行重建
Section titled 根据 Storyblok 更改进行重建¥Rebuild on Storyblok changes
如果你的项目使用 Astro 的默认静态模式,则需要设置一个 Webhook 以在内容更改时触发新的构建。如果你使用 Netlify 或 Vercel 作为托管提供商,则可以使用其 Webhook 功能从 Storyblok 事件触发新构建。
¥If your project is using Astro’s default static mode, you will need to set up a webhook to trigger a new build when your content changes. If you are using Netlify or Vercel as your hosting provider, you can use its webhook feature to trigger a new build from Storyblok events.
Netlify
Section titled Netlify要在 Netlify 中设置 Webhook:
¥To set up a webhook in Netlify:
-
Go to your site dashboard and click on Build & deploy.
-
Under the Continuous Deployment tab, find the Build hooks section and click on Add build hook.
-
Provide a name for your webhook and select the branch you want to trigger the build on. Click on Save and copy the generated URL.
Vercel
Section titled Vercel要在 Vercel 中设置 Webhook:
¥To set up a webhook in Vercel:
-
Go to your project dashboard and click on Settings.
-
Under the Git tab, find the Deploy Hooks section.
-
Provide a name for your webhook and the branch you want to trigger the build on. Click Add and copy the generated URL.
将 webhook 添加到 Storyblok
Section titled 将 webhook 添加到 Storyblok¥Adding a webhook to Storyblok
在你的 Storyblok 空间设置中,单击 Webhooks 选项卡。将你复制的 webhook URL 粘贴到 Story 已发布和未发布字段中,然后点击 Save 创建 webhook。
¥In your Storyblok space Settings, click on the Webhooks tab. Paste the webhook URL you copied in the Story published & unpublished field and hit Save to create a webhook.
现在,每当你发布新故事时,都会触发新的构建,并且你的博客也会更新。
¥Now, whenever you publish a new story, a new build will be triggered and your blog will be updated.
¥Official Resources
- Storyblok 提供了 Astro 整合 将 Storyblok 添加到你的项目中。
¥Community Resources
-
桑德拉·罗杰斯的《让可视化编辑器适用于 Storyblok + Astro》
-
乔纳斯·吉勒的《Astro + Storyblok:用于即时可视化编辑的 SSR 预览》
-
桑德拉·罗杰斯的《Astro-Storyblok 预览具有 Netlify 分支部署功能的站点》