65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 Astro 创建博客网站

starIconstarIconstarIconstarIconstarIcon

5.00/5 (2投票s)

2024 年 10 月 9 日

CPOL

22分钟阅读

viewsIcon

3587

本文将介绍如何使用开源的 Astro 包来创建一个功能齐全的博客网站。

对于我即将推出的博客,我决定不想使用传统的 CMS 平台,如 WordPress。我是一名程序员,我宁愿使用一个从源代码生成博客的工具。这些工具被称为静态网站生成器(SSG),其中知名度较高的有 Hugo、Jekyll、Gatsby 和 Astro。我选择 Astro 是因为其对 TypeScript 的支持,尽管学习它花了一些时间,但我对其灵活性和性能感到满意。

本文的目的是介绍如何使用 Astro 构建一个功能齐全的博客网站。第一部分将介绍如何创建一个示例博客项目,然后从该项目中生成博客文件。接着,我们将探讨 Astro 文件的格式以及构成 Astro 项目的文件。文章的最后部分将介绍路由和自定义。

1. 入门

Astro 的使命是将包含 Astro 文件(*.astro)的项目转换为包含网站文件(主要是 *.html)的文件夹。与其从头开始,不如创建一个 Astro 的默认博客项目并按需进行自定义。本节将介绍如何创建默认项目,将其转换为博客网站,然后在浏览器中查看该网站。

1.1 创建项目

Astro 的访问通过 Node 包管理器(npm)提供。Node 指的是Node.js,它是一个运行时环境,可以访问超过两百万个软件包。其中绝大多数包都是免费的,因此,如果您正在构建 Web 应用程序,您可能会找到几个有用的包。

在使用 npm 创建 Astro 项目之前,您需要安装 Node.js。下载页面是 https://node.org.cn,您可以点击适合您操作系统和处理器类型(可能是 64 位)的链接来下载安装程序。本文假定您运行的是 Node 22 或更高版本。

安装 Node 后,您就可以从命令行运行 npm 了。每个命令都以 npm cmd_name 开头,其中 cmd_name 标识命令。要创建新的 Astro 项目,请执行以下命令:

npm create astro@latest

在创建新项目之前,Astro 会询问六个问题。

  1. 应在何处创建此项目? - 输入项目文件夹的所需位置,可以是绝对路径(C:\newblog)或相对于当前目录的路径(newblog)。
  2. 您希望如何启动项目? - 您可以在“Empty”(空)、“Use blog template”(使用博客模板)和“Include sample files”(包含示例文件)之间进行选择。本文重点介绍博客,因此请选择“Use blog template”(使用博客模板)。
  3. 您是否打算编写 TypeScript? - 您可以选择编写 TypeScript 代码(Yes)或 JavaScript 代码(No)。对于本文,请选择Yes
  4. TypeScript 应有多严格? - 您可以在“Relaxed”(宽松)、“Strict”(严格)和“Strictest”(最严格)之间进行选择。对于本文,Strict(严格)即可。
  5. 安装依赖项? 选择Yes,让 Node 安装创建 TypeScript Astro 项目所需的包。
  6. 初始化新的 Git 存储库? 选择Yes,让 Node 创建一个 Git 存储库以启用项目的版本控制。

回答完这些问题后,包管理器将下载 Astro 包及其依赖项,然后创建一个简单的博客网站项目。表 1 列出了项目中顶级目录的文件和文件夹。

表 1:Astro 项目中的文件和文件夹
文件名/文件夹名 描述
.git Git 存储库文件夹
.vscode Visual Studio Code IDE 的设置
node_modules Astro 所需的 Node 依赖项
public 将部署到网站的静态资源
src Astro 项目的源文件
.gitignore 不包含在 Git 存储库中的文件列表
astro.config.mjs Astro 配置设置
package.json 项目配置设置
package-lock.json 列出了依赖项及其依赖项
README.md 项目描述
tsconfig.json 包含 TypeScript 编译器设置

您可以保留大多数这些文件不动,但 src 文件夹值得关注。它包含 Astro 项目的源文件,本文的大部分内容都与此目录的内容有关。但在深入细节之前,最好先创建并查看博客。

1.2 构建和查看博客

