Skip to content

feat(seo): pre-render the landing answer block (What is Semantic Anchors?)#593

Merged
JensGrote merged 1 commit into
LLM-Coding:mainfrom
raifdmueller:feat/landing-answer-block
Jun 10, 2026
Merged

feat(seo): pre-render the landing answer block (What is Semantic Anchors?)#593
JensGrote merged 1 commit into
LLM-Coding:mainfrom
raifdmueller:feat/landing-answer-block

Conversation

@raifdmueller

@raifdmueller raifdmueller commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Implements the landing-block half of #580: a crawlable "What is Semantic Anchors?" answer on the home page.

The gap

The home page (/) rendered its hero client-side, so search engines and LLM fetchers saw only the empty SPA skeleton — the single worst case for the query "What is Semantic Anchors?", the exact query the GEO audit flagged as getting zero AI mentions. #579 gave the home machine-readable identity (DefinedTermSet); this gives it a human-readable answer.

Change

scripts/prerender-routes.js now fills the home #page-content with the hero copy — title, the definition ("Semantic Anchors are words … that activate rich, well-defined concepts inside any modern LLM"), and emphasis — single-sourced from website/src/translations/en.json so it can never drift from the live hero. No new content was written.

  • Runs after the ROUTES loop and writes only dist/index.html, so the other routes (built from the cached shell) keep their empty-skeleton assumption.
  • On boot the SPA's home route overwrites #page-content with the full interactive hero + card grid, so users are unaffected — standard progressive enhancement.

The per-anchor "direct answer" sweep from #580 is intentionally skipped: anchor definitions already ship crawlable via the pre-rendered /all-anchors page, so the marginal value is low.

Scope note

This also aligns with the rule that every page must be pre-rendered — the home was the last route serving an empty shell.

Verification

Full vite build run locally:

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Neue Funktionen

    • Der Landing-Block auf der Startseite wird nun serverseitig vorab generiert.
  • Dokumentation

    • Changelog aktualisiert mit Details zur Implementierungsänderung.

…ability

The home page rendered its hero client-side, so crawlers and LLM fetchers saw
only the empty skeleton — the worst case for the query "What is Semantic
Anchors?". prerender-routes.js now fills the home #page-content with the hero
copy (title + definition + emphasis), single-sourced from the EN translations
so it never drifts from the live hero. The SPA overwrites #page-content with
the full interactive hero + card grid on boot, so users are unaffected; the
home is written separately so other routes keep their empty-skeleton assumption.

Implements the landing-block half of LLM-Coding#580; the per-anchor answer-block sweep is
intentionally skipped — anchor definitions already ship crawlable via
/all-anchors.

Verified with a full build: the home #page-content carries the definition plus
the DefinedTermSet/Organization, and a control route (/about) neither leaks the
home block nor loses its own doc content.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

Der PR erweitert das Build-Skript, um einen „Landing Answer Block" mit Hero-Titel und Intro-Text server-seitig auf der Startseite vor-zu-rendern und direkt in dist/index.html zu injizieren; die Inhalte werden aus den Englisch-Übersetzungen gelesen. Ein Changelog-Eintrag dokumentiert diese Änderung.

Änderungen

Homepage-Landingblock-Pre-Rendering

