fix(footer): send each documentation link to the section its label names
All checks were successful
PR checks / checks (pull_request) Successful in 9m38s
All checks were successful
PR checks / checks (pull_request) Successful in 9m38s
All three links under "Documentation" pointed at /docs/. Three labels — Getting started, Administration, Building a module — and one destination, which is the docs home and also what the header's Docs link already opens. They now land inside the section they name: Getting started /docs/getting-started/requirements/ Administration /docs/administration/configuration/ Building a module /docs/modules/building-a-module/ The docs home stays the header's link rather than becoming a fourth route to the same page. Eleven checks and two suites could not see this, and the reason is worth keeping: the bug is not a broken link. checkLinks resolves every internal href against the build and /docs/ resolves — three links to a page that exists are three valid links. checkSidebar compares the docs tree to the planned tree and never looks at the footer. checkA11y checks structure, and three correctly marked-up anchors are correct markup. Nothing asserted that a link goes where its label says. So the columns move to src/data/footer.mjs, beside legal.mjs and collection.mjs, and test/footer.test.mjs asserts it: every destination in a column distinct, no destination repeated across columns, each documentation link inside its own section prefix, none of them the docs home, and the two Project links still read from the brand. A column list inside an .astro component cannot be imported by a test, which is the whole reason for the move. Verified by reintroducing the bug: the suite fails with "Administration points at /docs/, which is not inside /docs/administration/". Restored, npm run verify is green — 42 tests, eleven checks, and the built index.html renders three distinct hrefs. Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
---
|
||||
import { renderBrand } from '../lib/brand.mjs';
|
||||
import { legal } from '../data/legal.mjs';
|
||||
import { footerColumns } from '../data/footer.mjs';
|
||||
import platform from '../data/platform.json';
|
||||
|
||||
/**
|
||||
@@ -19,33 +20,9 @@ const brand = renderBrand(Astro);
|
||||
|
||||
const year = new Date().getFullYear();
|
||||
|
||||
const columns = [
|
||||
{
|
||||
heading: 'Product',
|
||||
links: [
|
||||
{ href: '/features/', label: 'Features' },
|
||||
{ href: '/architecture/', label: 'Architecture' },
|
||||
{ href: '/modules/', label: 'Modules' },
|
||||
{ href: '/app/', label: 'Android app' },
|
||||
],
|
||||
},
|
||||
{
|
||||
heading: 'Documentation',
|
||||
links: [
|
||||
{ href: '/docs/', label: 'Getting started' },
|
||||
{ href: '/docs/', label: 'Administration' },
|
||||
{ href: '/docs/', label: 'Building a module' },
|
||||
],
|
||||
},
|
||||
{
|
||||
heading: 'Project',
|
||||
links: [
|
||||
{ href: brand.giteaOrg, label: 'Source' },
|
||||
{ href: brand.discordInvite, label: 'Discord' },
|
||||
{ href: '/community/', label: 'Community' },
|
||||
],
|
||||
},
|
||||
];
|
||||
// The columns live in src/data/footer.mjs so a test can read them — see the note there,
|
||||
// and test/footer.test.mjs. The two Project links come from the mounted brand (§7).
|
||||
const columns = footerColumns(brand);
|
||||
|
||||
const isExternal = (href: string) => href.startsWith('http');
|
||||
---
|
||||
|
||||
57
src/data/footer.mjs
Normal file
57
src/data/footer.mjs
Normal file
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* The footer's link columns.
|
||||
*
|
||||
* Data rather than markup, and in `src/data/` beside `legal.mjs` and `collection.mjs`, for
|
||||
* one reason: the links shipped wrong. All three entries under "Documentation" pointed at
|
||||
* `/docs/`, so the column rendered three different labels that went to the same page — and
|
||||
* every check passed, because each href resolved perfectly well. `checkLinks.mjs` asks
|
||||
* whether a link is broken; nothing asked whether a link goes where its label says.
|
||||
*
|
||||
* `test/footer.test.mjs` asks that now, which it can only do because the columns are
|
||||
* importable. That is the whole reason this file exists.
|
||||
*
|
||||
* The two Project links are brand-supplied (§7, D13), so this is a function of the rendered
|
||||
* brand rather than a constant — the mounted `brand.json` decides them, and `/beta` renders
|
||||
* per request, so they cannot be baked at build time.
|
||||
*/
|
||||
|
||||
/** Documentation sections a footer link may point into, and where each one starts. */
|
||||
export const docsEntryPoints = {
|
||||
'getting-started': '/docs/getting-started/requirements/',
|
||||
administration: '/docs/administration/configuration/',
|
||||
modules: '/docs/modules/building-a-module/',
|
||||
};
|
||||
|
||||
export function footerColumns(brand) {
|
||||
return [
|
||||
{
|
||||
heading: 'Product',
|
||||
links: [
|
||||
{ href: '/features/', label: 'Features' },
|
||||
{ href: '/architecture/', label: 'Architecture' },
|
||||
{ href: '/modules/', label: 'Modules' },
|
||||
{ href: '/app/', label: 'Android app' },
|
||||
],
|
||||
},
|
||||
{
|
||||
// Each of these lands INSIDE the section it names. The docs home — "What is Runic
|
||||
// Gateway?", the first page of Getting started — is the header's `Docs` link, so a
|
||||
// footer entry pointing there as well would be a fourth way to the same page rather
|
||||
// than a way into the section.
|
||||
heading: 'Documentation',
|
||||
links: [
|
||||
{ href: docsEntryPoints['getting-started'], label: 'Getting started' },
|
||||
{ href: docsEntryPoints.administration, label: 'Administration' },
|
||||
{ href: docsEntryPoints.modules, label: 'Building a module' },
|
||||
],
|
||||
},
|
||||
{
|
||||
heading: 'Project',
|
||||
links: [
|
||||
{ href: brand.giteaOrg, label: 'Source' },
|
||||
{ href: brand.discordInvite, label: 'Discord' },
|
||||
{ href: '/community/', label: 'Community' },
|
||||
],
|
||||
},
|
||||
];
|
||||
}
|
||||
Reference in New Issue
Block a user