创建 Astro 项目后,很容易将所有 *.astro 文件编译成 *.html 文件。在项目的顶级目录中打开命令提示符并执行以下命令:

npm run build

随着构建的进行,该工具将显示项目文件以及从中生成的 HTML 文件。以下文本是一个示例:

▶ src/pages/about.astro
  └─ /about/index.html (+12ms)
▶ src/pages/blog/index.astro
  └─ /blog/index.html (+13ms)
▶ src/pages/index.astro
  └─ /index.html (+3ms)

构建完成后,生成的文件将存储在一个名为 dist 的新顶级目录中。您可以通过在浏览器中打开 HTML 文件来查看它们。您还可以通过执行 npm run dev 来启动本地服务器。然后,在浏览器中访问 https://:4321 来查看博客。图 1 展示了博客主页的简化图示。

默认博客中的每个页面都有一个标题和一个页脚。它们之间的内容由一个或多个 Astro 文件的模板决定。下一节将介绍模板。

2. Astro 文件格式

如果您查看项目的 src 文件夹,您会发现大多数文件都是 Astro (*.astro) 文件。在我们深入研究项目之前,了解这些文件的内容以及内容的结构非常重要。每个 Astro 文件(最多)有两个部分:

  • frontmatter - 导入组件、定义变量并执行其他操作的 TypeScript
  • template - 在构建过程中渲染成 HTML 的标记,可以访问 frontmatter 中的组件和变量

frontmatter 是可选的,但如果存在,它必须包含在由三个连字符组成的行之间。这些被称为代码围栏,以下文本展示了代码围栏如何分隔 frontmatter 和模板:

---
frontmatter written in TypeScript
---
template written in markup

本讨论将介绍这两个部分。如果您对 TypeScript 和 HTML 有扎实的掌握,那么处理 Astro 文件将毫无问题。

2.1 Frontmatter

Astro 文件的 frontmatter 包含在模板渲染之前执行的代码。最常见的 frontmatter 操作包括导入数据结构以及声明变量和类型。

可以使用熟悉的 import 语句导入结构。这些语句可以访问 JavaScript 文件(*.js)、TypeScript 文件(*.ts)和其他 Astro 文件(*.astro)。例如,如果一个名为 XYZ 的数据结构定义在 ABC.astro 中,则可以使用以下代码导入它:

import XYZ from 'ABC.astro';

声明变量和类型同样简单。let 语句中的变量可以更新,const 语句中的变量不能更新,而 type 语句用于声明自定义类型。以下是一些典型的声明:

const today = new Date();

type Props = CollectionEntry<'blog'>['data'];

Astro 文件的 frontmatter 不仅限于导入和声明,但我遇到的代码中,这些语句占了绝大部分。

2.2 模板

每个 Astro 文件都有一个将在构建过程中转换为 HTML 的模板。这些部分以类似于 JavaScript XML (JSX) 的格式编写,而 JSX 又类似于 HTML。关于模板有两点需要了解:

  1. 模板可以使用常规的 HTML 标签,如 <div><a><head><body>。它还可以从导入的组件创建 HTML 标签,稍后章节将介绍组件。
  2. 模板可以包含用花括号括起来的 TypeScript 变量和表达式。例如,如果 x 是在 frontmatter 中声明的变量,那么它的值可以通过 {x} 插入到模板中。

为了演示这些要点,假设一个 Astro 文件的 frontmatter 导入了一个名为 MyComp 的组件,并声明了一个名为 compName 的变量。在模板中,以下标签创建了 MyComp 的一个实例,并将其 name 属性设置为 compName

<MyComp name={compName} />

当项目构建时,MyComp 的模板将被插入,其 name 属性将被设置为 compName

Astro 的模板语法在很多方面都类似于 JSX,但有一个主要的区别:Astro 文件的模板在构建后不会改变。也就是说,frontmatter 中的代码只会在构建期间执行,因此插入的变量只能取一个值。

3. 探索项目

此时,您应该已经熟悉 Astro 和 Astro 文件了。现在我们将深入研究项目的 src 目录。如果您打开此目录,您会发现表 2 中列出的文件夹和文件。

