From 9488c1ab6578e848f52c0eae20b3265d7da922cc Mon Sep 17 00:00:00 2001 From: sudoHG Date: Tue, 13 Oct 2026 19:59:58 +0800 Subject: [PATCH] Help search engines and link previews find the website (#160) Add robots.txt with a sitemap of both languages, an x-default hreflang, Open Graph site name and locales, X image alt text, SoftwareApplication structured data and a root favicon.ico. Shorten the English description to fit search results. Mark the pages.dev mirror noindex and cache hashed assets for a year through Cloudflare Pages headers; the not-found page now links its stylesheet with a hash too. --- site-src/README.md | 4 ++++ site-src/how/stamp.mjs | 2 +- site/404.html | 2 +- site/_headers | 25 +++++++++++++++++++++++++ site/favicon.ico | Bin 0 -> 6109 bytes site/index.html | 39 ++++++++++++++++++++++++++++++++++++++- site/robots.txt | 4 ++++ site/sitemap.xml | 17 +++++++++++++++++ site/zh/index.html | 37 +++++++++++++++++++++++++++++++++++++ 9 files changed, 127 insertions(+), 3 deletions(-) create mode 100644 site/_headers create mode 100644 site/favicon.ico create mode 100644 site/robots.txt create mode 100644 site/sitemap.xml diff --git a/site-src/README.md b/site-src/README.md index 4d50284..f431b96 100644 --- a/site-src/README.md +++ b/site-src/README.md @@ -14,3 +14,7 @@ npx wrangler pages deploy site --project-name askkey --branch main \ Wrangler reads a Cloudflare API token with Pages write access from `CLOUDFLARE_API_TOKEN` and the account from `CLOUDFLARE_ACCOUNT_ID`. Never put the token in a file, an argument or a log. Before deploying, run `npm run stamp` in `how/` if any CSS or JS changed, so pages never pair with a cached old file, and check both pages in a browser. + +## Search and sharing + +`site/robots.txt` points crawlers to `site/sitemap.xml`; update its `lastmod` dates when the pages change. `site/_headers` sets Cloudflare Pages response headers: the `askkey.pages.dev` mirror is marked `noindex`, hashed stylesheets, scripts and fonts are cached for a year, and pictures for a week. Each page carries its canonical URL, `hreflang` alternates, Open Graph and X card tags with its own share image (`site/assets/og-*.jpg`), and `SoftwareApplication` structured data. diff --git a/site-src/how/stamp.mjs b/site-src/how/stamp.mjs index f6d444a..8dcbef2 100644 --- a/site-src/how/stamp.mjs +++ b/site-src/how/stamp.mjs @@ -6,7 +6,7 @@ import { readFileSync, writeFileSync } from "node:fs"; const site = new URL("../../site/", import.meta.url); const files = ["style.css", "motion.js", "how/how.css", "how/how.js"]; const hash = Object.fromEntries(files.map((f) => [f, createHash("sha256").update(readFileSync(new URL(f, site))).digest("hex").slice(0, 10)])); -for (const page of ["index.html", "zh/index.html"]) { +for (const page of ["index.html", "zh/index.html", "404.html"]) { const url = new URL(page, site); let html = readFileSync(url, "utf8"); for (const f of files) { diff --git a/site/404.html b/site/404.html index e60184a..81db57e 100644 --- a/site/404.html +++ b/site/404.html @@ -6,7 +6,7 @@ 页面不存在 · Page not found — Ask Key - +