Skip to content

Commit 0a44ccb

Browse files
committed
Add Google Search Console verification
1 parent db405db commit 0a44ccb

6 files changed

Lines changed: 21 additions & 2 deletions

File tree

‎.agents/skills/pre-production-checklist/SKILL.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ Run this gate whenever public routes, metadata, canonical-domain behavior, or th
4242
1. Treat `src/data/siteIdentity.json` and `src/data/sitePages.json` as the shared registries for public identity, canonical origin, indexable routes, and route-specific titles and descriptions. Compare them with the public routes in `src/App.tsx` and the main-page links in `public/llms.txt`.
4343
2. Run `npm test` and `npm run build`. Confirm every registered route produces `dist/<route>/index.html` with rendered page content rather than an empty React root.
4444
3. Serve `dist` with a plain static server and request every canonical route directly. Each registered route must return `200`; unknown and `/concepts` routes must remain non-indexable.
45-
4. Inspect each generated page's initial HTML. Confirm it has one unique title, description, self-referencing canonical URL, Open Graph URL, `index, follow` directive, and valid Organization/WebPage JSON-LD.
45+
4. Inspect each generated page's initial HTML. Confirm it has one unique title, description, self-referencing canonical URL, Open Graph URL, `index, follow` directive, Google Search Console verification tag, and valid Organization/WebPage JSON-LD.
4646
5. Confirm `dist/sitemap.xml` lists every registered production canonical exactly once and no staging, concept-review, or unknown URL. Confirm `dist/robots.txt` allows crawling and references the production sitemap.
4747
6. Run a staging build with `VITE_NOINDEX=true` and the staging `VITE_SITE_ORIGIN`. Confirm every generated page says `noindex, nofollow`, `dist/robots.txt` allows crawlers to fetch and observe that directive without advertising a sitemap, and no sitemap is published. On GitHub project Pages, remember that a robots file below the host root is not a host-wide crawl policy.
4848
7. After deployment, request the production routes, `/robots.txt`, and `/sitemap.xml` directly. In Google Search Console, submit the sitemap and use URL Inspection on the homepage and at least one inner page.

‎README.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ The validator reports unmatched responses, invalid public links, missing assets,
4646
## Search and static routes
4747

4848
- `src/data/siteIdentity.json` and `src/data/sitePages.json` are the shared registries for the public identity, indexable routes, page titles, and descriptions.
49+
- `src/data/siteIdentity.json` also stores the public Google Search Console verification token that the build emits as a metadata tag.
4950
- `npm run build` creates rendered HTML at each route directory, then generates and validates `dist/sitemap.xml` and `dist/robots.txt`.
5051
- `src/components/RouteMetadata.tsx` keeps metadata synchronized during client-side navigation.
5152
- Production builds are indexable by default. Staging sets `VITE_NOINDEX=true` and a staging `VITE_SITE_ORIGIN`, which marks every page `noindex, nofollow` and suppresses the sitemap. Its robots file allows fetching so crawlers can observe the page-level directive.

‎scripts/lib/site-seo.js‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,12 +132,16 @@ export const buildPageHtml = ({
132132
}
133133

134134
html = html.replace(/\s*<meta\s+name="robots"[^>]*>/i, "");
135+
html = html.replace(/\s*<meta\s+name="google-site-verification"[^>]*>/i, "");
135136
const robotsMeta = noindex
136137
? '<meta name="robots" content="noindex, nofollow" />'
137138
: '<meta name="robots" content="index, follow" />';
139+
const verificationMeta = siteIdentity.googleSiteVerification
140+
? `<meta name="google-site-verification" content="${escapeHtml(siteIdentity.googleSiteVerification)}" />`
141+
: "";
138142
html = html.replace(
139143
"</head>",
140-
` ${robotsMeta}\n <script id="site-structured-data" type="application/ld+json">${jsonForHtml(structuredData)}</script>\n </head>`,
144+
` ${robotsMeta}\n ${verificationMeta}\n <script id="site-structured-data" type="application/ld+json">${jsonForHtml(structuredData)}</script>\n </head>`,
141145
);
142146
html = replaceRequired(
143147
html,

‎scripts/lib/site-seo.test.js‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ const pages = [
1111
const siteIdentity = {
1212
name: "Example Organization",
1313
alternateName: "Example Org",
14+
googleSiteVerification: "verification-token",
1415
logoPath: "/logo.svg",
1516
sameAs: ["https://social.example.com/example"],
1617
};
@@ -70,6 +71,10 @@ test("embeds rendered content and unique route metadata in the initial HTML", ()
7071
assert.match(html, /<main><h1>About us<\/h1><\/main>/);
7172
assert.match(html, /"@type":"WebPage"/);
7273
assert.match(html, /"@type":"EducationalOrganization"/);
74+
assert.match(
75+
html,
76+
/<meta name="google-site-verification" content="verification-token" \/>/,
77+
);
7378
assert.doesNotMatch(html, /name="robots" content="noindex/);
7479
});
7580

‎scripts/validate-seo-build.mjs‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,14 @@ for (const page of pages) {
3838
);
3939
assert.match(html, /"@type":"EducationalOrganization"/);
4040
assert.match(html, /"@type":"WebPage"/);
41+
assert.equal(
42+
occurrences(
43+
html,
44+
`<meta name="google-site-verification" content="${siteIdentity.googleSiteVerification}" />`,
45+
),
46+
1,
47+
`${page.path} must contain the Google Search Console verification token exactly once`,
48+
);
4149
assert.match(
4250
html,
4351
noindex

‎src/data/siteIdentity.json‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"name": "Computational Biology at Berkeley",
33
"alternateName": "CompBio at Berkeley",
44
"productionOrigin": "https://compbioatberkeley.github.io",
5+
"googleSiteVerification": "02GuXcaPxq10BM-UsozE-BtdcKgEJdfbfNYC1CUEYB0",
56
"logoPath": "/comp-bio-logo-berkeley.svg",
67
"sameAs": [
78
"https://github.com/CompbioAtBerkeley",

0 commit comments

Comments
 (0)