表 2:项目源(src)目录中的文件夹和文件
文件夹/文件名 描述
pages 表示要生成的页面的 Astro 文件(*.astro)
components 定义组件的 Astro 文件(*.astro)
content 提供博客帖子的 Markdown 文件(*.md 或 *.mdx)
layouts 定义页面可重用结构的 Astro 文件(*.astro)
styles 定义网站样式设置的 CSS 文件(*.css)
consts.ts 可在整个项目中访问的全局常量
env.d.ts 告诉 TypeScript 编译器在哪里可以找到 Astro 的类型声明

本节的目标是探讨这些文件夹并解释它们的文件功能。您对项目结构的理解越深入,就越容易自定义项目以适应您的博客。

3.1 Pages 文件夹

如果您查看 src/pages 文件夹,您会找到 index.astro、about.astro 以及一个名为 blog 的文件夹,其中包含另一个 index.astro 和一个不寻常但重要的文件 [...slug].astro。在构建过程中,src/pages 中的每个文件都将转换为一个或多个 HTML 文件。

如果您查看这些文件,您会发现它们的 frontmatter 包含如下所示的 import 语句:

import Header from '../components/Header.astro';

import Layout from '../layouts/BlogPost.astro';

Header 是从 components 文件夹中的一个文件导入的,因此可以安全地假设它是一个组件Layout 是从 layouts 文件夹中的一个文件导入的,因此它是一种特殊类型的组件,称为布局。稍后将对组件和布局进行介绍。

如果您比较 index.astro 和 about.astro,您会发现它们的模板大不相同。index.astro 像常规 HTML 文件一样包含 <head><body> 标签,但 about.astro 不包含任何这些标签。这是因为 about.astro 的页面结构是使用布局定义的,我稍后将解释什么是布局。

3.2 Components 文件夹

与许多 Web 框架一样,Astro 是一个以组件为中心的工具集。Astro 文件可以通过 import 语句访问组件,并将它们插入到模板中,就像它们是常规 HTML 元素一样。

每个组件都在一个单独的 Astro 文件中定义,包含 frontmatter 和模板部分。组件的模板可以访问两个重要功能:

  • props - 可用于每个组件的全局属性
  • template directives - 控制组件/元素如何行为的特殊属性

本讨论将介绍这些功能。

3.2.1 访问 Props

假设一个名为 MyComp 的组件有两个名为 attr1attr2 的属性。再假设一个布局组件导入 MyComp 并将其插入到其模板中,如下所示:

<code><MyComp attr1="abc" attr2="xyz" /></code>

在其 frontmatter 中,MyComp 组件可以通过全局 Astro.props 值(无需导入)访问属性值。以下代码可以说明其工作原理:

const { attr1, attr2 } = Astro.props;

此代码声明了变量 attr1attr2,并将它们的值分别设置为组件属性的值(在此示例中为“abc”和“xyz”)。这些变量可以在模板的任何地方使用,方法是用花括号括起来:{attr1}{attr2}

为了启用类型检查,许多组件会创建一个接口,为传入的属性分配类型。在以下代码中,接口包含 attr1attr2,并将它们都分配给 string 类型:

interface Props {
    attr1: string;
    attr2?: string;
}

如果任何一个属性不是字符串,Astro 将在构建过程中产生警告/错误。attr2 后面的问号告诉 Astro 该属性是可选的。

3.2.2 Template Directives

