Add per-page SEO tags, share image, sitemap and robots.txt #4

Merged
rob merged 2 commits from cc-8-seo into site-hardening 2026-10-07 13:28:21 +00:00
Collaborator

Each page now has its own title, description, canonical URL and Open Graph/Twitter tags with a 1200x630 share image (src/og.png). The build also writes sitemap.xml and robots.txt.

Pages declare <!-- title: ... --> and <!-- description: ... --> after <html>; the build strips them and fails if either is missing. Spec pages use the node's name and blurb.

The domain is a placeholder, https://campercan.example, in src/site.json. It needs the real one before launch.

Tested: node --test passes (4 tests, one new).

Ticket: CC-8

Each page now has its own title, description, canonical URL and Open Graph/Twitter tags with a 1200x630 share image (`src/og.png`). The build also writes `sitemap.xml` and `robots.txt`. Pages declare `<!-- title: ... -->` and `<!-- description: ... -->` after `<html>`; the build strips them and fails if either is missing. Spec pages use the node's `name` and `blurb`. The domain is a placeholder, `https://campercan.example`, in `src/site.json`. It needs the real one before launch. Tested: `node --test` passes (4 tests, one new). Ticket: CC-8
Claude left a comment

Two things to act on.

  1. test/build.test.js: the test only checks og:image, titles and sitemap. Dropping the canonical link, og:url, the twitter tags or the description meta would still pass. It also never covers escaping (the hub blurb has a ", so assert &quot; in spec/hub.html), robots.txt, or the .xml/.txt types in server.js. Add a few cheap assertions for canonical, description and robots.txt.

  2. src/site.json: the origin is the placeholder https://campercan.example. Canonical, og:url, the sitemap and robots.txt will all point at it if this ships as is. Set the real domain before merge, or confirm it's deliberate.

Minor: escapeHtml in build.js skips >. It's harmless inside attributes, but it is incomplete.

Two things to act on. 1. test/build.test.js: the test only checks og:image, titles and sitemap. Dropping the canonical link, og:url, the twitter tags or the description meta would still pass. It also never covers escaping (the hub blurb has a `"`, so assert `&quot;` in spec/hub.html), robots.txt, or the .xml/.txt types in server.js. Add a few cheap assertions for canonical, description and robots.txt. 2. src/site.json: the origin is the placeholder `https://campercan.example`. Canonical, og:url, the sitemap and robots.txt will all point at it if this ships as is. Set the real domain before merge, or confirm it's deliberate. Minor: `escapeHtml` in build.js skips `>`. It's harmless inside attributes, but it is incomplete.
Claude changed target branch from main to site-hardening 2026-10-07 11:09:15 +00:00
rob merged commit 8fc5efbe09 into site-hardening 2026-10-07 13:28:21 +00:00
rob deleted branch cc-8-seo 2026-10-07 13:28:21 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
rob/CamperCan!4
No description provided.