Skip to content

SEO/GenAI structured data + author profile page rebuild#784

Open
LukasWallrich wants to merge 1 commit into
mainfrom
feat/seo-structured-data-and-author-pages
Open

SEO/GenAI structured data + author profile page rebuild#784
LukasWallrich wants to merge 1 commit into
mainfrom
feat/seo-structured-data-and-author-pages

Conversation

@LukasWallrich
Copy link
Copy Markdown
Contributor

Summary

Adds structured data (JSON-LD) across the site for richer search-engine and GenAI results, and rebuilds the author profile system, which was fundamentally broken.

SEO / GenAI optimisation advice by Keegan Vaz — thank you! 🙏

Part 1 — Structured data (JSON-LD)

All built with the repo's existing dict + jsonify + safeJS convention (as in clusters/seo_jsonld.html), which JSON-escapes values safely — rather than hand-written JSON string interpolation.

Schema Where
DefinedTerm every glossary term page (all 5 languages, correct inLanguage)
Article Educators' Corner posts
ScholarlyArticle / CollectionPage the two Summaries pages (196 + 34 entries)
Person substantive author profiles

On DOIs: Summaries DOIs are extracted from the stored APA reference strings via regex — never fabricated. When a reference has no DOI, the field is omitted.

Not added — meta-description partial: the theme's site_head.html already emits description / og:description / twitter:description (and even uses a glossary term's definition), so a separate partial would only duplicate the tags.

Part 2 — Author profile page rebuild

The problem

content/authors/ was simultaneously a content section and the authors taxonomy (same name). Consequences:

  • Any profile whose term slug matched its folder name was suppressed (rendered nowhere) due to the section/taxonomy path collision.
  • Every profile carried a junk authors: - Name "X" field (a template copy-paste error) that mangled the surviving pages — they rendered at /author/name-<slug>/ with titles literally reading Name "...".
  • ~250 such thin, mangled pages were in the sitemap, hurting SEO.

The fix

  • Disabled the author taxonomy + its permalink; author profiles now render as plain section pages at /authors/<slug>/.
  • Rewrote layouts/authors/list.html to render the full profile (avatar, name, role, organization, social links, bio, real interests) plus an auto-generated list of that author's posts — and an alphabetical authors index at /authors/.
  • Stripped the junk authors: field and added a proper title: across the 119 profiles.
  • Override page_metadata_authors.html so bylines slugify display names and link to the new /authors/<slug>/ URLs (previously they pointed at an empty /author/).
  • Noindex empty template stubs (no bio/role/org/interests and no credited content) so they don't dilute search. 59 substantive profiles are indexed and carry Person schema; 60 empty stubs are noindex, follow.

Adding authors going forward

Drop a folder under content/authors/<username>/ with an _index.md (name, optional role/bio/organizations/social) and an avatar image. No taxonomy quirks.

⚠️ URL change

Author URLs change from /author/name-<slug>//authors/<slug>/. The old URLs were auto-generated and not referenced by any internal link (verified across content, layouts, data, static). If any are indexed/linked externally, we can add aliases for redirects.

Verification

  • hugo build is green.
  • Profile pages render correctly (verified via screenshots — avatar/role/org/bio/posts).
  • 119 author pages; old /author/* pages gone (0 in sitemap); exactly one Person per substantive profile (no theme duplicate).
  • All JSON-LD parses as valid JSON; schemas confirmed across glossary languages, educators, and both summaries pages.

🤖 Generated with Claude Code

Structured data (JSON-LD), built with the repo's dict + jsonify + safeJS
convention for safe escaping:
- DefinedTerm on glossary term pages (all languages, correct inLanguage)
- Article on Educators' Corner posts
- ScholarlyArticle/CollectionPage on the Summaries pages (DOIs are
  extracted from the stored references, never fabricated)
- Person on substantive author profiles

The proposed standalone meta-description partial was intentionally not
added: the theme's site_head already emits description/og/twitter tags
(including from a glossary term's definition), so it would only duplicate.

Author profile pages were broken: content/authors/ was both a content
section and the `authors` taxonomy, so every profile whose term slug
matched its folder name was suppressed, and a junk `authors: - Name "X"`
field in each profile mangled the remaining URLs and titles (pages showed
up as `Name "..."` at /author/name-x/). ~250 such thin pages were in the
sitemap, hurting SEO.

Rebuild:
- Disable the `author` taxonomy + permalink; render profiles as plain
  section pages at /authors/<slug>/.
- Rewrite layouts/authors/list.html to render the profile (avatar, name,
  role, organization, social, bio, interests) plus the author's posts,
  and add an alphabetical authors index.
- Strip the junk `authors:` field and add a proper `title:` across the
  119 profiles.
- Override page_metadata_authors.html so bylines slugify display names
  and link to the new /authors/<slug>/ URLs.
- Noindex empty template-stub profiles (no bio/role/org/interests and no
  credited content) so they don't dilute search.

Note: author URLs change from /author/name-<slug>/ to /authors/<slug>/.
No internal links referenced the old URLs.

SEO / GenAI optimisation advice by Keegan Vaz.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@LukasWallrich LukasWallrich requested a review from a team as a code owner June 3, 2026 13:53
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 3, 2026

👍 All image files/references (if any) are in webp format, in line with our policy.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 3, 2026

✅ Spell Check Passed

No spelling issues found when checking 130 changed file(s)! 🎉

@LukasWallrich
Copy link
Copy Markdown
Contributor Author

Staging Deployment Status

This PR has been successfully deployed to staging as part of an aggregated deployment.

Deployed at: 2026-06-03 13:58:10 UTC
Staging URL: https://staging.forrt.org

The staging site shows the combined state of all compatible open PRs.

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