diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md index a625131613..693f8b12ef 100644 --- a/.claude/CLAUDE.md +++ b/.claude/CLAUDE.md @@ -260,6 +260,12 @@ Collection config: `src/customer-stories/customer-stories.json` | `layouts/story.njk` | Customer stories | | `layouts/nohero.njk` | General pages without hero | +## Redirects + +**Add new redirects to `nuxt/redirects.ts`, not `netlify.toml`.** Nuxt is the front door for every route now, so retired-route redirects are handled as native Nitro route rules (`{ redirect: { to, statusCode: 301 } }`) keyed by the old path. `netlify.toml`'s `[[redirects]]` blocks are legacy and reserved for edge-level concerns that predate Nuxt (domain aliasing: `flowforge.com`/`flowfuze.com`/`flowfuse.io` → `flowfuse.com`) — don't add page-to-page redirects there. + +This also covers old `/docs/**` paths left behind by a rename in `flowfuse/flowfuse`'s `docs/` tree (e.g. a doc file renamed to fix a `nuxt-link-checker` `no-underscores` warning) — add the old path here so bookmarks/indexed links 301 instead of 404ing once the rename ships. + ## Call-to-Action components **Nuxt only** — 11ty pages still use hand-written `` links; these components have no 11ty equivalent yet. diff --git a/nuxt/composables/useDocsNav.ts b/nuxt/composables/useDocsNav.ts index 28a62c66bd..51892bed01 100644 --- a/nuxt/composables/useDocsNav.ts +++ b/nuxt/composables/useDocsNav.ts @@ -25,6 +25,7 @@ export interface DocsNavPage { navOrder?: number | null navGroup?: string | null navGroupOrder?: number | null + redirect?: { to: string } | null } /** diff --git a/nuxt/lib/docs-nav.mjs b/nuxt/lib/docs-nav.mjs index 9304c2834f..c6ad114218 100644 --- a/nuxt/lib/docs-nav.mjs +++ b/nuxt/lib/docs-nav.mjs @@ -9,12 +9,18 @@ // restructuring the docs is a change in the docs repo alone. /** - * @param {Array<{path: string, title?: string|null, navTitle?: string|null, navOrder?: number|null, navGroup?: string|null, navGroupOrder?: number|null}>} pages + * @param {Array<{path: string, title?: string|null, navTitle?: string|null, navOrder?: number|null, navGroup?: string|null, navGroupOrder?: number|null, redirect?: {to: string}|null}>} pages */ export function buildDocsNav (pages) { const tree = {} - const sorted = [...pages].sort((a, b) => { + // A page whose only purpose is `redirect: { to }` (e.g. FlowFuse/flowfuse's + // docs/admin/licensing.md and docs/community-support.md) has no content of its own to + // link to from the sidebar. Rendering it as a nav entry means every single docs page + // gets flagged by nuxt-link-checker's `redirects` inspection, so it's left out. + const linkable = pages.filter(page => !page.redirect) + + const sorted = [...linkable].sort((a, b) => { const depthA = a.path.split('/').filter(Boolean).length const depthB = b.path.split('/').filter(Boolean).length return depthA - depthB diff --git a/nuxt/redirects.ts b/nuxt/redirects.ts index 9cde2803c7..32c9ebcfc1 100644 --- a/nuxt/redirects.ts +++ b/nuxt/redirects.ts @@ -91,6 +91,9 @@ export const redirects: Record = { '/certified-nodes/**': { redirect: { to: '/integrations/?certified=1', statusCode: 301 } }, '/llms-full.txt': { redirect: { to: '/llms.txt', statusCode: 301 } }, '/docs/install/local/': { redirect: { to: '/docs/install/introduction/', statusCode: 301 } }, + '/docs/install/email_providers/': { redirect: { to: '/docs/install/email-providers/', statusCode: 301 } }, + '/docs/admin/user_management/': { redirect: { to: '/docs/admin/user-management/', statusCode: 301 } }, + '/docs/install/kubernetes/aws_terraform/': { redirect: { to: '/docs/install/kubernetes/aws-terraform/', statusCode: 301 } }, '/cloud/': { redirect: { to: 'https://app.flowfuse.com/account/create/', statusCode: 301 } }, '/legal/terms/': { redirect: { to: '/terms/', statusCode: 301 } }, '/book-a-demo/': { redirect: { to: '/book-demo/', statusCode: 301 } }, diff --git a/src/blog/2024/07/how-to-setup-sso-ldap-for-the-node-red.md b/src/blog/2024/07/how-to-setup-sso-ldap-for-the-node-red.md index 9e88371612..bd21da9e82 100644 --- a/src/blog/2024/07/how-to-setup-sso-ldap-for-the-node-red.md +++ b/src/blog/2024/07/how-to-setup-sso-ldap-for-the-node-red.md @@ -278,7 +278,7 @@ Slappasswd -g ### Signing in Using SSO -To sign in using SSO, users of your self-hosted FlowFuse must have a FlowFuse account created with an email ID associated with the domain configured with SSO. For more information, refer to [creating users in FlowFuse](/docs/admin/user_management/#creating-new-users). +To sign in using SSO, users of your self-hosted FlowFuse must have a FlowFuse account created with an email ID associated with the domain configured with SSO. For more information, refer to [creating users in FlowFuse](/docs/admin/user-management/#creating-new-users). 1. Open your platform in the browser. Enter the username in the username/email field. 2. Click on "Login". diff --git a/src/blog/2024/07/how-to-setup-sso-saml-for-the-node-red.md b/src/blog/2024/07/how-to-setup-sso-saml-for-the-node-red.md index 357e3c3d10..3782b11964 100644 --- a/src/blog/2024/07/how-to-setup-sso-saml-for-the-node-red.md +++ b/src/blog/2024/07/how-to-setup-sso-saml-for-the-node-red.md @@ -136,7 +136,7 @@ Now that we have created the SAML app in the workspace, we need to update the Fl ### Signing in Using SSO -To sign in using SSO, users of your self-hosted FlowFuse must have a FlowFuse account created with an email ID associated with the domain configured with SSO. For more information, refer to [creating users in FlowFuse](/docs/admin/user_management/#creating-new-users). Additionally, the user must already be logged in with that email in the browser. +To sign in using SSO, users of your self-hosted FlowFuse must have a FlowFuse account created with an email ID associated with the domain configured with SSO. For more information, refer to [creating users in FlowFuse](/docs/admin/user-management/#creating-new-users). Additionally, the user must already be logged in with that email in the browser. 1. Open your platform in the browser, Enter the email address in the username/email field. 2. Click on "Login".