Conversation
☁️ Cloudflare Worker Preview Deployed!🔗 https://ks-fix-301-api-markdown-links-docs.kestra-io.workers.dev 🔦 Lighthouse Benchmark
Scores (0–100, higher is better)
Core Web Vitals (lower is better)
Legend🟢 improved · 🔻 regressed · (blank) no significant change 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. View full Lighthouse HTML report for a pageFull per-page Lighthouse Results (LHR) are attached as the |
iitzIrFan
left a comment
There was a problem hiding this comment.
The hook placement is correct and all API-sourced markdown paths go through it (schema descriptions via PluginsMarkdownRender, plugin long descriptions via OneHeader.astro, blueprint bodies). Tests, astro check and lint pass locally. Every to in the literal list exists in src/contents/docs.
The rewrite logic is wrong in one respect. docs.yml is a 404-fallback table (only applied by notFoundRedirect) that uses regexp anchoring for specificity. toLiteralRedirects treats exact-only rules (.../?$) and collapse rules (.../.*) the same as prefix rules. Verified by running rewriteRedirectedHref against the real file:
/docs/getting-started/contributing => /docs/quickstart (site: /docs/contribute-to-kestra)
/docs/getting-started/terraform => /docs/quickstart (site: /docs/terraform)
/docs/administrator-guide/configuration/enterprise-edition/secrets => /docs/configuration (site: /docs/concepts/secret)
/docs/plugin-developer-guide/task => /docs/plugin-developer-guide (live page, rewritten to its index)
The last one comes from line 109 ("/docs/plugin-developer-guide/.*" -> "/docs/plugin-developer-guide") and affects all eleven live children of that section. MarkdownRenderer also renders docs child cards, changelog bodies and AI chat answers, so this is not limited to plugin pages.
Blocking
src/markdown/redirectedLinks.ts: keep exactness. Return{ from, to, prefix }fromtoLiteralRedirects, withprefixtrue only for(/.*)?,(.*)?,(.*)and.*tails, and only usestartsWithinresolveLiteralRedirectwhen it is set. Test on the real file:/docs/getting-started/contributing->/docs/contribute-to-kestra.src/markdown/redirectedLinks.ts: skip rules wherefrom === to(a self-targeting prefix rule can only be a fallback). Test:/docs/plugin-developer-guide/taskunchanged.
Non-blocking
- Rule 181 has a fragment in
to; the original suffix is appended after it:/docs/how-to-guides/cloudflare-r2#setup->.../runtime-and-storage#cloudflare-r2#setup. Let the rule's fragment win and keep the query before it. - Add a test that
parseRedirectRules(raw)deep-equalsYAML.parse(raw)fordocs.yml. The line parser silently drops single-quoted or unquoted scalars, and nothing would catch that today. - Trailing-slash stripping (
/docs/x/->/docs/x) happens with no matching rule. Fine fortrailingSlash: "never", but undocumented and untested.
Out of scope
- API text also links plugins with the old
/plugins/plugin-aws/tasks/s3/...shape (seen inUploadFiles); those still 301 viaredirectAlias. docs.ymlhas duplicate and conflicting rules (how-to-guides/cephtwice with different targets,administrator-guide/configurationthree times).
Plugin pages render markdown that comes from the API (schema property descriptions, plugin long descriptions, blueprint bodies). Those texts link to docs pages by URLs that have since moved, so every such link is a 301 for readers and a redirected inlink for crawlers.
The Screaming Frog crawl of 16 Sept lists ~400 of them, from three links repeated in the plugin templates:
/docs/developer-guide/namespace-files→/docs/concepts/namespace-files(210 links)/docs/workflow-components/plugin-defaults→/docs/migration-guide/v2.0.0/plugin-defaults-removed(112)/docs/configuration-guide/plugins→/docs/configuration/plugins-and-execution(74)The marked instances used by the markdown renderers now rewrite internal
/docs/...links with the literal rules ofsrc/contents/redirects/docs.yml(rules with capture groups or wildcards inside the path are skipped: they are 404 fallbacks and would rewrite live pages), and normalise/plugins/...links (lowercase, no.md). The rules file is read by line to keep the YAML library out of the hydrated islands.Unit tests cover the rule filtering, the rewrite, and both marked instances.