Skip to content

feat(pathways): add canonical + Course JSON-LD to pathway pages#185

Merged
jt14den merged 1 commit into
mainfrom
fix/pathway-jsonld-canonical
Jul 10, 2026
Merged

feat(pathways): add canonical + Course JSON-LD to pathway pages#185
jt14den merged 1 commit into
mainfrom
fix/pathway-jsonld-canonical

Conversation

@jt14den

@jt14den jt14den commented Jul 10, 2026

Copy link
Copy Markdown
Collaborator

Summary

Item 5 from the AI Discoverability Remediation Plan. src/pages/pathways/[id].astro had zero JSON-LD and no <link rel="canonical">.

Design decision: represent a pathway as schema.org Course, not ItemList/CollectionPage. Every lesson page already declares isPartOf: [{"@type": "Course", name: ...}] for its pathways (LessonJsonLd.astro) — that reference had no @id/url, so it was a dangling, unreferenceable node in the graph. Keeping Course on the pathway side and giving it a stable @id fixes that instead of introducing a second type for the same concept.

  • <link rel="canonical"> via the shared absoluteUrl() helper (from fix(discoverability): base-path-aware URLs, RSS 404, orphaned lesson pages #183)
  • Course JSON-LD: name, description, url, provider (UC OSPO Network as curator — individual lessons still carry their own real publisher/sameAs), and aboutDefinedTerm references derived from the union of topics covered by the pathway's own lessons, reusing the same controlled vocabulary lesson pages already reference rather than a second free-text list that could drift
  • LessonJsonLd.astro: the isPartOf Course stub now includes the matching @id

Deliberately left out hasPart/itemListElement enumerating every lesson — the page already renders the full lesson list and each lesson has its own JSON-LD, so re-enumerating on the Course node would be redundant weight for no real gain.

Test plan

  • npm run build succeeds
  • npx astro check — 0 errors
  • All 4 pathway pages: <link rel="canonical"> present, JSON-LD parses as valid JSON
  • Sample lesson (introduction-to-git) isPartOf now includes @id matching its pathway's canonical URL

Pathway pages had zero JSON-LD and no <link rel="canonical">. Adds:

- <link rel="canonical"> via the shared absoluteUrl() helper
- Course JSON-LD with a stable @id, matching the isPartOf: Course
  reference every lesson page already declares for its pathways
  (LessonJsonLd.astro) — that reference had no @id/url before this,
  so it was a dangling, unreferenceable node in the graph
- about: DefinedTerm references derived from the union of topics
  covered by the pathway's own lessons, reusing the same controlled
  vocabulary lesson pages reference (no separate free-text list to
  drift out of sync)

Course over ItemList/CollectionPage to stay consistent with the
existing isPartOf convention rather than introduce a second type for
the same concept. Left hasPart/itemListElement out — the page already
renders the full lesson list and each lesson has its own JSON-LD, so
enumerating them again on the Course node would be redundant weight
for no real gain.

Also fixes LessonJsonLd.astro's isPartOf Course stub to include the
matching @id.
@github-actions

Copy link
Copy Markdown

Lesson Validation Report

Metric Value
Status ✅ Pass
Mode delta-none
Lessons checked 66
Changed lesson files 0
Scoped lessons 0
URL checks run 0
Blocking errors 0
Warnings 0

Blocking Errors (top 10)

None

Warnings (top 10)

None

Workflow logs: https://github.com/UC-OSPO-Network/education/actions/runs/29128154090

@jt14den
jt14den merged commit 019afb5 into main Jul 10, 2026
3 checks passed
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.

1 participant