修改网站的favicon,并将favicon迁移到site.ts中
|
Before Width: | Height: | Size: 2.7 KiB |
|
After Width: | Height: | Size: 9.3 KiB |
|
After Width: | Height: | Size: 42 KiB |
|
After Width: | Height: | Size: 8.3 KiB |
|
After Width: | Height: | Size: 426 B |
|
After Width: | Height: | Size: 919 B |
|
After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 426 B |
|
Before Width: | Height: | Size: 554 B |
|
Before Width: | Height: | Size: 41 KiB |
@@ -4,7 +4,7 @@
|
|||||||
* pnpm new-post "文章标题"
|
* pnpm new-post "文章标题"
|
||||||
* pnpm new-post "树莓派装 Docker" --category 教程 --tags Docker,树莓派
|
* pnpm new-post "树莓派装 Docker" --category 教程 --tags Docker,树莓派
|
||||||
* pnpm new-post "读《XX》有感" --category 思考 --description "摘要" --pinned
|
* pnpm new-post "读《XX》有感" --category 思考 --description "摘要" --pinned
|
||||||
* pnpm new-post "标题" --file my-custom-slug --category 建站
|
* pnpm new-post "标题" --file 文件名 --slug my-custom-slug --category 建站
|
||||||
*
|
*
|
||||||
* 不加 --category 时文件放在 src/content/posts/ 根目录;
|
* 不加 --category 时文件放在 src/content/posts/ 根目录;
|
||||||
* 加了则同时写进 frontmatter 的 category 并放进同名子目录,和现有文章结构一致。
|
* 加了则同时写进 frontmatter 的 category 并放进同名子目录,和现有文章结构一致。
|
||||||
@@ -38,6 +38,7 @@ if (args.length === 0 || args[0] === "--help" || args[0] === "-h") {
|
|||||||
--category <分类> 分类名,同时决定存放的子目录
|
--category <分类> 分类名,同时决定存放的子目录
|
||||||
--file <文件名> 自定义文件名(默认用标题)
|
--file <文件名> 自定义文件名(默认用标题)
|
||||||
--tags <标签,标签> 标签,逗号分隔
|
--tags <标签,标签> 标签,逗号分隔
|
||||||
|
--slug <英文主题> 通常使用文章标题的英文缩写,Astro博客自带的属性
|
||||||
--description <摘要> 摘要,用于 SEO 和列表卡片
|
--description <摘要> 摘要,用于 SEO 和列表卡片
|
||||||
--image <路径> 封面图,public 下的绝对路径
|
--image <路径> 封面图,public 下的绝对路径
|
||||||
--pinned 置顶
|
--pinned 置顶
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ if (args.length === 0 || args[0] === "--help" || args[0] === "-h") {
|
|||||||
--title <标题> 可选标题
|
--title <标题> 可选标题
|
||||||
--location <地点> 地点,显示在日期旁
|
--location <地点> 地点,显示在日期旁
|
||||||
--weather <天气> 天气,与地点一起显示
|
--weather <天气> 天气,与地点一起显示
|
||||||
--images <路径,路径> 配图,public 下的绝对路径,逗号分隔
|
--images <路径,路径> 配图,public 下的绝对路径,逗号分隔,或者使用图床url链接
|
||||||
--tags <标签,标签> 标签,逗号分隔
|
--tags <标签,标签> 标签,逗号分隔
|
||||||
--pinned 置顶
|
--pinned 置顶
|
||||||
|
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ const statCells = [
|
|||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
class="flex items-center gap-2 text-muted-foreground text-xs hover:text-foreground transition-colors duration-200 group md:justify-end md:pr-4"
|
class="flex items-center gap-2 text-muted-foreground text-xs hover:text-foreground transition-colors duration-200 group md:justify-end md:pr-4"
|
||||||
>
|
>
|
||||||
<Github class="w-3.5 h-3.5" />
|
<Github className="w-3.5 h-3.5" />
|
||||||
<span>博客主题:朱墨留白 | VermilionVoid</span>
|
<span>博客主题:朱墨留白 | VermilionVoid</span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 481 KiB |
@@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
title: "工作效率的提升"
|
||||||
|
published: 2026-09-20
|
||||||
|
description: "我们这个时代为什么越来越繁忙,人工智能带来的增效仍然是一把双刃剑"
|
||||||
|
slug: Improving-work-efficiency
|
||||||
|
tags: [工作,人的异化]
|
||||||
|
category: "思考"
|
||||||
|
---
|
||||||
|
|
||||||
|
在这里写正文。
|
||||||
@@ -48,6 +48,48 @@ export const siteTitleSuffix = site.name
|
|||||||
/** 站点头像/站点图标的绝对地址,供友链页等对外展示用 */
|
/** 站点头像/站点图标的绝对地址,供友链页等对外展示用 */
|
||||||
export const siteAvatarUrl = `${site.url}/avatar.webp`
|
export const siteAvatarUrl = `${site.url}/avatar.webp`
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 站点图标(favicon)配置。
|
||||||
|
*
|
||||||
|
* 换图标有两种做法:
|
||||||
|
* 1. 图省事:直接覆盖 public/favicon/ 下的同名文件,本文件一个字都不用改;
|
||||||
|
* 2. 换了文件名或目录:只改下面这些值,页面里的 <link> 和 Web App Manifest 会一起跟上。
|
||||||
|
*
|
||||||
|
* dir 对应 public/ 下的目录,在线上就是站根下的绝对路径。
|
||||||
|
*/
|
||||||
|
export const favicon = {
|
||||||
|
/** 图标目录。改了要同步把 src/pages/favicon/ 这个路由目录挪到同名位置 */
|
||||||
|
dir: "/favicon",
|
||||||
|
|
||||||
|
/** 标签页图标:老的 .ico 兜底,内含 16/32/48 三档 */
|
||||||
|
ico: "favicon.ico",
|
||||||
|
/** 标签页主图标 32x32 —— 浏览器最常取的就是它 */
|
||||||
|
png32: "favicon-32x32.png",
|
||||||
|
/** 标签页小图标 16x16 */
|
||||||
|
png16: "favicon-16x16.png",
|
||||||
|
/** iOS「添加到主屏幕」图标,180x180 */
|
||||||
|
appleTouchIcon: "apple-touch-icon.png",
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Web App Manifest:只在「添加到主屏幕 / 装成 App」时被浏览器取用。
|
||||||
|
* 文件不在 public/ 里,而是由 src/pages/favicon/[manifest].ts 按本配置生成,
|
||||||
|
* 所以站名、图标路径不会和这里对不上。
|
||||||
|
*/
|
||||||
|
manifest: {
|
||||||
|
/** 生成的文件名。改这里,<link rel="manifest"> 和产物文件名一起变 */
|
||||||
|
file: "site.webmanifest",
|
||||||
|
/** Android「添加到主屏幕」用的两档图标 */
|
||||||
|
android192: "android-chrome-192x192.png",
|
||||||
|
android512: "android-chrome-512x512.png",
|
||||||
|
/** 移动端状态栏与启动屏配色 */
|
||||||
|
themeColor: "#ffffff",
|
||||||
|
backgroundColor: "#ffffff",
|
||||||
|
},
|
||||||
|
} as const
|
||||||
|
|
||||||
|
/** 把 favicon 里的文件名拼成站内绝对路径,例如 /favicon/favicon.ico */
|
||||||
|
export const faviconUrl = (file: string) => `${favicon.dir}/${file}`
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 统计分析。每一项留空即不加载对应的脚本。
|
* 统计分析。每一项留空即不加载对应的脚本。
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
import "katex/dist/katex.min.css"
|
import "katex/dist/katex.min.css"
|
||||||
import "@/styles/global.css"
|
import "@/styles/global.css"
|
||||||
import { ClientRouter } from "astro:transitions"
|
import { ClientRouter } from "astro:transitions"
|
||||||
import { analytics, homeTitle, site } from "@/data/site"
|
import { analytics, favicon, faviconUrl, homeTitle, site } from "@/data/site"
|
||||||
import ImageLightbox from "@/components/ImageLightbox.astro"
|
import ImageLightbox from "@/components/ImageLightbox.astro"
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
@@ -91,10 +91,11 @@ const resolvedTwitterDescription = twitterDescription || description
|
|||||||
? "https://fonts.googleapis.com/css2?family=Playfair+Display:ital,wght@0,400..700;1,400..700&family=Noto+Serif+SC:wght@400..900&display=swap"
|
? "https://fonts.googleapis.com/css2?family=Playfair+Display:ital,wght@0,400..700;1,400..700&family=Noto+Serif+SC:wght@400..900&display=swap"
|
||||||
: "https://fonts.googleapis.com/css2?family=Inter:wght@400..700&family=Noto+Sans+SC:wght@400..700&family=Playfair+Display:ital,wght@0,400..700;1,400..700&family=Noto+Serif+SC:wght@400..900&display=swap"}
|
: "https://fonts.googleapis.com/css2?family=Inter:wght@400..700&family=Noto+Sans+SC:wght@400..700&family=Playfair+Display:ital,wght@0,400..700;1,400..700&family=Noto+Serif+SC:wght@400..900&display=swap"}
|
||||||
/>
|
/>
|
||||||
<link rel="icon" href="/icon-light-32x32.png" media="(prefers-color-scheme: light)" />
|
<link rel="icon" href={faviconUrl(favicon.ico)} sizes="16x16 32x32 48x48" />
|
||||||
<link rel="icon" href="/icon-dark-32x32.png" media="(prefers-color-scheme: dark)" />
|
<link rel="icon" href={faviconUrl(favicon.png32)} type="image/png" sizes="32x32" />
|
||||||
<link rel="icon" href="/icon.svg" type="image/svg+xml" />
|
<link rel="icon" href={faviconUrl(favicon.png16)} type="image/png" sizes="16x16" />
|
||||||
<link rel="apple-touch-icon" href="/apple-icon.png" />
|
<link rel="apple-touch-icon" href={faviconUrl(favicon.appleTouchIcon)} />
|
||||||
|
<link rel="manifest" href={faviconUrl(favicon.manifest.file)} />
|
||||||
<script is:inline define:vars={{ analytics }}>
|
<script is:inline define:vars={{ analytics }}>
|
||||||
;(() => {
|
;(() => {
|
||||||
// ClientRouter 切页时 head 里的内联脚本可能再次执行,用全局标记兜底
|
// ClientRouter 切页时 head 里的内联脚本可能再次执行,用全局标记兜底
|
||||||
|
|||||||
@@ -0,0 +1,58 @@
|
|||||||
|
import fs from "node:fs"
|
||||||
|
import path from "node:path"
|
||||||
|
import type { APIRoute } from "astro"
|
||||||
|
import { favicon, faviconUrl, site } from "@/data/site"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Web App Manifest 由路由生成而非放在 public/,这样站名、图标路径都跟随
|
||||||
|
* src/data/site.ts —— 换 favicon 只需要改那一个文件,不会出现"manifest 没跟上"。
|
||||||
|
* 同样的思路见 src/pages/robots.txt.ts。
|
||||||
|
*
|
||||||
|
* 产物文件名取自 favicon.manifest.file,所以改名也在 site.ts 里做。
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** 本路由所在目录,必须和 favicon.dir 一致 —— 改了一个就得改名另一个 */
|
||||||
|
const ROUTE_DIR = "/favicon"
|
||||||
|
|
||||||
|
export function getStaticPaths() {
|
||||||
|
if (favicon.dir !== ROUTE_DIR) {
|
||||||
|
throw new Error(
|
||||||
|
`favicon.dir 是 "${favicon.dir}",但 manifest 路由在 src/pages${ROUTE_DIR}/ 下。` +
|
||||||
|
`请把该目录一并改名为 src/pages${favicon.dir}/,否则 manifest 会被生成到错误的路径上。`,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// public/ 里的同名文件会在构建时胜出(Astro 只打一行 WARN 就跳过本路由),
|
||||||
|
// manifest 会静默停在旧内容。宁可构建失败,也不要默默把旧 manifest 推上线。
|
||||||
|
const shadow = path.join(process.cwd(), "public", favicon.dir, favicon.manifest.file)
|
||||||
|
if (fs.existsSync(shadow)) {
|
||||||
|
throw new Error(
|
||||||
|
`public${favicon.dir}/${favicon.manifest.file} 与本路由重名,构建时 public 里的那个会胜出,` +
|
||||||
|
`manifest 将不再跟随 site.ts。请删掉它 —— manifest 是自动生成的,不需要手写。`,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return [{ params: { manifest: favicon.manifest.file } }]
|
||||||
|
}
|
||||||
|
|
||||||
|
export const GET: APIRoute = () => {
|
||||||
|
const { manifest } = favicon
|
||||||
|
|
||||||
|
const body = {
|
||||||
|
name: site.name,
|
||||||
|
description: site.description,
|
||||||
|
lang: site.lang,
|
||||||
|
start_url: "/",
|
||||||
|
display: "standalone",
|
||||||
|
background_color: manifest.backgroundColor,
|
||||||
|
theme_color: manifest.themeColor,
|
||||||
|
icons: [
|
||||||
|
{ src: faviconUrl(manifest.android192), sizes: "192x192", type: "image/png" },
|
||||||
|
{ src: faviconUrl(manifest.android512), sizes: "512x512", type: "image/png" },
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Response(JSON.stringify(body, null, 2), {
|
||||||
|
headers: { "Content-Type": "application/manifest+json; charset=utf-8" },
|
||||||
|
})
|
||||||
|
}
|
||||||