Changelog 6c40238
Link old changelog entries only to pages that still exist
The deploy's SEO audit failed on 14 links from old changelog pages to history and culture entries that were later renamed or removed (for example croatia-medical-production-2025). A changelog page now links such an entry only while its page exists, and shows the title alone otherwise, as it already did for countries. Reproduced with the full git history, as the deploy builds it: 3,945 indexable pages, no problems. Claude-Session: https://claude.ai/code/session_015PFhJhHBpXsnUocs8vvYAd
1 file of code, design or docs +10 −5 lines
Code, design and documents 1 file
src/pages/changelog/[hash].astro +10 −5
@@ -4,5 +4,6 @@ import Base from "../../layouts/Base.astro"; import UncommittedReload from "../../components/UncommittedReload.astro"; import { commits, emptyGroups, reloadUncommitted, summaryOf } from "../../lib/gitlog.js"; -import { formatDate, places, SEGMENTS, segmentPoints } from "../../lib/countries.js"; +import { formatDate, places, changes, SEGMENTS, segmentPoints } from "../../lib/countries.js"; +import { cultureEntries } from "../../lib/culture.js"; import { tierColor } from "../../lib/tiers.js"; @@ -32,4 +33,8 @@ const g = c.groups; const CAP = 200; // longest list shown in full const placeUrl = (slug) => (places.some((p) => p.slug === slug.split("/")[0]) ? `${base}country/${slug}/` : null); +// An old change can name a history or culture entry that has since been renamed or removed: it is +// linked only while the page still exists, otherwise its title stands alone. +const live = new Set([...changes.map((ch) => `history/${ch.id}/`), ...cultureEntries.map((e) => e.url)]); +const pageUrl = (path) => (path && (live.has(path) || !/^(history|culture)\//.test(path)) ? `${base}${path}` : null); const label = (name) => name.replace(/\./g, " › ").replace(/_/g, " "); const scored = g.places.filter((p) => p.scores?.length); @@ -79,5 +84,5 @@ const moves = g.places.filter((p) => p.scores?.length || (p.status === "added" & <h3 class="gl-h" id="gl-history-added">Added <span>{g.history.added.length}</span></h3> <ul class="gl-entries"> - {g.history.added.slice(0, CAP).map((e) => <li class="gl-add"><a href={`${base}history/${e.id}/`}>{e.title}</a> <small>{e.date}</small></li>)} + {g.history.added.slice(0, CAP).map((e) => <li class="gl-add">{pageUrl(`history/${e.id}/`) ? <a href={pageUrl(`history/${e.id}/`)}>{e.title}</a> : e.title} <small>{e.date}</small></li>)} {g.history.added.length > CAP && <li class="gl-more">and {g.history.added.length - CAP} more</li>} </ul> @@ -89,5 +94,5 @@ const moves = g.places.filter((p) => p.scores?.length || (p.status === "added" & {g.history.changed.slice(0, CAP).map((e) => ( <article class="gl-card"> - <h4><a href={`${base}history/${e.id}/`}>{e.title}</a></h4> + <h4>{pageUrl(`history/${e.id}/`) ? <a href={pageUrl(`history/${e.id}/`)}>{e.title}</a> : e.title}</h4> {e.fields.map((f) => <div class="gl-field"><span>{label(f.name)}</span><p class="gl-words">{f.parts.map(([k, t]) => k === "+" ? <ins>{t}</ins> : k === "-" ? <del>{t}</del> : t)}</p></div>)} </article> @@ -124,5 +129,5 @@ const moves = g.places.filter((p) => p.scores?.length || (p.status === "added" & {newTexts.length > 0 && ( <ul class="gl-entries"> - {newTexts.slice(0, CAP).map((t) => <li class={t.status === "added" ? "gl-add" : "gl-del"}>{t.url && t.status === "added" ? <a href={`${base}${t.url}`}>{t.title}</a> : t.title} <small>{t.kind} · {t.status} · {t.words} words</small></li>)} + {newTexts.slice(0, CAP).map((t) => <li class={t.status === "added" ? "gl-add" : "gl-del"}>{t.status === "added" && pageUrl(t.url) ? <a href={pageUrl(t.url)}>{t.title}</a> : t.title} <small>{t.kind} · {t.status} · {t.words} words</small></li>)} {newTexts.length > CAP && <li class="gl-more">and {newTexts.length - CAP} more</li>} </ul> @@ -130,5 +135,5 @@ const moves = g.places.filter((p) => p.scores?.length || (p.status === "added" & {editedTexts.slice(0, CAP).map((t) => ( <article class="gl-card"> - <h4>{t.url ? <a href={`${base}${t.url}`}>{t.title}</a> : t.title} <small>{t.file}</small></h4> + <h4>{pageUrl(t.url) ? <a href={pageUrl(t.url)}>{t.title}</a> : t.title} <small>{t.file}</small></h4> {t.fields.map((f) => <div class="gl-field"><span>{label(f.name)}</span><p class="gl-words">{f.parts.map(([k, x]) => k === "+" ? <ins>{x}</ins> : k === "-" ? <del>{x}</del> : x)}</p></div>)} </article>