调试一个Astro模板

初接触Astro感觉还不错

在调试Astro免费模板 Astrology-i18n 中的一些笔记

在很多astror的模板中,他们都使用的是URL为images.unsplash.com的图片源,国内对这个地址的反应时间太慢,所以有了下面的一些改进,基于AI编码,改进而来。

A 我提问: 我需要同时能显示本地图片和外部URL图片。

google AI 回答: 在 Astro 5.0 中,要让一个字段(如 heroImage)同时兼容本地相对路径和外部 URL 链接,你需要利用 Zod 的 z.union 或 z.or 来定义联合类型,并结合 image() 校验器。

以下是具体的代码实现和使用步骤:

  1. 修改 src/content.config.ts

你需要解构出 image 助手函数,并定义字段可以接受“本地优化图片”或“普通字符串(URL)”。

import { defineCollection, z } from 'astro:content';
import { glob } from 'astro/loaders';
// ... 保持 LANGS 定义不变
const post = defineCollection({
loader: glob({ pattern: '**/*.{md,mdx,markdown}', base: './src/content/posts' }),
// 注意这里:schema 变成了一个接收 { image } 参数的函数
schema: ({ image }) => z.object({
title: z.string(),
description: z.string(),
category: z.string(),
tags: z.array(z.string()).default([]),
pubDate: z.coerce.date(),
updatedDate: z.coerce.date().optional(),
author: z.string().default('Astro'),
// ✅ 核心修改:同时支持本地图片对象或 URL 字符串
heroImage: image().or(z.string()),
heroImageAlt: z.string(),
locales: z.enum(LANGS),
draft: z.boolean().default(false),
featured: z.boolean().default(false),
}),
});
// page 和 author 集合如果需要也可以按此方式修改
  1. 在 Markdown/MDX 中如何填写你可以根据图片来源灵活填写:使用本地图片(会自动压缩、转换格式):
---
title: "使用本地图片的文章"
heroImage: "./my-cover.jpg" # 必须以 ./ 开头,指向当前目录或相对路径
heroImageAlt: "本地图片描述"
---

使用外部 URL(直接引用,不进行本地压缩):

---
title: "使用链接的文章"
heroImage: "images.unsplash.com" # 完整的 URL
heroImageAlt: "外部图片描述"
---
  1. 在 .astro 组件中渲染 由于 heroImage 现在可能是“图片对象”或“字符串”,直接传给 <Image /> 组件时,如果是外部字符串,Astro 要求必须手动提供 width 和 height(除非你在配置里对该域名做了特殊设置)。 推荐的健壮渲染方式:
---
// src/components/PostCard.astro 或 src/pages/posts/[id].astro
import { Image } from 'astro:assets';
const { post } = Astro.props;
const { heroImage, heroImageAlt } = post.data;
// 判断是否是远程链接(简单的字符串检查)
const isExternal = typeof heroImage === 'string';
---
{
isExternal ? (
// 如果是外部链接,直接使用标准 img 标签或指定远程策略的 Image
<img
src={heroImage}
alt={heroImageAlt}
class="w-full h-auto rounded-lg"
/>
) : (
// 如果是本地图片,利用 Astro Image 组件进行自动优化(转 WebP/AVIF 等)
<Image
src={heroImage}
alt={heroImageAlt}
width={800}
height={450}
class="rounded-lg"
/>
)
}
  1. 为什么这样处理最好?

构建性能:2025 年的 Astro 构建速度虽然很快,但处理数千张本地图片仍需时间。通过将 heroImage 设置为 union,你可以对高质量的封面图用本地优化,对普通的引用图用外部链接,平衡视觉质量与构建速度。 安全性:对于外部 URL,你在 astro.config.mjs 中已经配置了 remotePatterns(如 Unsplash),这保证了只有可信域名的外部图片会被显示 [1]。

兼容性:当你将网站从 Vercel 迁移到自有服务器时,这种处理方式不需要服务器安装任何像 Sharp 这样的底层图像库,因为本地图片在你的开发电脑 build 阶段就处理好了,而外部图片则由用户浏览器直接下载。

