Skip to content

fix(docs): resolve ./index.md and ../index.md links without a trailing slash - #5681

Open
vfanucci wants to merge 1 commit into
mainfrom
fix/301-docs-index-links
Open

vfanucci wants to merge 1 commit into
mainfrom
fix/301-docs-index-links

Conversation

@vfanucci

Copy link
Copy Markdown
Contributor

Two relative-link shapes in docs sources resolved to a directory URL with a trailing slash, which the site 301s:

  • ./index.md from a leaf file (api-reference/03.problems/*.md/docs/api-reference/problems/, 35 links)
  • ../index.md from an index file (triggers/, migration-guide/v2.0.0/, task-runners/, scripts/, cicd/, rbac/, 6 links)

The remark link replacer moves out of astro.config.mjs into src/markdown/remark/resolve-doc-link.ts and resolves those two shapes to the directory segment explicitly (../problems, ../triggers). Other relative links keep their previous resolution, which the tests pin.

@github-actions

github-actions Bot commented Sep 16, 2026

Copy link
Copy Markdown
Contributor

☁️ Cloudflare Worker Preview Deployed!

🔗 https://ks-fix-301-docs-index-links-docs.kestra-io.workers.dev
🔗 https://1e1aad34-docs.kestra-io.workers.dev

🔦 Lighthouse Benchmark

Tested on 2026-09-16 17:14 UTC  ·  links point to https://ks-fix-301-docs-index-links-docs.kestra-io.workers.dev
Compared against main baseline from 2026-09-16
Runner CPU index per shard: 2490, 2489, 2957, 2289 (baseline: 2334, deltas hidden on 5 page(s))

Scores (0–100, higher is better)

Page Performance Accessibility Best Practices SEO
Home 90 84 77 92
Get Started 61 83 77 100
Pricing 97 92 77 100
Enterprise 95 83 77 100
Cloud 93 80 77 100
About Us 86 91 77 100
Docs Landing 88 88 77 92
Contribute to Kestra (simple docs) 92 88 77 92
Flow (full featured docs) 88 90 77 92
Blog Index 66 91 77 100
Blog Post (sample) 92 88 77 100
VS Page (sample) 96 88 77 100
Plugins Landing 86 81 77 92
Plugin Page (sample) 91 88 77 100
Plugin Debug Page (sample) 94 🟢 +15 88 77 100
Plugin Debug Return Page (sample) 87 88 77 100
Blueprints Landing 84 91 77 100
Blueprint Audit Logs CSV Export 90 92 77 100

Core Web Vitals (lower is better)

Page LCP FCP TBT CLS Speed Index
Home 1.55 s 0.69 s 127 ms 0.000 1.64 s
Get Started 2.01 s 0.62 s 1053 ms 0.000 1.07 s
Pricing 1.07 s 0.64 s 108 ms 🔻 0.000 🟢 0.99 s
Enterprise 1.38 s 0.66 s 79 ms 0.003 1.12 s
Cloud 1.64 s 0.68 s 73 ms 0.001 1.13 s
About Us 2.52 s 0.58 s 69 ms 0.000 1.05 s
Docs Landing 1.08 s 0.58 s 252 ms 🔻 0.001 1.33 s
Contribute to Kestra (simple docs) 1.12 s 0.60 s 196 ms 0.000 0.88 s
Flow (full featured docs) 1.86 s 🔻 0.65 s 142 ms 0.002 1.32 s
Blog Index 16.53 s 0.57 s 38 ms 0.000 🟢 3.77 s
Blog Post (sample) 1.82 s 0.56 s 52 ms 0.000 0.92 s
VS Page (sample) 1.28 s 0.67 s 89 ms 0.000 🟢 0.98 s
Plugins Landing 1.76 s 1.17 s 88 ms 0.000 2.07 s
Plugin Page (sample) 1.37 s 0.96 s 103 ms 0.000 1.87 s
Plugin Debug Page (sample) 1.00 s 0.54 s 173 ms 🟢 0.000 0.94 s
Plugin Debug Return Page (sample) 1.06 s 0.52 s 239 ms 0.000 1.60 s
Blueprints Landing 2.33 s 0.82 s 126 ms 🔻 0.005 1.47 s
Blueprint Audit Logs CSV Export 1.13 s 0.70 s 188 ms 0.000 1.50 s
Legend

🟢 improved  ·  🔻 regressed  ·  (blank) no significant change
Score threshold: ±10 pts  ·  Metric threshold: ±30% of baseline

Median of repeated runs: Home x5, About Us x3, Docs Landing x5, Flow (full featured docs) x3, Plugins Landing x3, Blueprints Landing x3. A single run of these swings 20+ points between runners.
The sample is measured across 4 parallel runners, so each page carries its own CPU index (Lighthouse's benchmarkIndex). Lighthouse does not normalise for host CPU, so a page's deltas are hidden when its runner differs from the baseline's by more than 10%.

View full Lighthouse HTML report for a page

Full per-page Lighthouse Results (LHR) are attached as the lhr-reports-shard-* artifacts on this run. Download and unzip one, then open https://googlechrome.github.io/lighthouse/viewer/ and drop the <page>-lhr.json file into the page to see every audit, opportunity, and diagnostic.

@vfanucci
vfanucci requested a review from iitzIrFan September 18, 2026 12:59

@iitzIrFan iitzIrFan left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Approving — the resolution logic checks out.

I ran the old astro.config.mjs replacer and the new resolveRelativeDocLink side by side over every relative markdown link in src/contents/** (~1500 links, all collections, since the markdown processor is global). Exactly 41 outputs change: the 35 ./index.md links under api-reference/03.problems/ and the 6 ../index.md* links in index files. Everything else resolves identically, so no collateral change to blogs/orchestration/resources.

I then resolved each rewritten href against its own page URL (computed with the same generateId the content loader uses) and matched it against the set of doc ids — all of them land on an existing page, including the two that could have gone wrong in generateId: v2.0.0 survives intact (../v2.0.0) and 16.scripts loses only its ordering prefix (../scripts).

The climb = ups + 1 for leaf files vs ups for index files is right, since generateId only strips ordering prefixes and never collapses a segment — URL depth mirrors filesystem depth. astro sync loads the config fine, path is still used after the generateId import was dropped, and the new test is picked up by vitest's src/**/*.test.ts include.


One non-blocking nit, in content rather than in this diff:

src/contents/docs/05.workflow-components/07.triggers/05.realtime-trigger/index.md:11

Most Kestra [triggers](./index.md) poll external systems at a fixed interval

./index.md from an index file means "this directory's index", so it resolves to realtime-trigger — the page linking to itself. The prose means the parent triggers page, so it should be ../index.md, which this PR now resolves to ../triggers.

It's a pre-existing typo and the preserved ./index.md-from-an-index-file branch is correct as written (the test at resolve-doc-link.test.ts:44 pins the right behaviour). But since this PR is about making index links land on the right page, it's the one index link in the corpus still pointing at the wrong one — a natural one-line addition here, or a follow-up if you'd rather keep the diff to the resolver.

@iitzIrFan

Copy link
Copy Markdown
Member

Concrete version of the nit from my review, if you want to fold it in — and a correction: I wrote ../index.md above, but the parent index is index.mdx, so it's ../index.mdx.

src/contents/docs/05.workflow-components/07.triggers/05.realtime-trigger/index.md:11

-Most Kestra [triggers](./index.md) poll external systems at a fixed interval, which works well for batch processing.
+Most Kestra [triggers](../index.mdx) poll external systems at a fixed interval, which works well for batch processing.

That matches what the sibling page already does — 06.mcp-tool-trigger/index.md:88 links to ../index.mdx#trigger-common-properties.

link resolves to
now ./index.md realtime-trigger/docs/workflow-components/triggers/realtime-trigger (itself)
after ../index.mdx ../triggers/docs/workflow-components/triggers

Worth noting the fix depends on this branch: on main, ../index.mdx from an index file resolves to . — the 301 you're removing here. So it only lands correctly once this PR is in, which is why it seemed a natural addition rather than a separate commit. Still non-blocking either way.

This branch was successfully deployed

1 active deployment
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: To review

Development

Successfully merging this pull request may close these issues.

2 participants