Skip to content

Make docs section URLs actually redirect - #5617

Merged
dimitrieh merged 1 commit into
mainfrom
docs/redirect-route-rules
Sep 10, 2026
Merged

Make docs section URLs actually redirect#5617
dimitrieh merged 1 commit into
mainfrom
docs/redirect-route-rules

Conversation

@dimitrieh

@dimitrieh dimitrieh commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

Description

Docs section URLs do not redirect. /docs/install/ answers 200 with a <meta http-equiv="refresh"> page instead of a 301. A reader still lands on the right page. A crawler or an inbound link gets nothing, because no redirect status is ever sent. This is live on flowfuse.com today.

Why it happens. The docs page component redirects while rendering. The prerenderer writes that render out as a static HTML file. Netlify serves a matching static file before it consults a redirect rule, so the rule never runs.

What this changes. docs-source now reads the layout: redirect frontmatter at build time and turns it into a Nitro route rule. Those routes also stay out of the prerender list, so no stub file is written that could win over the rule. The netlify preset compiles the rules into dist/_redirects, and they resolve at the edge.

The prerender filter matches any rule that redirects, not only the generated ones. redirects.ts maps a few underscored docs slugs to hyphenated names, and a docs tree still carrying the old filenames used to prerender a stub that beat the rule.

The URLs this affects:

URL Redirects to
/docs/user/ /docs/user/introduction
/docs/cloud/ /docs/cloud/introduction
/docs/admin/ /docs/admin/introduction
/docs/install/ /docs/install/introduction
/docs/hardware/ /docs/hardware/introduction
/docs/migration/ /docs/migration/introduction
/docs/contribute/ /docs/contribute/introduction
/docs/device-agent/ /docs/device-agent/introduction
/docs/device-agent/install/ /docs/device-agent/install/overview
/docs/admin/hardening/ /docs/admin/hardening/kubernetes/
/docs/admin/licensing/ /pricing/
/docs/community-support/ Node-RED forum

The stub pages have to stay. Deleting them is not an alternative fix. There is no Netlify rule for any of these paths, so the frontmatter is the only place the redirect is declared. The same frontmatter is also the docs nav definition: each stub carries the navGroup, navGroupOrder, navTitle and navOrder its whole section is grouped and labelled by, and the leaf pages do not. #5551 dropped the stubs from the sidebar and d1a2528 had to put that metadata back.

Related Issue(s)

None.

Checklist

  • I have read the contribution guidelines
  • I have considered the performance impact of these changes
  • Suitable unit/system level tests have been added and they pass
  • Documentation has been updated
  • For blog PRs, an Art Request has been created (instructions)

@netlify

netlify Bot commented Aug 17, 2026

Copy link
Copy Markdown

Deploy Preview for flowforge-website ready!

Name Link
🔨 Latest commit 46ddeec
🔍 Latest deploy log https://app.netlify.com/projects/flowforge-website/deploys/6aa29d84f21b660008ad6a5b
😎 Deploy Preview https://deploy-preview-5617--flowforge-website.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
Lighthouse
Lighthouse
1 paths audited
Performance: 66 (🟢 up 11 from production)
Accessibility: 96 (no change from production)
Best Practices: 100 (no change from production)
SEO: 92 (no change from production)
PWA: -
View the detailed breakdown and full score reports

To edit notification comments on pull requests, go to your Netlify project configuration.

@ZJvandeWeg

Copy link
Copy Markdown
Member

He @dimitrieh, if we remove the frontmatter, would that also resolve this issue? As we have a redirect on Netlify in that case, we can just remove those files altogether?

The 12 docs pages carrying `layout: redirect` redirected from inside the page
component. The prerenderer turns that into an HTML file holding a
`<meta http-equiv="refresh">`, and Netlify serves a matching static file in
preference to a non-forced redirect rule, so /docs/install/ answered 200 with
a 116-byte stub and passed nothing on to /docs/install/introduction.

docs-source already walks the synced docs, so it now reads their frontmatter
and registers route rules, the same mechanism nuxt/redirects.ts uses for the
retired 11ty paths, and keeps those routes out of the prerender list so no stub
is written. The netlify preset compiles them into dist/_redirects, which
resolves them at the edge rather than in the function.

