Strapi 与 Astro
Strapi 是一个开源的、可定制化的无头 CMS。
与 Astro 集成
Section titled “与 Astro 集成”这个指南将构建一个包装函数,用于连接 Strapi 和 Astro。
在开始之前,你需要准备以下内容:
- Astro 项目 - 如果你还没有 Astro 项目,我们的安装指南将帮助你快速入门;
- Strapi CMS 服务器 - 你可以在本地环境中设置 Strapi 服务器。
在 .env 文件中添加 Strapi URL
Section titled “在 .env 文件中添加 Strapi URL”为了将 Strapi URL 添加到 Astro 中,你可以在项目的根目录中创建一个 .env 文件(如果还没有的话),并添加以下变量:
STRAPI_URL="http://127.0.0.1:1337" # 或者使用你的 IP 地址重启开发服务器以在你的 Astro 项目中使用这个环境变量。
如果你希望为环境变量使用 IntelliSense,可以在 src/ 目录下创建一个 env.d.ts 文件,并像这样配置 ImportMetaEnv:
interface ImportMetaEnv { readonly STRAPI_URL: string;}你的根目录现在应该包含了新的文件:
文件夹src/
- env.d.ts
- .env
- astro.config.mjs
- package.json
了解更多关于 Astro 中的 环境变量 和
.env 文件的内容。
创建 API 包装器
Section titled “创建 API 包装器”在 src/lib/strapi.ts 中创建一个新文件,并添加以下包装函数来与 Strapi API 进行交互:
interface Props { endpoint: string; query?: Record<string, string>; wrappedByKey?: string; wrappedByList?: boolean;}
/** * Fetches data from the Strapi API * @param endpoint - The endpoint to fetch from * @param query - The query parameters to add to the url * @param wrappedByKey - The key to unwrap the response from * @param wrappedByList - If the response is a list, unwrap it * @returns */export default async function fetchApi<T>({ endpoint, query, wrappedByKey, wrappedByList,}: Props): Promise<T> { if (endpoint.startsWith('/')) { endpoint = endpoint.slice(1); }
const url = new URL(`${import.meta.env.STRAPI_URL}/api/${endpoint}`);
if (query) { Object.entries(query).forEach(([key, value]) => { url.searchParams.append(key, value); }); } const res = await fetch(url.toString()); let data = await res.json();
if (wrappedByKey) { data = data[wrappedByKey]; }
if (wrappedByList) { data = data[0]; }
return data as T;}该函数需要一个具有以下属性的对象:
endpoint- 要获取的端点;query- 要添加到 URL 末尾的查询参数;wrappedByKey- 用于包装你Response对象中的data键;wrappedByList- 一个参数,用于“解封”Strapi 返回的列表,并只返回第一项。
可选:创建 Article 接口
Section titled “可选:创建 Article 接口”如果你使用 TypeScript,可以基于以下 Article 接口来创建 src/interfaces/article.ts,用于响应 Strapi 的内容类型:
export default interface Article { documentId: number; title: string; description: string; content: string; slug: string; createdAt: string; updatedAt: string; publishedAt: string;}你可以修改这个接口,或者创建多个接口,以适应你自己的项目数据。
文件夹src/
文件夹interfaces/
- article.ts
文件夹lib/
- strapi.ts
- env.d.ts
- .env
- astro.config.mjs
- package.json
展示文章列表
Section titled “展示文章列表”-
更新你的首页
src/pages/index.astro,用以展示一个博客文章列表,当中的每篇文章都有描述和链接到自己页面。 -
导入包装函数和接口。添加以下 API 调用来获取你的文章并返回一个列表:
src/pages/index.astro ---import fetchApi from '../lib/strapi';import type Article from '../interfaces/article';const articles = await fetchApi<Article[]>({endpoint: 'articles', // 需要获取的内容类型wrappedByKey: 'data', // 在响应中被拆封的键});---该 API 调用请求会从
http://localhost:1337/api/articles获取数据,并返回articles,这是一个表示数据的 JSON 对象数组:[{documentId: 1,title: "What's inside a Black Hole",description: "Maybe the answer is in this article, or not...",content: "Well, we don't know yet...",slug: "what-s-inside-a-black-hole",createdAt: "2023-05-28T13:19:46.421Z",updatedAt: "2023-05-28T13:19:46.421Z",publishedAt: "2023-05-28T13:19:45.826Z"},// ...] -
使用 API 返回的
articles数组中的数据,并在列表中展示你的 Strapi 博客文章。这些文章将链接到它们各自的页面,在下一步中你将创建这些页面。src/pages/index.astro ---import fetchApi from '../lib/strapi';import type Article from '../interfaces/article';const articles = await fetchApi<Article[]>({endpoint: 'articles?populate=image',wrappedByKey: 'data',});---<!DOCTYPE html><html lang="en"><head><title>Strapi & Astro</title></head><body><main><ul>{articles.map((article) => (<li><a href={`/blog/${article.slug}/`}>{article.title}</a></li>))}</ul></main></body></html>