Skip to content

Add canonical link injection to public CV pages#164

Merged
vincentmakes merged 1 commit into
mainfrom
claude/add-canonical-link-bcXdc
May 6, 2026
Merged

Add canonical link injection to public CV pages#164
vincentmakes merged 1 commit into
mainfrom
claude/add-canonical-link-bcXdc

Conversation

@vincentmakes
Copy link
Copy Markdown
Owner

Description

Adds <link rel="canonical"> tag injection to public CV pages to prevent search engine indexing of duplicate content across URL variants. The canonical link is derived from the request and respects reverse-proxy headers (X-Forwarded-Proto and X-Forwarded-Host), consistent with how /sitemap.xml and /robots.txt are already handled.

Behavior:

  • Public root (/) and live-CV fallback pages always emit a canonical link
  • /v/:slug pages emit a canonical link only when slugsIndex setting is enabled
  • When slugsIndex is disabled, /v/:slug pages receive noindex, nofollow robots meta tag instead

Implementation:

  • New buildCanonicalTag(req) helper function in src/server.js that constructs the canonical URL from request headers and path
  • Canonical injection applied at all three SSR injection points in servePublicIndex() and serveDatasetPage()
  • Query strings and fragments are stripped (uses req.path)

Type of Change

  • New feature (non-breaking change that adds functionality)

Checklist

Required for all code changes

  • I have tested my changes locally (npm test passes)
  • Version has been bumped in all 3 files (package.json, package-lock.json, version.json)
  • CHANGELOG.md has been updated with a new entry under the correct version

If adding or changing user-visible strings

  • No user-visible strings added (canonical links are SEO metadata, not UI text)

Test Coverage

Added comprehensive test suite covering:

  • Canonical link emission on public root with X-Forwarded-Host
  • Protocol and host header handling (X-Forwarded-Proto and X-Forwarded-Host)
  • Canonical omission on /v/:slug when slugsIndex is disabled (with noindex verification)
  • Canonical emission on /v/:slug when slugsIndex is enabled

All tests pass with npm test.

https://claude.ai/code/session_01EGykcv9Yvem218n13TqYhz

Crawlers were free to index the same CV under multiple URL variants
(http vs https, alternate hostnames behind a reverse proxy, query-string
permutations). The public root, the live-CV fallback, and indexable
/v/:slug pages now emit a canonical link derived from the request,
honoring X-Forwarded-Proto / X-Forwarded-Host the same way sitemap.xml
and robots.txt already do — so no extra config is required. Slug pages
that resolve to noindex intentionally omit the tag.

https://claude.ai/code/session_01EGykcv9Yvem218n13TqYhz
@vincentmakes vincentmakes merged commit 0b3c60e into main May 6, 2026
3 checks passed
@vincentmakes vincentmakes deleted the claude/add-canonical-link-bcXdc branch May 6, 2026 13:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants