From 1b6b83c5b7d5995dc609926f80a82889cccd78aa Mon Sep 17 00:00:00 2001
From: Zixuan Chen
Date: Fri, 2 Oct 2026 15:48:18 +0800
Subject: [PATCH] fix(docs): declare English document language
---
pages/_document.tsx | 13 +++++++++++++
scripts/seo-build.test.mjs | 1 +
scripts/seo.test.mjs | 4 ++++
3 files changed, 18 insertions(+)
create mode 100644 pages/_document.tsx
diff --git a/pages/_document.tsx b/pages/_document.tsx
new file mode 100644
index 0000000..b2fff8b
--- /dev/null
+++ b/pages/_document.tsx
@@ -0,0 +1,13 @@
+import { Html, Head, Main, NextScript } from "next/document";
+
+export default function Document() {
+ return (
+
+
+
+
+
+
+
+ );
+}
diff --git a/scripts/seo-build.test.mjs b/scripts/seo-build.test.mjs
index 67f95c7..99f4bc5 100644
--- a/scripts/seo-build.test.mjs
+++ b/scripts/seo-build.test.mjs
@@ -18,6 +18,7 @@ function links(html) {
for (const route of routes) {
test(`built metadata: ${route}`, () => {
const html = read(`.next/server/pages${route === "/" ? "/index" : route}.html`);
+ assert.match(html, /]*\slang="en"(?:\s|>)/, "English pages must declare their document language");
const tags = links(html);
const { canonicalUrl, chineseUrl } = getPageUrls(route);
assert.deepEqual(tags.filter((link) => link.rel === "canonical").map((link) => link.href), [canonicalUrl]);
diff --git a/scripts/seo.test.mjs b/scripts/seo.test.mjs
index d9b52b0..35e5a59 100644
--- a/scripts/seo.test.mjs
+++ b/scripts/seo.test.mjs
@@ -8,6 +8,10 @@ import { getPageUrls, hasChineseTranslation, normalizePath } from "../lib/seo.mj
const root = new URL("../", import.meta.url);
const read = (path) => readFileSync(new URL(path, root), "utf8");
+test("English document declares its language before client rendering", () => {
+ assert.match(read("pages/_document.tsx"), //);
+});
+
test("canonical paths exclude queries, fragments, and trailing slashes", () => {
for (const path of [undefined, "", "/", "/?utm_source=test#top"]) {
assert.equal(normalizePath(path), "/");