D 我提问: md语法

google ai 答:在 Astro 5.0+ 中使用 Markdown (MD/MDX) 时,除了标准语法,你还需要特别注意 Content Layer (内容层) 的路径处理以及 Astro 特有组件 的集成。 以下是针对你目前项目配置的 Markdown 语法全指南:

  1. 基础 MD 语法 (标准) 这些在 Astro 中完全通用:
# 一级标题
## 二级标题
**加粗***斜体*~~删除线~~
- 无序列表
1. 有序列表
[链接文字](https://google.com)
![图片描述](../../assets/images/posts/kk.jpg)
> 引用块
  1. Frontmatter 配置 (关键) 根据你之前定义的 defineCollection schema,你的 MDX 开头必须包含这些字段,否则会构建报错:
---
title: "我的 2025 占星指南"
description: "这是一篇关于星座的深度分析"
category: "占星"
tags: ["星座", "运势"]
pubDate: 2025-12-31
heroImage: "../../assets/images/posts/kk.jpg" # 本地图片路径
heroImageAlt: "封面图描述"
locales: "zh" # 必须是你定义的 LANGS 之一
draft: false # 是否为草稿
featured: true # 是否推荐
---
  1. 代码块渲染 (Expressive Code) 因为你配置了 astro-expressive-code,你的代码块支持高级功能:
```js {1, 3-4} title="example.js" ins={6} del={2}
const a = 1; // 这一行会被高亮
const b = 2; // 这一行会被标记为删除
const c = 3;
const d = 4;
// 下面这一行会被标记为新增
console.log("Hello Astro 2025");
实际显示出来的效果如下:
```js {1, 3-4} title="example.js" ins={6} del={2}
const a = 1; // 这一行会被高亮
const b = 2; // 这一行会被标记为删除
const c = 3;
const d = 4;
// 下面这一行会被标记为新增
console.log("Hello Astro 2025");

释义如下:

{1}: 高亮第一行。 title=”…”: 给代码块加个标题栏。 ins / del: 模拟 Git 的新增/删除效果。

  1. MDX 特有:直接使用 Astro 组件 由于你安装了 @astrojs/mdx,你可以在 Markdown 里直接写交互组件或 HTML。 示例:在文章中插入你那个 GitHub 日历组件
import GitHubActivityCalendar from '../../components/widgets/GitHubActivityCalendar.astro';
# 个人动态
下面是我的 GitHub 贡献统计:
<GitHubActivityCalendar username="yourid" client:visible />

注意:在 MDX 中引入组件必须使用相对路径。

  1. 图片处理技巧 在 2025 年的 Astro 中,处理本地图片有两种 MD 写法:
标准 MD 写法(适合正文):
![描述](../../assets/images/photo.jpg) -> Astro 会自动压缩并转为 WebP。
HTML/组件写法(适合需要精细控制):
html
<img src="../../assets/images/photo.jpg" width="400" alt="说明" />
  1. 特殊功能:自动显示最后修改时间

你在配置中加了 remarkModifiedTime 插件。如果你想在页面上显示“最后更新于:2025-xx-xx”,通常需要在 .astro 模板中通过 remarkPluginFrontmatter 获取,而不是直接在 MD 语法里写。

  1. 避坑指南 (2025 常见错误)

a. 路径别名:在 MD/MDX 中,不能使用 @/assets/ 别名,必须用 ../../。
b. 空行:在 MDX 中,Import 语句和 Markdown 正文之间必须留一个空行。
c. i18n 路径:确保你的 MD 文件存放位置与 locales 字段对应。虽然你用了 routing: ‘manual’,但如果 src/content/posts/en/test.md 里的 locales 写成了 zh,可能会导致 Pagefind 搜索索引混乱。

  1. astro系统组件在MD文件中仅以文本方式显示。

如果在MD文件中有类似于 <Image /> 组件时,请加上转义符 \ 才会显示为文本,而不是组件。

发布于: 2025年12月31日 · 修改于: 2026年1月2日

相关文章