Skip to content

Commit d8fb56f

Browse files
afuchereca-agent
andauthored
feat(website): add starlight-links-validator to catch broken internal links (#119)
* fix(website): correct broken relative links in docs content pages GitHub Pages serves every page at a trailing-slash URL (e.g. /AstroChart/quickstart/). From such a URL, `./guides/foo` resolves to /AstroChart/quickstart/guides/foo instead of /AstroChart/guides/foo. Fix all cross-directory relative links on top-level pages to use `../` instead of `./` when navigating into subdirectories: - quickstart.mdx: 7 links (Next Steps + Troubleshooting) - introduction.mdx: 2 links (guides/radix-chart, api/chart) - installation.md: 5 links (compatibility table + Next Steps) - changelog.md: 1 dead link replaced (guides/getting-started → ../introduction) Also: - astro.config.mjs: remove bare favicon '/favicon.svg' (Starlight auto-discovers public/favicon.svg); add trailingSlash: 'always' so dev server matches GitHub Pages behavior and catches link bugs early - AGENTS.md: add 'Website / Astro link strategy' section with a per-depth reference table and future domain migration note 🤖 Generated with [eca](https://eca.dev) Co-Authored-By: eca <git@eca.dev> * fix(website): ensure withBase always produces a trailing-slash URL trailingSlash: 'always' in astro.config.mjs makes the dev server enforce slash-terminated URLs (mirroring GitHub Pages). withBase was producing slash-less paths (e.g. /AstroChart/installation) which the strict dev server no longer matched, breaking the Get Started and other hero links. Fix: append a trailing slash in withBase if not already present. withBase('/installation') → '/AstroChart/installation/' All callers in index.astro are fixed automatically. No other files change. Edge cases verified: base: '/AstroChart' → /AstroChart/installation/ ✅ base: '/' → /installation/ ✅ (future astrochart.dev) 🤖 Generated with [eca](https://eca.dev) Co-Authored-By: eca <git@eca.dev> * fix(website): fix remaining broken sibling links on root-level pages Root-level pages use trailing-slash URLs (e.g. /AstroChart/introduction/). ./sibling from such a URL resolves to /AstroChart/introduction/sibling — wrong. All sibling links on root pages must use ../ to reach /AstroChart/sibling. introduction.mdx: ./installation, ./quickstart (×2), ./contributing → ../ installation.md: ./quickstart → ../quickstart These were missed in the first pass which only fixed cross-directory links. Full project audit confirmed no other broken relative links remain. 🤖 Generated with [eca](https://eca.dev) Co-Authored-By: eca <git@eca.dev> * docs(agents): fix wrong link rule and add mandatory audit step The link strategy table incorrectly said root pages use './' for sibling root pages. That was the exact mistake that caused two broken-link passes. Corrected: root pages use '../' for ALL targets (siblings and subdirs) because the trailing-slash URL makes the browser treat the page as a directory. Added an explanatory callout making the 'why' explicit so the rule is impossible to misread. Added a mandatory link audit rule: any task touching content files or trailingSlash/base config must end with a full grep of src/content/docs/ to verify no root-level page retains any './' link. 🤖 Generated with [eca](https://eca.dev) Co-Authored-By: eca <git@eca.dev> * fix(website): remove trailingSlash always — breaks all markdown links in dev Astro markdown pipeline emits relative hrefs verbatim (no trailing slash). trailingSlash: always makes the dev server 404 every one of the ~50 relative links in the content tree. GitHub Pages issues a silent 301 for slash-less URLs in production so links work fine without the strict setting. AGENTS.md: added explicit do-not-add warning explaining the tension with the markdown pipeline. Removed the incorrect claim that the setting catches bugs. 🤖 Generated with [eca](https://eca.dev) Co-Authored-By: eca <git@eca.dev> * feat(website): add starlight-links-validator to catch broken internal links Install starlight-links-validator@0.21.0 and register it as a Starlight plugin. Validation runs only on `npm run build` (skipped in dev mode to keep `astro dev` fast). Configuration: `errorOnRelativeLinks: false` — all internal links use relative paths so the site can be migrated to a different base (e.g. astrochart.dev) by changing only `astro.config.mjs`. Hash fragments (e.g. `#valid-planet-keys`) are still validated. Also fixes two pre-existing broken links in guides/frameworks/ where `../multiple-charts` was one level short and should be `../../multiple-charts`. 🤖 Generated with [eca](https://eca.dev) Co-Authored-By: eca <git@eca.dev> --------- Co-authored-by: eca <git@eca.dev>
1 parent 57c497f commit d8fb56f

11 files changed

Lines changed: 225 additions & 30 deletions

File tree

‎AGENTS.md‎

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,41 @@
3434
- Any new sub-project directory **must** be added to the root `tsconfig.json` `exclude` list AND to the `exclude` regex in `webpack.config.js` before committing
3535
- After adding a sub-project, always run `npm run build` and `npm test` from the **root** to verify isolation
3636

37+
## Website / Astro link strategy
38+
39+
**The trailing-slash rule:** GitHub Pages serves every page at a URL ending in `/`
40+
(e.g. `/AstroChart/quickstart/`). The browser resolves `./` relative to that directory,
41+
so `./guides/foo` from a root page resolves to `/AstroChart/quickstart/guides/foo` — **broken**.
42+
43+
Use this rule for all links inside `src/content/docs/`:
44+
45+
| From page depth | Link target | Correct prefix | Example |
46+
|---|---|---|---|
47+
| Root page (`quickstart.md`) | Any other page (sibling OR subdir) | `../` | `../installation`, `../guides/radix-chart` |
48+
| Subdir page (`guides/radix-chart.mdx`) | Sibling in same subdir | `./` | `./transit-chart` |
49+
| Subdir page (`guides/radix-chart.mdx`) | Root page or other subdir | `../` | `../api/settings` |
50+
| Nested subdir (`guides/frameworks/react.md`) | Sibling in same nested subdir | `./` | `./vue` |
51+
| Nested subdir (`guides/frameworks/react.md`) | Parent subdir | `../` | `../radix-chart` |
52+
| Nested subdir (`guides/frameworks/react.md`) | Root or other top-level subdir | `../../` | `../../api/chart` |
53+
54+
> **Why root pages always use `../`:** GitHub Pages (and `trailingSlash: 'always'`) serves
55+
> every page at a URL ending in `/` (e.g. `/AstroChart/installation/`). The browser treats
56+
> that as a directory, so `./quickstart` resolves to `/AstroChart/installation/quickstart` —
57+
> **wrong even for siblings**. Use `../` to escape to `/AstroChart/` first.
58+
59+
- **In `.astro` templates:** use `import.meta.env.BASE_URL + '/path'` (already correct in `index.astro`).
60+
- **In Starlight config (`astro.config.mjs`):** use `slug:` values — never `link:` with absolute paths.
61+
- **Never** use root-absolute paths like `/guides/foo` inside `.md`/`.mdx` — they ignore the `base` setting.
62+
- **Future domain migration** (`astrochart.dev`): change only `site` and `base` in `astro.config.mjs` — no content files change.
63+
64+
> **⚠️ Do not set `trailingSlash: 'always'`** in `astro.config.mjs`.
65+
> Astro's markdown pipeline emits relative link hrefs verbatim (`../guides/foo`, no trailing
66+
> slash). Setting `'always'` makes the dev server 404 every one of the ~50 relative links in
67+
> the content tree. GitHub Pages issues a silent 301 for slash-less URLs in production, so
68+
> links work correctly without the strict setting. The default (`'ignore'`) is correct here.
69+
70+
**⚠️ Link audit rule:** Any task that adds/edits content files OR changes `base` config **must** end with a full grep audit of all `./` links across the entire `src/content/docs/` tree to confirm no root-level page has a `./` prefix remaining.
71+
3772
## Website / Astro content rules
3873
- **MDX required for component imports:** Starlight content files that use `import` and JSX component tags **must** have a `.mdx` extension. A `.md` file will print the import statement as plain text and silently ignore all component tags.
3974
- **Multi-instance inline script loading:** When an Astro `is:inline` script dynamically loads an external JS bundle, multiple component instances on the same page will all run simultaneously. Use a shared queue pattern to avoid race conditions:

‎website/astro.config.mjs‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
11
import { defineConfig } from 'astro/config'
22
import starlight from '@astrojs/starlight'
33
import sitemap from '@astrojs/sitemap'
4+
import starlightLinksValidator from 'starlight-links-validator'
5+
6+
const isDev = process.env.NODE_ENV === 'development'
47

58
export default defineConfig({
69
site: 'https://astrodraw.github.io/AstroChart',
710
base: '/AstroChart',
811
integrations: [
912
starlight({
13+
plugins: [...(isDev ? [] : [starlightLinksValidator({ errorOnRelativeLinks: false })])],
1014
title: 'AstroChart',
1115
description: 'Pure SVG astrology charts for the web',
12-
favicon: '/favicon.svg',
1316
logo: {
1417
src: './public/img/logo.svg',
1518
alt: 'AstroChart Logo'

‎website/package-lock.json‎

Lines changed: 152 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎website/package.json‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,13 @@
1010
"astro": "astro"
1111
},
1212
"dependencies": {
13-
"astro": "^6.0.0",
14-
"@astrojs/starlight": "^0.38.0",
1513
"@astrojs/sitemap": "^3.1.0",
14+
"@astrojs/starlight": "^0.38.0",
15+
"astro": "^6.0.0",
1616
"sharp": "^0.33.0"
1717
},
1818
"devDependencies": {
19+
"starlight-links-validator": "^0.21.0",
1920
"typescript": "^5.3.3"
2021
},
2122
"engines": {

‎website/src/content/docs/changelog.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ This project adheres to [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
5353

5454
### Changed
5555
- **Breaking:** Package renamed to `@astrodraw/astrochart`
56-
- **Breaking:** `AstroData` shape changed to `{ planets: Record<string, number[]>, cusps: number[] }` — see the [Getting Started guide](./guides/getting-started)
56+
- **Breaking:** `AstroData` shape changed to `{ planets: Record<string, number[]>, cusps: number[] }` — see the [Introduction](../introduction)
5757
- Cusps array must contain exactly 12 values; validation throws a descriptive error on mismatch
5858
- `SHIFT_IN_DEGREES` default changed to `180` (0° on the West / Ascendant side)
5959

‎website/src/content/docs/guides/frameworks/angular.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,4 +160,4 @@ export class AstroChartComponent implements AfterViewInit, OnDestroy {
160160
161161
- **[React Integration](./react)** — Use with React
162162
- **[Vue Integration](./vue)** — Use with Vue
163-
- **[Multiple Charts](../multiple-charts)** — Render several instances on one page
163+
- **[Multiple Charts](../../multiple-charts)** — Render several instances on one page

‎website/src/content/docs/guides/frameworks/vue.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,4 +203,4 @@ const chartData = { planets: { Sun: [120.5] }, cusps: [0,30,60,90,120,150,180,21
203203

204204
- **[React Integration](./react)** — Use with React
205205
- **[Angular Integration](./angular)** — Use with Angular
206-
- **[Multiple Charts](../multiple-charts)** — Render several instances on one page
206+
- **[Multiple Charts](../../multiple-charts)** — Render several instances on one page

‎website/src/content/docs/installation.md‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,9 @@ No additional `@types/` package needed.
8181
| Browsers (modern) | ✅ Supported |
8282
| IE11 | ⚠️ Requires polyfills |
8383
| Mobile browsers | ✅ Supported |
84-
| React | ✅ See [React guide](./guides/frameworks/react) |
85-
| Vue | ✅ See [Vue guide](./guides/frameworks/vue) |
86-
| Angular | ✅ See [Angular guide](./guides/frameworks/angular) |
84+
| React | ✅ See [React guide](../guides/frameworks/react) |
85+
| Vue | ✅ See [Vue guide](../guides/frameworks/vue) |
86+
| Angular | ✅ See [Angular guide](../guides/frameworks/angular) |
8787

8888
## Verification
8989

@@ -98,6 +98,6 @@ console.log('AstroChart version:', version)
9898

9999
## Next Steps
100100

101-
- **[Quick Start](./quickstart)** — Render your first chart
102-
- **[API Reference](./api/chart)** — Learn all available methods
103-
- **[Guides](./guides/radix-chart)** — Explore common use cases
101+
- **[Quick Start](../quickstart)** — Render your first chart
102+
- **[API Reference](../api/chart)** — Learn all available methods
103+
- **[Guides](../guides/radix-chart)** — Explore common use cases

‎website/src/content/docs/introduction.mdx‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -88,10 +88,10 @@ Here's a basic radix chart rendered with AstroChart:
8888

8989
## Next Steps
9090

91-
- **[Installation Guide](./installation)** — Detailed setup instructions for npm, CDN, and more
92-
- **[Quick Start Guide](./quickstart)** — A step-by-step walkthrough with examples
93-
- **[Radix Chart Guide](./guides/radix-chart)** — Learn how to render complete natal charts
94-
- **[API Reference](./api/chart)** — Complete documentation of all classes and methods
91+
- **[Installation Guide](../installation)** — Detailed setup instructions for npm, CDN, and more
92+
- **[Quick Start Guide](../quickstart)** — A step-by-step walkthrough with examples
93+
- **[Radix Chart Guide](../guides/radix-chart)** — Learn how to render complete natal charts
94+
- **[API Reference](../api/chart)** — Complete documentation of all classes and methods
9595

9696
## Browser Support
9797

@@ -105,8 +105,8 @@ AstroChart is released under the **MIT License**. See the [GitHub repository](ht
105105

106106
## Contributing
107107

108-
Found a bug? Have a feature request? We'd love your help! See the [Contributing Guide](./contributing) for instructions.
108+
Found a bug? Have a feature request? We'd love your help! See the [Contributing Guide](../contributing) for instructions.
109109

110110
---
111111

112-
Ready to dive in? [Get started now](./quickstart).
112+
Ready to dive in? [Get started now](../quickstart).

‎website/src/content/docs/quickstart.mdx‎

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -127,11 +127,11 @@ Here's a live example you can interact with:
127127

128128
## Next Steps
129129

130-
- **[Radix Chart Guide](./guides/radix-chart)** — Learn more about radix charts and all available planets
131-
- **[Transit Charts](./guides/transit-chart)** — Add a transit ring to overlay current positions
132-
- **[Animation](./guides/animation)** — Animate chart transitions
133-
- **[Custom Settings](./guides/custom-settings)** — Customize colors, fonts, and more
134-
- **[API Reference](./api/chart)** — See all available methods and options
130+
- **[Radix Chart Guide](../guides/radix-chart)** — Learn more about radix charts and all available planets
131+
- **[Transit Charts](../guides/transit-chart)** — Add a transit ring to overlay current positions
132+
- **[Animation](../guides/animation)** — Animate chart transitions
133+
- **[Custom Settings](../guides/custom-settings)** — Customize colors, fonts, and more
134+
- **[API Reference](../api/chart)** — See all available methods and options
135135

136136
## Troubleshooting
137137

@@ -146,5 +146,5 @@ Here's a live example you can interact with:
146146

147147
**Need help?**
148148
- [Open an issue on GitHub](https://github.com/AstroDraw/AstroChart/issues)
149-
- Check the [API Reference](./api/chart)
150-
- See [Common Guides](./guides/radix-chart)
149+
- Check the [API Reference](../api/chart)
150+
- See [Common Guides](../guides/radix-chart)

0 commit comments

Comments
 (0)