Layer / Datei(en) Zusammenfassung
Pre-Rendering-Implementierung
scripts/prerender-routes.js
Neue Helfer-Funktion prerenderHome() liest EN-Übersetzungen, generiert HTML für den Home-Answer-Block und injiziert ihn in dist/index.html im #page-content-Element. main() wird erweitert, um diese Funktion nach dem Shell-Laden auszuführen und die Log-Ausgabe entsprechend anzupassen.
Changelog-Dokumentation
docs/changelog.adoc
Eintrag unter 2026-06-10 dokumentiert die nun Server-seitig gerenderte Darstellung des Landing-Blocks mit Single-Sourcing aus Übersetzungen (#580).

Geschätzter Code-Review-Aufwand

🎯 2 (Einfach) | ⏱️ ~10 Minuten

Möglicherweise zugehörige Issues

  • LLM-Coding/Semantic-Anchors#580: Der PR implementiert die Funktionalität aus diesem Issue — Server-seitiges Pre-Rendering eines crawlbaren „Landing Answer Blocks" auf der Startseite durch Lesen der Übersetzungen.

Möglicherweise zugehörige Pull Requests

  • LLM-Coding/Semantic-Anchors#462: Beide PRs adressieren denselben Homepage-„Hero/Landing-Answer-Block": dieser PR injiziert ihn Server-seitig via scripts/prerender-routes.js, während PR #462 die zugrundeliegenden i18n-Keys und Hero-Markup-Updates einführt.
  • LLM-Coding/Semantic-Anchors#429: Der PR erweitert die in PR #429 eingeführte Pre-Rendering-Logik in scripts/prerender-routes.js um die statische Injektion eines „home/landing answer blocks" in dist/index.html.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed Der Titel beschreibt präzise die Hauptänderung: Das Prerendern des Landing-Answer-Blocks (Hero-Content) auf der Startseite für SEO-Zwecke, was direkt mit den Änderungen in scripts/prerender-routes.js und docs/changelog.adoc übereinstimmt.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@scripts/prerender-routes.js`:
- Line 321: Die Abschlussmeldung in scripts/prerender-routes.js verwendet eine
ungenaue Formulierung; passe die console.log-Ausgabe (die Zeile mit ROUTES) so
an, dass sie korrekt widerspiegelt, dass Routen nach dist/<route>/index.html
geschrieben werden, während die Startseite nach dist/index.html geschrieben wird
(z.B. durch Nennung beider Ziele oder eine differenzierte Formulierung), damit
die Variable ROUTES und der separate Home-Block korrekt beschrieben sind.
- Around line 284-286: Die aktuelle stille Fallback-Logik mit "const title =
en['hero.title'] || ''" (und ähnlich für intro, emphasis) erzeugt leere
Hero-Blöcke bei fehlenden Übersetzungs-Keys; stattdessen prüfe in
prerender-routes.js nach dem Laden von en, ob die Keys en['hero.title'],
en['hero.intro'] und en['hero.introEmphasis'] vorhanden und nicht leer sind, und
wirf bei fehlenden/leeren Werten eine aussagekräftige Error-Exception (oder rufe
process.exit(1) auf), sodass der Build hart fehlschlägt; referenziere die
Variablen title, intro und emphasis in der Validierungslogik und liefere im
Fehlertext welche Key(s) fehlen.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: 815b904c-2be7-4574-8c8e-ad421a3ab090

📥 Commits

Reviewing files that changed from the base of the PR and between c5d4735 and 14561d0.

📒 Files selected for processing (2)
  • docs/changelog.adoc
  • scripts/prerender-routes.js

Comment on lines +284 to +286
const title = en['hero.title'] || ''
const intro = en['hero.intro'] || ''
const emphasis = en['hero.introEmphasis'] || ''

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Fehlende Pflicht-Validierung der Hero-Übersetzungsschlüssel

Mit || '' wird ein stiller Fehlerpfad erzeugt: Bei fehlenden/umbenannten Keys wird ein leerer Home-Answer-Block geschrieben, der Build bleibt aber erfolgreich. Für das SEO-Ziel sollte der Build hier hart fehlschlagen.

Vorschlag (fail-fast statt silent fallback)
 function prerenderHome() {
   const enPath = path.join(__dirname, '..', 'website', 'src', 'translations', 'en.json')
   const en = JSON.parse(fs.readFileSync(enPath, 'utf-8'))
-  const title = en['hero.title'] || ''
-  const intro = en['hero.intro'] || ''
-  const emphasis = en['hero.introEmphasis'] || ''
+  const requiredKeys = ['hero.title', 'hero.intro', 'hero.introEmphasis']
+  for (const key of requiredKeys) {
+    if (typeof en[key] !== 'string' || en[key].trim() === '') {
+      throw new Error(`Missing required translation key for home prerender: ${key}`)
+    }
+  }
+  const title = en['hero.title']
+  const intro = en['hero.intro']
+  const emphasis = en['hero.introEmphasis']
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const title = en['hero.title'] || ''
const intro = en['hero.intro'] || ''
const emphasis = en['hero.introEmphasis'] || ''
function prerenderHome() {
const enPath = path.join(__dirname, '..', 'website', 'src', 'translations', 'en.json')
const en = JSON.parse(fs.readFileSync(enPath, 'utf-8'))
const requiredKeys = ['hero.title', 'hero.intro', 'hero.introEmphasis']
for (const key of requiredKeys) {
if (typeof en[key] !== 'string' || en[key].trim() === '') {
throw new Error(`Missing required translation key for home prerender: ${key}`)
}
}
const title = en['hero.title']
const intro = en['hero.intro']
const emphasis = en['hero.introEmphasis']
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/prerender-routes.js` around lines 284 - 286, Die aktuelle stille
Fallback-Logik mit "const title = en['hero.title'] || ''" (und ähnlich für
intro, emphasis) erzeugt leere Hero-Blöcke bei fehlenden Übersetzungs-Keys;
stattdessen prüfe in prerender-routes.js nach dem Laden von en, ob die Keys
en['hero.title'], en['hero.intro'] und en['hero.introEmphasis'] vorhanden und
nicht leer sind, und wirf bei fehlenden/leeren Werten eine aussagekräftige
Error-Exception (oder rufe process.exit(1) auf), sodass der Build hart
fehlschlägt; referenziere die Variablen title, intro und emphasis in der
Validierungslogik und liefere im Fehlertext welche Key(s) fehlen.

}
console.log(`\n✓ Pre-rendered ${ROUTES.length} routes to dist/<route>/index.html`)
prerenderHome()
console.log(`\n✓ Pre-rendered ${ROUTES.length} routes + home to dist/<route>/index.html`)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Abschluss-Log ist fachlich ungenau

Die Meldung sagt dist/<route>/index.html, obwohl der Home-Block in dist/index.html geschrieben wird. Das erschwert Build-Diagnosen unnötig.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/prerender-routes.js` at line 321, Die Abschlussmeldung in
scripts/prerender-routes.js verwendet eine ungenaue Formulierung; passe die
console.log-Ausgabe (die Zeile mit ROUTES) so an, dass sie korrekt
widerspiegelt, dass Routen nach dist/<route>/index.html geschrieben werden,
während die Startseite nach dist/index.html geschrieben wird (z.B. durch Nennung
beider Ziele oder eine differenzierte Formulierung), damit die Variable ROUTES
und der separate Home-Block korrekt beschrieben sind.

@JensGrote JensGrote merged commit 042e741 into LLM-Coding:main Jun 10, 2026
7 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.

3 participants