From bc8810d24b201d069aa76ac4a3d363271a00e761 Mon Sep 17 00:00:00 2001 From: liuxuezhuo Date: Wed, 30 Sep 2026 00:42:48 +0800 Subject: [PATCH 1/2] docs(site): add a favicon so link cards show a thumbnail Chat apps such as DingTalk render the site icon as the link card thumbnail; the site emitted no favicon at all, so cards showed an empty slot while sibling sites on the same domain showed theirs. Co-authored-by: QoderAI (Qwen 3.8 Max) --- docs/docusaurus.config.js | 12 ++++++++++++ docs/scripts/sync-assets.mjs | 1 + 2 files changed, 13 insertions(+) diff --git a/docs/docusaurus.config.js b/docs/docusaurus.config.js index 882859e..3a1fe06 100644 --- a/docs/docusaurus.config.js +++ b/docs/docusaurus.config.js @@ -14,6 +14,18 @@ const config = { projectName: "Qoderian", trailingSlash: false, + headTags: [ + { + tagName: "link", + attributes: { + rel: "icon", + type: "image/svg+xml", + // headTags hrefs are emitted verbatim, so the baseUrl prefix is manual. + href: "/Qoderian/img/favicon.svg", + }, + }, + ], + onBrokenLinks: "throw", i18n: { diff --git a/docs/scripts/sync-assets.mjs b/docs/scripts/sync-assets.mjs index b556fa8..6ac420b 100644 --- a/docs/scripts/sync-assets.mjs +++ b/docs/scripts/sync-assets.mjs @@ -11,6 +11,7 @@ const repoRoot = join(scriptsDir, "..", ".."); const targets = [ ["assets/preview.png", "static/img/preview.png"], ["assets/social-card.jpg", "static/img/social-card.jpg"], + ["src/assets/qoder-icon.svg", "static/img/favicon.svg"], ]; for (const [from, to] of targets) { From e8cd609447db3b853f38d06788256822f83e7979 Mon Sep 17 00:00:00 2001 From: liuxuezhuo Date: Wed, 30 Sep 2026 08:00:15 +0800 Subject: [PATCH 2/2] docs(site): make the favicon follow the browser color scheme A favicon has no surrounding text color for currentColor to inherit, so the synced icon now carries a prefers-color-scheme block: black mark on light browser chrome, white on dark, mirroring how the plugin icon picks up the vault theme. Co-authored-by: QoderAI (Qwen 3.8 Max) --- docs/scripts/sync-assets.mjs | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/docs/scripts/sync-assets.mjs b/docs/scripts/sync-assets.mjs index 6ac420b..2e2f912 100644 --- a/docs/scripts/sync-assets.mjs +++ b/docs/scripts/sync-assets.mjs @@ -1,6 +1,6 @@ // Copies shared repository assets into the website's static dir so the // published site can reference them without committing duplicates. -import { copyFileSync, mkdirSync } from "node:fs"; +import { copyFileSync, mkdirSync, readFileSync, writeFileSync } from "node:fs"; import { dirname, join } from "node:path"; import { fileURLToPath } from "node:url"; @@ -11,7 +11,6 @@ const repoRoot = join(scriptsDir, "..", ".."); const targets = [ ["assets/preview.png", "static/img/preview.png"], ["assets/social-card.jpg", "static/img/social-card.jpg"], - ["src/assets/qoder-icon.svg", "static/img/favicon.svg"], ]; for (const [from, to] of targets) { @@ -20,3 +19,20 @@ for (const [from, to] of targets) { copyFileSync(join(repoRoot, from), dest); console.log(`synced ${from} -> docs/${to}`); } + +// The favicon reuses the plugin icon, but a favicon has no surrounding text +// color for currentColor to inherit, so the theme switch is made explicit: +// black mark on light browser chrome, white on dark. +const favicon = readFileSync(join(repoRoot, "src/assets/qoder-icon.svg"), "utf8") + .replace('fill="currentColor"', 'class="qf"') + .replace('stroke="currentColor"', 'class="qs"') + .replace( + /]*>/, + (tag) => + `${tag}", + ); +const faviconDest = join(siteDir, "static/img/favicon.svg"); +mkdirSync(dirname(faviconDest), { recursive: true }); +writeFileSync(faviconDest, favicon); +console.log("built src/assets/qoder-icon.svg -> docs/static/img/favicon.svg");