半神 Astro 博客主题使用说明
半神 Astro 博客主题使用说明
半神是一个基于 Astro 的中文静态博客主题。它保留了旧导航主题的网格背景、玻璃卡片和高信息密度风格,并把文章、归档、分类、标签、动态、相册、装备、音乐、友链、数据页、搜索、评论和外观设置都整理成 Astro 项目结构。
这份文档按“之前用过 Hugo,但没用过 Astro”的习惯来写。你可以把 Astro 理解成另一套静态站点生成器:文章放在 src/content/,站点数据放在 src/data/,页面模板放在 src/pages/,公共静态资源放在 public/,构建后输出到 dist/。
快速开始
先确认本机已安装 Node.js,建议使用当前 LTS 版本。
npm install
npm run dev开发服务器启动后,默认访问:
http://127.0.0.1:4321/构建正式静态文件:
npm run build本地预览构建结果:
npm run preview常用命令说明:
| 命令 | 作用 |
|---|---|
npm run dev | 开发预览,修改文件后自动刷新 |
npm run build | 类型检查、构建静态站点,并修正旧文章 .html 链接 |
npm run preview | 预览 dist/ 构建结果 |
npm run check | 只运行 Astro 类型检查 |
不要手动修改 dist/。dist/ 是构建产物,每次 npm run build 都会重新生成。
Hugo 用户先看这里
| Hugo 习惯 | Astro 里对应位置 |
|---|---|
hugo.toml / config.toml | astro.config.mjs 和 src/data/site.ts |
content/posts/*.md | src/content/posts/*.md |
data/*.yaml | src/data/*.ts |
static/ | public/ |
layouts/ | src/pages/、src/layouts/、src/components/ |
assets/css | src/styles/global.css 和各 .astro 文件底部的 <style> |
hugo server | npm run dev |
hugo | npm run build |
public/ 输出目录 | dist/ 输出目录 |
Astro 的页面路由来自 src/pages/ 文件名。例如 src/pages/about.astro 会生成 /about/,src/pages/posts/[...id].astro 会生成文章详情页。
项目目录
astro-demius/
├─ astro.config.mjs # Astro 构建配置、站点域名、Markdown 短代码插件、代码高亮主题
├─ package.json # 项目依赖和 npm 脚本
├─ README.md # 当前说明文档
├─ scripts/
│ └─ postbuild-legacy-posts.mjs # 构建后处理旧站 /posts/xxx.html 链接
├─ public/ # 静态资源,构建时原样复制到网站根目录
│ ├─ img/ # 头像、Logo、二维码、装备图片、友链头像等
│ ├─ audio/ # 本地音乐文件
│ ├─ favicon.svg
│ └─ og.svg
└─ src/
├─ content.config.ts # 文章 Front Matter 字段规则
├─ content/posts/ # 所有文章 Markdown / MDX
├─ data/ # 站点配置、友链、动态、相册、装备、音乐
├─ pages/ # 页面路由
├─ layouts/ # 页面基础布局
├─ components/ # 通用组件
├─ styles/global.css # 全局样式、色盘、网格背景、文章样式、短代码样式
└─ utils/ # 文章工具、分页、短代码转换最重要的配置文件
站点基础信息
修改:
src/data/site.ts这里控制站点大部分基础信息:
| 字段 | 作用 |
|---|---|
name、title | 站点名称和浏览器标题 |
subtitle | Logo 旁边和侧栏作者卡简介 |
description | 默认 SEO 描述 |
author | 作者名,底部版权也会使用 |
url | 正式域名,SEO、RSS、友链本站信息会用到 |
avatar | 作者头像路径 |
logo | 导航栏 Logo 路径 |
postsPerPage | 文章列表每页数量 |
since | 建站年份,底部版权和本站运行时间从这里算 |
announcement | 首页公告兜底文字 |
announcements | 首页公告轮播列表 |
appearance | 默认外观设置 |
security | 构建前配置的站点保护开关 |
comments.artalk | Artalk 评论配置 |
reward | 文章底部赞赏二维码 |
hero | 首页顶部轮播内容 |
示例:
export const siteConfig = {
title: '半神',
subtitle: '时间就是生命,Life is money,Money is life',
url: 'https://blog.demius.space',
avatar: '/img/avatar.png',
logo: '/img/logo.png',
since: 2024
};正式域名
正式上线前同时修改两个位置:
astro.config.mjs
src/data/site.tsastro.config.mjs:
export default defineConfig({
site: 'https://你的域名'
});src/data/site.ts:
url: 'https://你的域名'这会影响:
- canonical 地址
- RSS 链接
- sitemap 链接
- Open Graph 图片地址
- 分享链接
- 旧站文章 SEO 保持
文章怎么写
文章放在:
src/content/posts/支持 .md 和 .mdx。普通文章用 .md 就够了。
一键创建文章模板:
npm run new:post带标题创建:
npm run new:post -- "我的新文章"常用参数:
npm run new:post -- "我的新文章" --slug my-new-post
npm run new:post -- "我的新文章" --filename "我的新文章"
npm run new:post -- "我的新文章" --category 技术 --tag Astro
npm run new:post -- "我的新文章" --publish默认情况下,新建脚本会用文章标题作为本地 Markdown 文件名,方便在 src/content/posts/ 里整理;浏览器地址栏使用 front matter 里的 slug,中文标题会自动转成拼音连字符格式。
生成的文件默认是草稿,Front Matter 里每个配置项都有注释。写完后把 draft: true 改成 draft: false 就会发布。
新建文章示例:
src/content/posts/my-first-post.mdFront Matter 示例:
---
title: 我的第一篇文章
description: 这是一段文章摘要,会用于列表、搜索和 SEO。
pubDate: 2026-06-09
updatedDate: 2026-06-09
author: 半神
thumbnail: /img/default-cover.webp
cover: /img/default-cover.webp
coverAlt: 封面说明
categories:
- 技术
tags:
- Astro
- 博客
draft: false
pinned: false
featured: false
series: 半神主题
---
## 正文标题
这里写正文。文章字段说明:
| 字段 | 必填 | 说明 |
|---|---|---|
title | 是 | 文章标题 |
description | 是 | 摘要,用于文章卡片、搜索、SEO |
pubDate | 是 | 发布时间 |
updatedDate | 否 | 更新时间 |
author | 否 | 作者,默认值在 src/content.config.ts |
thumbnail | 否 | 文章卡片缩略图,优先级最高 |
cover | 否 | 备用封面图,文章卡片可使用,但文章详情页顶部不显示大图 |
coverAlt | 否 | 封面图说明 |
slug | 否 | 文章公开地址短名,用来生成 /posts/xxx.html;不写时会自动从文件名、标题生成拼音/英文 slug,最后用日期 hash 兜底 |
legacySlug | 否 | 旧站文章短链接,用来保留 /posts/xxx.html |
categories | 否 | 分类数组 |
tags | 否 | 标签数组 |
draft | 否 | true 时不发布 |
pinned | 否 | 首页和文章列表优先排序 |
featured | 否 | 精选标记,当前首页精选区已移除,但字段保留 |
series | 否 | 系列名 |
文章地址规则
没有 legacySlug:
src/content/posts/我的第一篇文章.md
=> /posts/wo-de-di-yi-pian-wen-zhang.html如果你希望地址更短或更像英文关键词,可以手动写一个更可读的 slug:
slug: my-first-post有 legacySlug:
legacySlug: fwv2okpo生成地址:
/posts/fwv2okpo.html这是旧 Hugo 站迁移时保留 SEO 的关键。只要正式域名不变,旧文章地址也不变。
缩略图规则
文章卡片缩略图优先级:
thumbnailcover- 主题根据文章标题动态生成的默认缩略图
动态缩略图逻辑在:
src/utils/posts.ts如果想修改默认缩略图风格,改 generatedPostThumbnail()。
首页内容怎么改
首页文件:
src/pages/index.astro首页内容数据主要来自:
src/data/site.ts
src/content/posts/常改内容:
| 内容 | 修改位置 |
|---|---|
| 顶部轮播标题、描述、图片、链接 | src/data/site.ts 的 hero.slides |
| 首页顶部主标题和介绍 | src/data/site.ts 的 hero |
| 公告文字和链接 | src/data/site.ts 的 announcements |
| 最新发布文章 | 自动读取 src/content/posts/ |
| 热门文章卡片 | 首页逻辑在 src/pages/index.astro |
| 文章单双三列默认值 | src/data/site.ts 的 appearance.postLayout |
首页轮播方向在外观设置里可以切换,默认值在:
appearance: {
heroDirection: 'left'
}可选:
left
right
up
down外观设置怎么改
外观设置组件:
src/components/AppearanceRuntime.astro默认外观配置:
src/data/site.ts当前支持:
| 功能 | 默认配置字段 | 说明 |
|---|---|---|
| 主题色盘 | accent | forest、sky、rose、amber、violet、slate、dark |
| 侧栏左右 | sidebar | right 或 left |
| 首页文章列数 | postLayout | 1、2、3 |
| 首页顶部显示 | homeHero | on 或 off |
| 首页轮播方向 | heroDirection | left、right、up、down |
| 粒子背景 | particles | on 或 off |
| 氧气泡背景 | oxygenBubbles | on 或 off |
| 头像礼花 | avatarEffect | on 或 off |
| 侧栏作者卡 | sidebarAuthor | on 或 off |
用户在浏览器里修改外观后,会保存在 localStorage 的 demius-appearance,所以刷新后仍会保持个人选择。
右键菜单和开发者工具入口保护不属于外观设置,不会显示在部署后的外观面板中,也不会读取用户浏览器的 localStorage。这两个开关只在构建前修改:
security: {
disableContextMenu: 'off',
disableDevtools: 'off'
}把值改成 'on' 后重新执行 npm run build,生成的静态文件会按配置拦截游客右键和常见开发者工具快捷键,并显示关心提醒。
色盘和全局颜色在:
src/styles/global.css重点看这些 CSS 变量:
:root {
--bg: ...;
--surface: ...;
--text: ...;
--accent: ...;
--cool: ...;
--warm: ...;
}每个色盘都有类似:
:root[data-accent='forest'] { ... }
:root[data-theme='dark'][data-accent='forest'] { ... }导航栏怎么改
导航数据在:
src/data/site.ts修改 navItems:
export const navItems = [
{ title: '首页', href: '/', icon: House },
{ title: '文章', href: '/posts/', icon: BookOpen },
{ title: '生活', href: '/life/', icon: Compass }
];导航栏组件在:
src/components/layout/Header.astro移动端菜单也使用同一份 navItems。
侧栏怎么改
侧栏组件:
src/components/Sidebar.astro侧栏当前包含:
- 作者信息卡
- 站点概览
- 最新评论
- 盲盒文章
站点概览统计来自文章、分类、字数、最后更新时间等构建期数据。字数统计函数在:
src/utils/posts.ts如果想改字数统计口径,改:
countPostWords()
totalPostWords()
formatWordCount()侧栏显示位置由外观设置控制:
right
left布局 CSS 在:
src/styles/global.css搜索关键词:
.main-grid
[data-sidebar='left']
.sidebar底部怎么改
底部组件:
src/components/layout/Footer.astro底部包含:
- 逆行人生组件
- 版权年份
- 本站运行时间
运行时间起点来自:
src/data/site.ts字段:
since: 2024改成 2025 后,底部版权和运行时间起点都会同步变化。
关于页面怎么改
关于页:
src/pages/about.astro这是独立页面,不使用侧栏。页面中的个人介绍、卡片、时间线、标签等都在这个文件里改。头像仍然可以复用:
src/data/site.ts -> avatar文章详情页怎么改
文章详情组件:
src/components/PostDetail.astro它负责:
- 文章标题区
- 文章元信息
- 正文渲染
- 文章目录
- 上一篇/下一篇
- 评论区
文章底部作者卡:
src/components/PostAuthorCard.astro这里负责:
- 赞赏作者
- 微信和支付宝二维码
- 分享按钮
- 复制链接
赞赏二维码路径在:
src/data/site.ts -> reward
public/img/weixin.webp
public/img/zhifubao.jpg评论系统 Artalk
评论组件:
src/components/Comments.astro默认不填写 Artalk 服务地址时,评论不会加载,只显示预留说明。
创建 .env:
PUBLIC_ARTALK_SERVER=https://你的-artalk-服务地址
PUBLIC_ARTALK_SITE=半神或者在部署平台里配置同名环境变量。
侧栏最新评论也依赖 Artalk。如果没有配置 PUBLIC_ARTALK_SERVER,侧栏会显示提示。
搜索怎么改
搜索页:
src/pages/search.astro搜索索引:
src/pages/search.json.js搜索弹窗:
src/components/SearchDialog.astro搜索数据来自所有非草稿文章,使用 Fuse.js 在浏览器端搜索。快捷键是:
Ctrl + K
Command + K生活入口和生活子页面
生活入口:
src/pages/life.astro生活入口只是聚合入口,不重复展示所有内容。具体内容在各子页面维护:
| 页面 | 路由 | 内容数据 |
|---|---|---|
| 动态 | /moments/ | src/data/moments.ts |
| 友链 | /links/ | src/data/links.ts |
| 相册 | /gallery/ | src/data/gallery.ts |
| 装备 | /gear/ | src/data/gear.ts |
| 音乐 | /music/ | src/data/music.ts |
| 数据 | /data/ | 自动统计文章和数据文件 |
这些页面都不使用侧栏。
动态页面怎么改
数据文件:
src/data/moments.ts页面文件:
src/pages/moments.astro本地动态示例:
export const moments = [
{
id: 'today',
content: '今天继续打磨半神主题。',
date: '2026-06-09 20:00',
tags: ['主题'],
location: '工作台',
source: 'local',
media: [
{ type: 'image', url: '/img/default-cover.webp', alt: '图片说明' }
],
stats: {
likes: 1,
comments: 0
}
}
];说说显示开关和 Ech0 同步配置也在 src/data/moments.ts:
export const shuoshuoConfig = {
enabled: true
};
export const ech0SyncConfig = {
enabled: false,
apiUrl: '',
homepage: '',
limit: 30
};如果只想保留时间线、不显示说说视图,把 shuoshuoConfig.enabled 改为 false。部署 Ech0 后,把 ech0SyncConfig.enabled 改为 true,填入 apiUrl。
友链页面怎么改
数据文件:
src/data/links.ts页面文件:
src/pages/links.astro友链数据结构:
export const friendLinks = [
{
title: '站点名称',
description: '站点描述',
url: 'https://example.com',
avatar: 'https://example.com/avatar.png',
tags: ['技术', '生活'],
group: '一些博客'
}
];友链页的戴森球中心会自动找与 siteConfig.url 相同域名的链接作为本站核心。如果没有找到,就用第一条友链。
本站友链信息代码块在:
src/pages/links.astro搜索:
selfLinkSnippet如果要改戴森球视觉、旋转、卡片、弹窗样式,也在 src/pages/links.astro 里改。
相册页面怎么改
数据文件:
src/data/gallery.ts页面文件:
src/pages/gallery.astro数据结构:
export const galleryItems = [
{
title: '照片标题',
description: '照片描述',
image: '/img/gallery/demo.webp',
date: '2026-06-09',
category: '生活'
}
];图片放到:
public/img/gallery/引用时写:
/img/gallery/demo.webp装备页面怎么改
数据文件:
src/data/gear.ts列表页面:
src/pages/gear.astro详情页面:
src/pages/gear/[id].astro装备是两层结构:
gearSetups是总装备卡片,例如电脑装备、露营设备。parts是这个装备下的配件树,例如 CPU、显示器、鼠标、键盘。
简化示例:
export const gearSetups = [
{
id: 'main-workstation',
name: '电脑装备',
type: '电脑整机',
group: '桌面工作流',
status: '使用中',
date: '2026-06-09',
price: '约 13999 元',
image: '/img/gear/setup-workstation.png',
summary: '主力开发电脑。',
description: '这里写装备详情。',
parts: [
{
id: 'keyboard',
name: '键盘名称',
category: '键盘',
role: '写作与代码',
spec: '配件规格',
price: '约 999 元',
date: '2026-06-09',
status: '使用中',
image: '/img/gear/part-keyboard.png',
note: '使用体验'
}
]
}
];装备图片放到:
public/img/gear/音乐页面怎么改
数据文件:
src/data/music.ts页面文件:
src/pages/music.astro本地音乐最稳,直接可播放:
{
server: 'local',
type: 'local',
title: 'Demo Track',
artist: 'Demius',
note: '本地歌曲说明',
url: '/audio/demo.mp3',
cover: '/img/default-cover.webp',
duration: '03:42',
tags: ['Local']
}本地音频放到:
public/audio/外部音乐平台数据也可以写在 src/data/music.ts,当前支持的类型包括:
netease
tencent
kugou
local
youtube
bilibili页面会统一显示为音乐列表,不突出平台名称。
数据页面怎么改
页面文件:
src/pages/data.astro数据页统计来自:
- 文章数量
- 分类数量
- 标签数量
- 全站字数
- 友链数量
- 相册数量
- 装备和音乐数量
- 最近更新
全站字数计算在:
src/utils/posts.ts首页侧栏和数据页共用同一套统计函数,避免不一致。
RSS、站点地图和 SEO
RSS:
src/pages/rss.xml.js搜索索引:
src/pages/search.json.js站点地图页面:
src/pages/sitemap.astroAstro sitemap 集成:
astro.config.mjs构建后会生成:
dist/rss.xml
dist/sitemap-index.xml
dist/sitemap-0.xml上线前必须确认:
astro.config.mjs -> site
src/data/site.ts -> siteConfig.url静态资源怎么放
所有 public/ 下的文件,都会被复制到网站根目录。
例如:
public/img/avatar.png网页里引用:
/img/avatar.png常用资源位置:
| 资源 | 位置 |
|---|---|
| 作者头像 | public/img/avatar.png |
| Logo | public/img/logo.png |
| 默认封面 | public/img/default-cover.webp |
| 微信赞赏码 | public/img/weixin.webp |
| 支付宝赞赏码 | public/img/zhifubao.jpg |
| 装备图片 | public/img/gear/ |
| 友链头像本地备份 | public/img/links_avatar/ |
| 本地音乐 | public/audio/ |
短代码怎么用
短代码转换插件:
src/utils/remarkDemiusShortcodes.mjs短代码运行时:
src/components/ShortcodeRuntime.astro短代码样式:
src/styles/global.css当前支持 Hugo 风格写法:
{{< shortcode attr="value" >}}
{{< /shortcode >}}也支持部分 ::: 指令写法。
文章里现在可以通过短代码插入视频、音乐、本地音频、网页 iframe、相册组、下载卡片、网盘卡片、GitHub 卡片、豆瓣卡片等内容。旧 Typecho / Handsome 常见的 collapse、tabs、tab、button、color、reply-visible、music、bilibili 写法已经做了兼容。
按钮
{{< button href="/posts/" text="查看文章" color="primary" >}}
{{< button href="https://example.com" text="外部链接" target="_blank" >}}
{{< button href="#" color="danger" outline="true" >}}危险按钮{{< /button >}}可用字段:
href / url
text / label / title
color / type
size: small / normal / large
outline: true
block: true
target
rel
icon链接卡片
{{< linkcard
url="https://github.com/uxiaohan/vhAstro-Theme"
title="vhAstro-Theme"
desc="参考文章能力、媒体展示和主题配置思路。"
site="GitHub"
image="/img/default-cover.webp"
>}}更多实用卡片:
{{< download url="/files/theme.zip" title="主题包下载" desc="ZIP / 12 MB" >}}
{{< netdisk url="https://pan.example.com/s/xxx" title="网盘资源" code="abcd" >}}
{{< github repo="owner/repo" desc="项目源码仓库" >}}
{{< douban type="book" id="1234567" title="书名" rating="8.8" cover="/img/default-cover.webp" >}}折叠块
{{< collapse title="点击展开" open="true" >}}
这里是折叠内容。
{{< /collapse >}}也兼容:
{{< details title="点击展开" >}}
{{< /details >}}提示块
{{< note title="提示" >}}
这里是提示内容。
{{< /note >}}
{{< warning title="注意" >}}
这里是警告内容。
{{< /warning >}}支持:
note
tip
info
success
warning
danger
alert
callout时间线
{{< timeline >}}
{{< timeline-item date="2026-06-09" title="主题更新" type="success" >}}
完成一个功能。
{{< /timeline-item >}}
{{< /timeline >}}选项卡
{{< tabs tabs="方案一,方案二" default="1" >}}
{{< tab title="方案一" index="1" >}}
第一段内容。
{{< /tab >}}
{{< tab title="方案二" index="2" >}}
第二段内容。
{{< /tab >}}
{{< /tabs >}}图片
普通 Markdown 图片也支持:
短代码图片:
{{< image src="/img/default-cover.webp" alt="说明" caption="图片标题" >}}
{{< picture src="/img/default-cover.webp" title="图片标题" >}}Live Photo:
{{< livephoto src="/img/photo.webp" video="/video/live.mp4" caption="动态照片" >}}图片组:
{{< gallery images="/img/a.webp,/img/b.webp,/img/c.webp" captions="第一张|第二张|第三张" title="相册标题" >}}网页嵌入
{{< iframe src="https://example.com" title="嵌入网页" height="520" >}}
{{< embed url="https://example.com" title="嵌入内容" ratio="4/3" >}}视频
B 站:
{{< bilibili bvid="BVxxxx" >}}
{{< video "https://www.bilibili.com/video/BVxxxx" >}}YouTube:
{{< youtube id="dQw4w9WgXcQ" >}}
{{< video "https://www.youtube.com/watch?v=dQw4w9WgXcQ" >}}本地视频:
{{< video src="/video/demo.mp4" poster="/img/default-cover.webp" controls="true" >}}音乐和音频
本地音频:
{{< audio src="/audio/demo.mp3" title="Demo Track" artist="Demius" cover="/img/default-cover.webp" >}}MetingJS 音乐:
{{< music server="netease" type="song" id="27583305" >}}
{{< music server="netease" type="playlist" id="4977885420" >}}
{{< netease id="27583305" >}}
{{< music auto="https://music.163.com/#/song?id=27583305" >}}文章中出现 meting-js 时,ShortcodeRuntime.astro 会自动加载 APlayer/Meting 资源。
徽章和彩色文字
{{< badge text="半神短代码" color="primary" >}}
{{< color color="#be3455" >}}彩色文字{{< /color >}}隐藏内容
{{< encrypt hint="提示文字" >}}
隐藏内容。
{{< /encrypt >}}注意:当前 Astro 静态模式下不会做真正的服务端加密,主题会把它渲染为折叠块,避免旧 Hugo 文章短代码直接露出来导致版面错乱。
代码块和文章样式
Markdown 代码块:
```js
console.log('hello');
```代码高亮主题在:
astro.config.mjs当前使用:
shikiConfig: {
themes: {
light: 'light-plus',
dark: 'dark-plus'
}
}代码块复制、过长折叠、行内代码样式在:
src/components/PostDetail.astro
src/styles/global.css修改样式应该去哪里
优先顺序:
- 全站共用样式改
src/styles/global.css - 某个页面独有样式改对应
src/pages/*.astro文件底部<style> - 某个组件独有样式改对应
src/components/*.astro文件底部<style>
常见样式位置:
| 想改什么 | 文件 |
|---|---|
| 网格背景 | src/styles/global.css 的 .site-shell::before |
| 色盘 | src/styles/global.css 的 :root[data-accent=...] |
| 玻璃卡片 | src/styles/global.css 的 .glass-panel |
| 文章正文 | src/styles/global.css 的 .prose |
| 文章卡片 | src/components/cards/PostCard.astro |
| 链接卡片 | src/components/cards/LinkCard.astro |
| 顶部导航 | src/components/layout/Header.astro |
| 底部 | src/components/layout/Footer.astro |
| 外观设置面板 | src/components/AppearanceRuntime.astro |
| 友链戴森球 | src/pages/links.astro |
| 动态页面 | src/pages/moments.astro |
| 装备页面 | src/pages/gear.astro、src/pages/gear/[id].astro |
| 音乐页面 | src/pages/music.astro |
页面路由清单
| 路由 | 文件 |
|---|---|
/ | src/pages/index.astro |
/posts/ | src/pages/posts/index.astro |
/posts/page/2/ | src/pages/posts/page/[page].astro |
/posts/文章slug.html | src/pages/posts/[slug].html.astro 和 scripts/postbuild-legacy-posts.mjs |
/posts/旧文章名/ | src/pages/posts/[...id].astro,跳转到新的 .html 地址 |
/archive/ | src/pages/archive/index.astro |
/categories/ | src/pages/categories/index.astro |
/categories/分类名/ | src/pages/categories/[category]/index.astro |
/tags/ | src/pages/tags/index.astro |
/tags/标签名/ | src/pages/tags/[tag]/index.astro |
/life/ | src/pages/life.astro |
/moments/ | src/pages/moments.astro |
/links/ | src/pages/links.astro |
/gallery/ | src/pages/gallery.astro |
/gear/ | src/pages/gear.astro |
/gear/装备id/ | src/pages/gear/[id].astro |
/music/ | src/pages/music.astro |
/data/ | src/pages/data.astro |
/about/ | src/pages/about.astro |
/search/ | src/pages/search.astro |
/rss.xml | src/pages/rss.xml.js |
/search.json | src/pages/search.json.js |
/sitemap/ | src/pages/sitemap.astro |
/404.html | src/pages/404.astro |
旧站迁移注意事项
保持旧 URL
旧 Hugo 文章如果原来是:
/posts/fwv2okpo.html迁移后的 Markdown 要加:
legacySlug: fwv2okpo构建时 scripts/postbuild-legacy-posts.mjs 会把 Astro 默认生成的目录式 HTML 修正为真正的:
dist/posts/fwv2okpo.html并同步修正 sitemap 里的链接。
分类和标签
分类和标签不需要单独维护。它们来自每篇文章 Front Matter:
categories:
- 旧站文章
tags:
- Hugo
- Demius分类页和标签页会自动统计数量。
短代码
旧 Demius Hugo 文章里的常见短代码已经由 remarkDemiusShortcodes.mjs 适配。遇到某个短代码显示为原始文本时:
- 先确认写法是否是
{{< name >}}或{{< /name >}} - 去
src/utils/remarkDemiusShortcodes.mjs检查是否支持这个name - 如果不支持,在
containerNames或leafNames中加入,并补对应渲染函数 - 样式加到
src/styles/global.css
部署
Astro 构建后的静态文件在 dist/。部署时只需要把 dist/ 里的内容同步到服务器静态站点目录。
当前服务器发布流程
当前项目已经配置好 rsync 发布脚本,脚本位置是 deploy-rsync.ps1。
默认发布目标:
本地目录:dist/
远程目录:/var/www/example-site/dist/
服务器:deploy-user@example.com:22
SSH 私钥:~/.ssh/deploy_key日常发布直接运行:
npm run deploy:rsync:build这条命令会先执行 npm run build,再用 rsync 把 dist/ 同步到远程服务器。
如果已经手动构建过,也可以分两步执行:
npm run build
npm run deploy:rsync发布完成后访问:
https://blog.demius.space/首次准备
rsync 要求本机和远程服务器都安装 rsync。
当前这台 Windows 机器已经在项目内放置了 portable cwRsync:
.tools/cwrsync/bin/rsync.exe.tools/ 已加入 .gitignore,只作为本机工具目录,不需要提交。
如果换一台电脑,需要重新准备本机 rsync。可选方式:
1. 使用项目内 portable cwRsync
2. 安装 MSYS2 并安装 rsync
3. 安装 Cygwin 并安装 rsync
4. 安装 cwRsync脚本会自动查找这些常见位置:
.tools/cwrsync/bin/rsync.exe
C:/msys64/usr/bin/rsync.exe
C:/cygwin64/bin/rsync.exe
C:/Program Files/cwRsync/bin/rsync.exe
C:/Program Files (x86)/cwRsync/bin/rsync.exe如果 rsync 在其他位置,可以手动指定:
.\deploy-rsync.ps1 -RsyncPath "C:\path\to\rsync.exe"远程服务器如果没有 rsync,先运行:
npm run deploy:rsync:setup-remote当前服务器已经执行过这一步。
这一步通过 SSH 给远程服务器安装的是 rsync。脚本会先检查远程是否已经有 rsync:
ssh -i ~/.ssh/deploy_key -p 22 -o BatchMode=yes -o StrictHostKeyChecking=accept-new -o ConnectTimeout=20 deploy-user@example.com "command -v rsync >/dev/null 2>&1"如果没有,deploy-rsync.ps1 -InstallRemoteRsync 会通过同一条 SSH 连接在远程服务器执行下面的安装逻辑:
if command -v apt-get >/dev/null 2>&1; then
DEBIAN_FRONTEND=noninteractive apt-get install -y rsync || \
(apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y rsync)
elif command -v dnf >/dev/null 2>&1; then
dnf install -y rsync
elif command -v yum >/dev/null 2>&1; then
yum install -y rsync
elif command -v apk >/dev/null 2>&1; then
apk add --no-cache rsync
else
echo 'No supported package manager found for installing rsync.' >&2
exit 127
fi迁移到新的 Debian / Ubuntu 服务器时,最常用的手动 SSH 命令是:
ssh -i ~/.ssh/deploy_key -p 22 -o StrictHostKeyChecking=accept-new deploy-user@example.com "apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y rsync"同步前脚本还会确保远程站点目录存在:
ssh -i ~/.ssh/deploy_key -p 22 -o StrictHostKeyChecking=accept-new deploy-user@example.com "mkdir -p '/var/www/example-site/dist'"发布前预演
预演不会修改远端文件,只会显示 rsync 准备同步的结果:
.\deploy-rsync.ps1 -DryRun常用参数:
.\deploy-rsync.ps1 -Build # 上传前先运行 npm run build
.\deploy-rsync.ps1 -DryRun # 预演,不修改远端文件
.\deploy-rsync.ps1 -NoDelete # 不删除远端多余文件
.\deploy-rsync.ps1 -Checksum # 按文件内容校验,速度更慢但更严格rsync 发布说明
脚本默认带 --delete,远程 dist/ 中本地已经不存在的旧文件会被删除,避免旧构建产物残留。如果只是临时测试,不想删除远端多余文件,可以使用:
.\deploy-rsync.ps1 -NoDeletersync 是增量同步。没有变化时只传输文件列表和校验信息,不会重复上传所有文件;有变化时只上传变化的文件。
其他部署方式
如果部署到静态托管平台,运行构建后上传 dist/ 即可:
npm run build适合的平台:
- Cloudflare Pages
- Vercel
- Netlify
- GitHub Pages
- 1Panel / Nginx 静态站点
- 任意能托管静态文件的服务器
部署前检查:
astro.config.mjs -> site
src/data/site.ts -> url
src/data/site.ts -> title / description / author
public/favicon.svg
public/img/avatar.png
public/img/logo.png
PUBLIC_ARTALK_SERVER
PUBLIC_ARTALK_SITE如果域名与旧站一致,并且旧文章都配置了 legacySlug,SEO 链接不会因为迁移到 Astro 而改变。
旧部署脚本
deploy.py 是旧的 Python/Paramiko 发布脚本,现在保留为备用方案。日常发布优先使用:
npm run deploy:rsync:build常见问题
修改了内容但页面没变化
开发模式下先看终端是否报错。如果是构建产物没变化,重新运行:
npm run build不要改 dist/,要改 src/ 或 public/。
文章不显示
检查:
- 文件是否在
src/content/posts/ - 后缀是否是
.md或.mdx - Front Matter 是否有
title、description、pubDate draft是否为true- YAML 缩进是否正确
图片不显示
如果图片在 public/img/demo.webp,文章里应该写:
不要写成:
public/img/demo.webp外观设置刷新后仍保留旧状态
外观设置保存在浏览器 localStorage。如果你改了默认配置但浏览器仍显示旧设置,可以清除浏览器本地存储里的:
demius-appearance
demius-theme评论不显示
检查:
PUBLIC_ARTALK_SERVER
PUBLIC_ARTALK_SITE并确认 Artalk 服务允许当前域名访问。
想改全站字数统计口径
修改:
src/utils/posts.ts重点函数:
countPostWords()
totalPostWords()
formatWordCount()想增加一个新页面
例如新增 /books/:
- 新建
src/pages/books.astro - 如需数据,新建
src/data/books.ts - 如需导航入口,在
src/data/site.ts的navItems里加入 - 如需样式,可写在
books.astro底部<style>或src/styles/global.css
维护建议
- 文章只放
src/content/posts/ - 数据只放
src/data/ - 图片、音频、静态文件只放
public/ - 不要修改
dist/ - 不要随意改
src/content.config.ts,除非你要新增文章 Front Matter 字段 - 上线前一定确认
astro.config.mjs和src/data/site.ts的域名一致