模板指令是可以在 Astro 模板中的组件或其他 HTML 元素中插入的特殊属性。每个指令名称由两个由冒号分隔的单词组成,有三个通用指令:

  • class:list - 将元素数组转换为字符串
  • set:html - 将字符串注入元素(类似于 innerHTML
  • set:text - 将文本注入元素(类似于 innerText

模板可以包含 JavaScript,但默认情况下,组件不会在客户端进行水合。要控制何时对组件进行水合,您需要在组件中插入一个客户端指令。Astro 提供了六个客户端指令:

  • client:load - 页面加载时立即对组件进行水合
  • client:idle - 页面加载后,在 requestIdleCallback 事件触发后对组件进行水合
  • timeout - 在进行水合之前等待的最大时间
  • client:visible - 当组件进入用户视口时对其进行水合
  • client:media - 当满足 CSS 媒体查询时对组件进行水合
  • client:only - 跳过服务器渲染,仅在客户端进行渲染

如果您查看 src/components 文件夹中的 HeaderLink.astro 文件,您会发现它使用 class:list 指令来设置锚点的文本。不幸的是,没有一个组件模板演示了客户端指令的用法。

3.3 Layouts 文件夹

src/layouts 目录中的 Astro 文件定义了称为布局的特殊组件。布局的目标是指定可在整个博客中使用的页面结构。src/pages 目录中的 Astro 文件可以导入布局来定义页面的基本元素,如 <html><head><body><style> 等。

例如,如果您查看 src/pages/about.astro,您会发现它的 frontmatter 和模板具有以下结构:

---
import Layout from '../layouts/BlogPost.astro';
---
<Layout ...>
   ...
</Layout>

frontmatter 导入了布局 组件,它在模板中用作顶级元素。这提供了页面的结构,如果您查看 BlogPost.astro,您会发现它的模板具有以下内容:

<html ...>
    <head>
        <BaseHead ... />
        <style>
            ...
        </style>
    </head>

    <body>
        <Header />
        <article>
            <div class="hero-image">
                ...
            </div>
            <div class="prose">
                <div class="title">
                    ...
                </div>
                <slot />
            </div>
        </article>
        <Footer />
    </body>
</html>

如所示,布局包含 BaseHeadHeaderFooter 等组件。BaseHead 的模板由 <meta><link> 元素组成,在构建过程中,这些元素将被插入到使用此布局的每个页面的 <head> 中。

在 class 为 prose<div> 元素中,有一个名为 <slot /> 的重要元素。这就是布局组件中的内容将被放置的地方。回到 about.astro 中的模板,<Layout></Layout> 之间的标记将被放置在 Layout 组件模板的 <slot /> 元素中。

大多数博客每页显示一篇帖子。对于 Astro 博客,这些页面的结构由一个布局组件决定。这使得正确编写布局组件变得很重要。

3.4 Content 文件夹

本质上,Astro 项目的目的是打包博客的内容以便部署。如果您查看 src/content,您会找到一个名为 blog 的文件夹和一个名为 config.ts 的文件。blog 文件夹中的文件包含博客的帖子,这些帖子使用 Markdown (*.md) 和 Markdown eXtended (*.mdx) 编写。config.ts 文件导出一个集合,允许组件访问博客的帖子。

3.4.1 Content 文件

得益于 Github,Markdown 语言在文本格式化方面已变得非常流行。如果一个内容文件的后缀是 *.md,那么它的文本可以使用 Markdown 的语法规则进行格式化。表 3 列出了九种基本规则,并对每种规则进行了描述。

表 3:基本 Markdown 语法
格式规则 示例 描述
标题 # 一级标题
## 二级标题
# 号越多,
标题越小
斜体 * 斜体文字 * 一个星号打印斜体文字
粗体 ** 粗体文字 ** 两个星号打印粗体文字
无序列表 - 无序
- 无序
连字符创建无序列表项
有序列表 1. 项 1
2. 项 2
数字-点-空格创建项目
在有序列表中
代码 `代码字体` 反引号打印代码字体文本
水平线 --- 三个连字符创建一条水平线
Image ![alt](img.png) 方括号中的替代文本,
然后是括号中的图像文件
超链接 [文本](https://www.xyz.com) 方括号中的打印文本,
然后是括号中的 URL

除了这些规则之外,Markdown 还支持自己的 frontmatter,通常用于提供元数据。与 Astro 文件一样,Markdown 文件中的 frontmatter 也用代码围栏包围。与 Astro 文件不同,Markdown frontmatter 是用 YAML 编写的,这意味着名称和值由冒号分隔。以下文本可以说明其外观。

---
title: "Title"
author: "Tom Smith"
---
# This is an important heading!

如果一个文件的后缀是 *.mdx,那么它就是用 Markdown eXtended (MDX) 编写的,它将 Markup 格式的简洁性与 Astro 文件的灵活性结合起来。MDX 是 Markdown 的超集,因此它支持常规的格式规则和 frontmatter。此外,还有四点需要了解:

  1. TypeScript import/export 语句可以插入到文本的任何位置。
  2. 导入后,组件可以使用类似于 Astro 模板的标记插入到文本中。
  3. frontmatter 中的名称可以作为 frontmatter 类的属性访问。例如,如果 title 在 frontmatter 中被赋值,那么它可以在文本中作为 {frontmatter.value} 访问。
  4. MDX 可用于 src/pages 中的文件以及 src/content 中的文件。

如果您查看项目中的 src/content/blog 文件夹,您会看到一个名为 using-mdx.mdx 的文件。这演示了 MDX 如何在博客文章中使用。

3.4.2 Content Collections 和 config.ts

src/content 中的任何文件都称为内容条目,src/content 中的任何顶级文件夹都称为内容集合。每个集合包含特定类型的内容,因此如果您的站点包含博客文章和源代码文件,它们应该存储在单独的集合中。

在代码中,通过调用 astro:content 导出的 defineCollection 函数来创建内容集合。在示例项目中,这由 src/content 中的 config.ts 文件调用,其完整代码如下:

import { defineCollection, z } from 'astro:content';
const blog = defineCollection({
    type: 'content',
    // Type-check frontmatter using a schema
    schema: z.object({
        title: z.string(),
        description: z.string(),
        // Transform string to Date object
        pubDate: z.coerce.date(),
        updatedDate: z.coerce.date().optional(),
        heroImage: z.string().optional(),
    }),
});
export const collections = { blog };

在此代码中,schema 属性访问每个内容条目的 frontmatter。默认情况下,titledescriptionpubDate 字段是必需的,而 updatedDataheroImage 字段是可选的。export 语句使内容集合在整个项目中可用。稍后,我将解释组件如何访问此内容并将其插入页面。

3.5 Styles

如果您打开 src/styles 目录,您会发现一个名为 global.css 的文件。此样式表中定义的规则适用于整个项目,无需导入。

您可以更改博客的字体,方法是更改 font-face 规则。body 规则的设置尤为重要,因为它们适用于网页正文中的每个组件。

4. 路由

如果您通过运行 npm run build 来构建默认项目,则生成的博客文件将存储在项目的 dist 文件夹中。此文件夹中的 HTML 文件是从项目 src/pages 和 src/content 文件夹中的文件生成的。

表 3 阐明了项目六个源文件和生成文件之间的关系。第一列列出了源文件的路径,第二列列出了生成文件的路径,第三列列出了生成文件的 URL。URL 是相对于 www.example.com 给出的,因为这是 astro.config.mjs 中指定的默认站点。

表 4:生成的文件和 URL
源文件 生成的文件 URL
src/pages/index.astro dist/index.html www.example.com
src/pages/about.astro dist/about.html www.example.com/about
src/pages/blog/index.astro dist/blog/index.html www.example.com/blog
src/content/blog/first-post.md dist/blog/first-post/index.html www.example.com/blog/first-post
src/content/blog/second-post.md dist/blog/second-post/index.html www.example.com/blog/second-post
src/content/blog/third-post.md dist/blog/third-post/index.html www.example.com/blog/third-post

如所示,Astro 为 src/content/blog 中的每个 Markdown 文件(*.md)创建一个目录,每个目录都有一个 index.html 文件。如前所述,Astro 将 src/content/blog 文件夹称为内容集合,该文件夹中的每个文件都是一个内容条目。

此表具有误导性,因为 Astro 并不直接将内容条目转换为 HTML 文件。要理解转换是如何执行的,您需要了解两个主题:

  1. Astro 的 CollectionEntry 类型
  2. src/content/blog 文件夹中的 [...slug].astro 文件

一旦您理解了这两个主题,您将对 Astro 的动态路由有一个扎实的掌握,它会自动为博客文章生成 HTML 文件。

4.1 CollectionEntry 类型

如前所述,src/content/config.ts 文件调用 defineCollection 函数,并传入一个具有 typeschema 属性的对象。type 属性设置为 contentschema 包含博客文章 frontmatter 的字段。该函数的返回值是一个 CollectionConfig

Astro 的 getCollection 函数接受一个 CollectionConfig 并返回一个 CollectionEntry。这个重要的对象有五个属性:

  • id - 对于内容条目,这是 markdown 文件(*.md 或 *.mdx)的名称
  • collection- 包含该条目的内容集合的名称(blog
  • data- 包含 CollectionConfigschema 属性中的字段
  • slug- 作为条目 URL 最后一部分的文本
  • body- 内容文件中的文本

默认情况下,Astro 将 slug 属性设置为 id 属性,方法是移除文件后缀、将每个字符转换为小写,并将每个空格和下划线替换为连字符。您可以通过在博客文章文件中添加 slug 字段到 frontmatter 来为条目设置自定义 slug。

除了这些属性之外,每个 CollectionEntry 都有一个名为 render 的方法。它编译条目的内容并返回一个 Astro 组件,该组件显示编译后的结果。

4.2 [...slug].astro 文件

/src/pages/blog 文件夹中的 [...slug].astro 文件负责为 /src/content/blog 中的每个内容条目创建页面。其内容如下:

---
import { type CollectionEntry, getCollection } from 'astro:content';
import BlogPost from '../../layouts/BlogPost.astro';

export async function getStaticPaths() {
    const posts = await getCollection('blog');
    return posts.map((post) => ({
        params: { slug: post.slug },
        props: post,
    }));
}
type Props = CollectionEntry<'blog'>;

const post = Astro.props;
const { Content } = await post.render();
---

<BlogPost {...post.data}>
    <Content />
</BlogPost>

frontmatter 中的代码形成一个内容条目列表,并告诉 Astro 为列表中的每个元素创建一个页面。有四点需要注意:

  1. 如果 Astro 文件名用方括号括起来,其 frontmatter 可以将其名称作为变量访问。[...slug].astro 的 frontmatter 访问一个名为 slug 的变量。
  2. frontmatter 调用 getCollection 来访问名为 blog 的集合中的 CollectionEntry 对象。
  3. frontmatter 遍历条目并创建一个元素数组。该数组的每个元素都有一个名为 params 的属性,而每个 params 都有一个名为 slug 的属性,其值等于 CollectionEntryslug 属性。
  4. frontmatter 导出一个名为 getStaticPaths 的函数,该函数返回第 4 步中构建的数组。当 Astro 调用此函数时,它会为数组中的每个元素创建一个目录,并将其命名为 params.slug。这解释了为什么 Astro 会创建 dist/blog/first-post、dist/blog/second-post 等。

要设置这些生成页面的内容,[...slug].astro 执行四个操作:

  1. frontmatter 调用每个 CollectionEntry 的 render 方法。生成的组件被赋予名称 Content
  2. 模板包含一个 BlogPost 组件,该组件定义了页面的布局。
  3. 模板将 CollectionEntrydata 字段传递给 BlogPost,后者可以通过 Astro.props 访问它。
  4. 模板将 Content 组件插入到 BlogPost 组件内部。结果是,CollectionEntry 内容将替换布局组件模板中的 <slot /> 元素。

Astro 将此页面生成过程称为静态模式,因为页面是在构建过程中生成的。Astro 还支持服务器模式,在该模式下,页面由服务器渲染。这不使用 getStaticPaths,您可以 此处 了解更多关于服务器模式的信息。

5. 自定义博客

此时,您应该对如何向 Astro 项目添加帖子以及如何将项目转换为 HTML 有了扎实的理解。本节将介绍博客作者可能想要执行的一些自定义任务。

5.1 项目配置

如果您正在创建一个新博客,第一个要更改的文件是项目顶级目录中的 astro.config.mjs。这是项目的中心配置文件,默认情况下,其内容如下:

import { defineConfig } from 'astro/config';
import mdx from '@astrojs/mdx';

import sitemap from '@astrojs/sitemap';

// https://astro.js.cn/config
export default defineConfig({
    site: 'https://example.com',
    integrations: [mdx(), sitemap()],
});

至少,您应该将 site 属性更改为您的网站 URL。如果您不想包含 MDX,可以删除第二个 import 语句,并从 integrations 数组中删除 mdx() 元素。

Astro 在 astro.config.mjs 中支持许多其他配置选项。您可以在 此处 阅读完整的列表。

5.2 Header 和 Header Links

默认博客在左上角有一个标题(Astro Blog),在上中心有三个链接(HomeBlogAbout),在右上角有社交链接(MastodonTwitterGithub)。顶部的横幅在 src/components/Header.astro 中定义,其模板标记如下:

<h2><a href="/">{SITE_TITLE}</a></h2>
<div class="internal-links">
    <HeaderLink href="/">Home</HeaderLink>
    <HeaderLink href="/blog">Blog</HeaderLink>
    <HeaderLink href="/about">About</HeaderLink>
</div>
<div class="social-links">
    ...
</div>

此标记的第一行设置了左上角的博客标题,文本从项目 src 目录中的 consts.ts 导入。此文件的默认内容如下:

export const SITE_TITLE = 'Astro Blog';
export const SITE_DESCRIPTION = 'Welcome to my website!';

您可能需要更改这些常量。此外,如果您有任何字符串希望在整个网站中使用(例如版权声明),最好将其添加到 src/consts.ts。

Header 组件的模板中,class 为 internal-links 的 division 创建了上中心的HomeBlogAbout 链接。这些链接被实现为 HeaderLink 组件的实例,该组件定义在 src/components/HeaderLink.astro 中。

5.3 BaseHead 组件

如果搜索引擎优化 (SEO) 是一个关注点,您可以向 src/components/BaseHead.astro 中定义的 BaseHead 组件添加关键字和其他项。BlogPost 布局将 BaseHead 插入到使用该布局的每个页面的 <head> 元素中。

Basehead 还设置了网站的图标,以下标记设置了默认图像:

<link rel="icon" type="image/svg+xml" href="/favicon.svg" />

您可能需要更改规范 URL,该 URL 在页面可通过多个 URL 访问时设置页面的首选 URL。默认规范 URL 的设置方式如下:

<link rel="canonical" href={canonicalURL} />

BaseHeadBlogPost 组件接收 titledescription 属性,该组件将它们设置为 src/consts.ts 中的 SITE_TITLESITE_DESCRIPTION 常量。在 BaseHead 模板中,这些属性用于设置页面的主要元元素:

<title>{title}</title>
<meta name="title" content={title} />
<meta name="description" content={description} />

如果您希望您的博客网站能在社交媒体上分享,您可以添加由 Open Graph 协议定义的元数据。为此,BaseHead 包含以下几行:

<meta property="og:type" content="website" />
<meta property="og:url" content={Astro.url} />
<meta property="og:title" content={title} />
<meta property="og:description" content={description} />
<meta property="og:image" content={new URL(image, Astro.url)} />

在这些标签中,变量 Astro.url 始终设置为插入这些标签的页面的 URL。

5.4 Footer 组件

在博客底部,页脚显示版权声明和社交媒体链接。Footer 组件的缩写结构如下:

<footer>
    &copy; {today.getFullYear()} Your name here. All rights reserved.
    <div class="social-links">
        ...
    </div>
</footer>
<style>
    ...
</style>

自然,您会想在页脚中添加您的名字。您可以设置页脚的背景颜色和填充,方法是设置 <style>...</style> 标签中的属性。

5.5 Really Simple Syndication (RSS)

RSS 允许用户在无需手动访问网站的情况下访问博客内容。要支持 RSS,博客需要提供一个符合 RSS 2.0 标准格式的文件。该格式基于 XML,并使用 <rss></rss> 作为根元素。

如果您查看 dist 文件夹,您会发现 Astro 构建生成了一个名为 rss.xml 的文件。该文件的内容由项目 src/pages 文件夹中的 rss.xml.js 文件决定。它定义了一个名为 GET 的函数,该函数如下定义:

export async function GET(context) {
    const posts = await getCollection('blog');
    return rss({
        title: SITE_TITLE,
        description: SITE_DESCRIPTION,
        site: context.site,
        items: posts.map((post) => ({
            ...post.data,
            link: `/blog/${post.slug}/`,
        })),
    });
}

在 RSS Feed 中,<title> 元素设置为 SITE_TITLE<description> 元素设置为 SITE_DESCRIPTION。Feed 还将为每个博客文章包含一个 <item> 元素。如果您想用不同的元素自定义 RSS Feed,rss.xml.js 是要修改的文件。

历史

本文最初于 2024 年 10 月 9 日提交。

© . All rights reserved.