The prerender filter matches any route rule that redirects, not only the ones
generated here. nuxt/redirects.ts maps three underscored docs slugs to their
hyphenated names, and a docs tree still carrying the underscored filename
prerendered a stub that won against the rule. Verified against a full build:
those three stubs disappear and no meta-refresh HTML is left in dist.

Link checker reports the same 519 warnings and 0 errors as before the change.
@dimitrieh
dimitrieh force-pushed the docs/redirect-route-rules branch from d86a9e5 to 46ddeec Compare September 10, 2026 12:07
@dimitrieh dimitrieh changed the title Serve docs redirects as 301s instead of a meta-refresh stub Make docs section URLs actually redirect Sep 10, 2026
@dimitrieh

Copy link
Copy Markdown
Contributor Author

if we remove the frontmatter, would that also resolve this issue?

No. That frontmatter is also what builds the docs sidebar. Each of these stub pages carries navGroup, navGroupOrder, navTitle and navOrder. The leaf pages don't: docs/user/introduction.md only has navTitle and navOrder. So docs/user/README.md is the only thing saying /docs/user belongs under "FlowFuse User Manuals", first in the list.

We tried this already. #5551 dropped the stubs from the sidebar. d1a2528 had to put the metadata back, because sections fell into "Other", got named after their raw path ("user", "admin"), and three groups disappeared.

As we have a redirect on Netlify in that case, we can just remove those files altogether?

There is no Netlify redirect for these paths. I checked every one. None is in nuxt/redirects.ts, and netlify.toml only has the flowforge.com to flowfuse.com rules. The frontmatter is the only place these redirects exist. Delete the files and the URLs 404.

Regardless, the bug is still live. Every one of those paths answers 200 with a meta refresh on flowfuse.com right now. Rebased on main and rewrote the description, so this is ready for another look.

@dimitrieh

Copy link
Copy Markdown
Contributor Author

Before and after

Probed both sides with the same command on 2026-09-10, after the rebase onto main:

curl -s -o /dev/null -w '%{http_code} %{redirect_url}' <host><path>

Before is live flowfuse.com. After is the deploy preview for this branch. Every path targets the same place on both sides, so the target is listed once.

URL Before After Target
/docs/user/ 200, meta refresh 301 /docs/user/introduction
/docs/cloud/ 200, meta refresh 301 /docs/cloud/introduction
/docs/admin/ 200, meta refresh 301 /docs/admin/introduction
/docs/install/ 200, meta refresh 301 /docs/install/introduction
/docs/hardware/ 200, meta refresh 301 /docs/hardware/introduction
/docs/migration/ 200, meta refresh 301 /docs/migration/introduction
/docs/contribute/ 200, meta refresh 301 /docs/contribute/introduction
/docs/device-agent/ 200, meta refresh 301 /docs/device-agent/introduction
/docs/device-agent/install/ 200, meta refresh 301 /docs/device-agent/install/overview
/docs/admin/hardening/ 200, meta refresh 301 /docs/admin/hardening/kubernetes/
/docs/admin/licensing/ 200, meta refresh 301 /pricing/
/docs/community-support/ 200, meta refresh 301 Node-RED forum (off-site)

Before, no path sent a Location header at all. The redirect only existed as <meta http-equiv="refresh" content="0; url=..."> inside a 200 response. After, every path sends a real Location and no HTML body.

Sidebar regression check

The same stub pages define the docs nav, so I checked the sidebar still builds on the preview at /docs/user/introduction/. All group headings render (FlowFuse User Manuals, FlowFuse Cloud, FlowFuse Self-Hosted, Device Agent, Contributing, Support) and no section fell into an Other group.

Checks

test_website / Build and check passes, including the link checker. The new nuxt/lib/docs-redirects.test.mjs covers the frontmatter parsing and the prerender filter, and passes.

@dimitrieh
dimitrieh merged commit d565288 into main Sep 10, 2026
7 checks passed
@dimitrieh
dimitrieh deleted the docs/redirect-route-rules branch September 10, 2026 14:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants