Skip to content

node-red: serve /node-red/ from Nuxt - #5793

Merged
ZJvandeWeg merged 13 commits into
mainfrom
nuxt/node-red
Sep 25, 2026
Merged

ZJvandeWeg merged 13 commits into
mainfrom
nuxt/node-red

Conversation

@dimitrieh

@dimitrieh dimitrieh commented Sep 11, 2026 •

Copy link
Copy Markdown
Contributor

Description

Moves /node-red/ to Nuxt.

The certified nodes grid is derived from the two certified catalogue feeds the integrations code already fetches, instead of a second copy of that fetch. Names come from the package id, so acronyms print as OPC UA and RTSP rather than lowercase slugs.

Related Issue(s)

Part of #5777

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)

Note

Serve /node-red/ from Nuxt and remove legacy 11ty page

Macroscope summarized 8992cd1.

@netlify

netlify Bot commented Sep 11, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for flowfuse-website ready!

Name Link
🔨 Latest commit 8992cd1
🔍 Latest deploy log https://app.netlify.com/projects/flowfuse-website/deploys/6ab56722d1bd84000977bf52
😎 Deploy Preview https://deploy-preview-5793--flowfuse-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: 45 (🟢 up 9 from production)
Accessibility: 95 (no change from production)
Best Practices: 92 (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.

@dimitrieh

Copy link
Copy Markdown
Contributor Author

@dimitrieh

Copy link
Copy Markdown
Contributor Author

Rebased on main. scripts/gen-site-art.py is now scripts/gen-site-art.mjs and nuxt/lib/rich-text.mjs is gone, both per the review on #5784.

Three fixes from the review pass over the whole migration:

  • A four-line Nunjucks {# ... #} comment survived inside the Vue <template>. Vue has no {# #} syntax, so it was a static text node and would have printed verbatim above the certified-nodes section on the live page. Moved into <script setup> beside the fetch it describes (it was also stale: it named src/_data/certifiedNodes.js, which this PR retires).
  • legacy.ts still carried normalised !== '/node-red' and a comment saying /node-red "keeps falling through to 11ty: it is still a marketing page there". This PR puts /node-red in NUXT_PREFIXES and deletes src/node-red/index.njk, so the guard was dead and the comment inverted. Both gone.
  • fetchCatalogueFeed's bare catch { return [] } said nothing. /node-red/ is prerendered now, so a transient failure on either certified-nodes feed at build time bakes a page with that whole section missing, and it stays missing until the next deploy. Still degrades to a hidden section rather than a broken page, but the build log now names the feed that failed.

Also dropped a page-comment bullet claiming the 11ty layout emitted an empty second <h1>: layouts/page.njk guards the hero on {% if (title and not hideTitle) %} and src/node-red/index.njk sets no title, so no heading was emitted at all.

@dimitrieh

Copy link
Copy Markdown
Contributor Author

Rebased onto main. The conflicts in nuxt/server/middleware/legacy.ts and nuxt/nuxt.config.ts are resolved and CI is green.

The rest of that prefix (the core-node reference and the hardware guides)
already moved into /docs/; this was the last page under it.

The certified-nodes grid was driven by src/_data/certifiedNodes.js, whose own
comment said it "deliberately duplicates the fetch rather than importing across
the boundary" while the site was mid-migration. That boundary is gone: the page
reads /api/certified-nodes, which derives the list from the same two feeds
nuxt/utils/integrations.ts already fetches for /integrations/. The data file
goes away with 11ty.

fetchCatalogue() could not be used directly: it merges the certified feeds with
the npm catalogue and the flowfuse-nodes feed, and tags that last group
`certified` too, so filtering its result by tier returned 9 nodes where the two
certified catalogues hold 5. fetchCertifiedCatalogues() is exported for exactly
those two. Display names are title-cased from the id rather than taken from
`name`, which normalizeCatalogueModule fills with the id's last segment when the
feed carries none - as all of these do - so the cards read "Modbus" and "RTSP"
rather than "modbus" and "rtsp".

BlogFaq's renderer gained ordered and unordered list support, unit tested. Two
answers here carried <ol>/<ul> markup under `| safe`, and a list cannot sit
inside the <p> the renderer used to emit, so the component now renders a list
block bare.

Two malformed bits of markup fixed: the hero opened a stray <p> with no closing
tag (HTML auto-closes it, Vue's compiler does not), and the page rendered a
second, empty <h1> from layouts/page.njk's `nohero` branch.

Verified against production, with no structural differences.
@dimitrieh

Copy link
Copy Markdown
Contributor Author

Rebased onto main. The conflicts in nuxt/server/middleware/legacy.ts and nuxt/nuxt.config.ts are resolved and CI is green.

@dimitrieh

Copy link
Copy Markdown
Contributor Author

Nothing to change here, one note. /node-red was never added to NUXT_PREFIXES in nuxt/server/middleware/legacy.ts, so npm run dev keeps proxying it to 11ty and serves the old page. That middleware returns early unless NODE_ENV === 'development', which is why CI and the deploy preview both look correct and this went unnoticed.

It was flagged on three of these PRs and is actually missing on eight, so it is fixed in one place in #5815 rather than eight conflicting edits to the same file. Merge that one after this, since registering a section before its pages land points dev at a Nuxt route that does not exist yet.

Without the prefix the dev middleware keeps proxying to 11ty, so npm run dev
shows the old page. The middleware returns early unless NODE_ENV is development,
which is why CI and the deploy preview both looked correct.

Its index is a Nuxt page now, so the carve-out that deliberately kept just
/node-red on 11ty while /node-red/* went to Nitro is no longer needed.
@dimitrieh

Copy link
Copy Markdown
Contributor Author

Correction to my earlier comment: #5815 is closed, the registration belongs in each migration PR instead. Pushed here. It also drops the carve-out that kept /node-red itself on 11ty, now that its index is a Nuxt page.

The nine glyphs the page names are stock Heroicons, so the keys in the two data
lists become iconify names and the call sites become <UIcon>, each carrying its
own size since the mask span has no intrinsic ratio.

certified-node is the exception and does not become a <UIcon>: it already has
IntegrationsCertifiedIcon, and .certified-icon sets fill and stroke and overrides
the size inside .certified-eyebrow, none of which reach a mask span. Reusing that
component keeps the rendering identical.
@dimitrieh

Copy link
Copy Markdown
Contributor Author

Cross-PR pass over the four patterns. Two applied:

  • Custom icon files. The nine glyphs are stock Heroicons, so the keys in LOW_CODE and WHY are iconify names now and the call sites are <UIcon>. SiteArt.vue, siteArt.ts and gen-site-art.mjs are gone. Sizes are explicit per call site, since the mask span has no intrinsic ratio and both wrappers are w-8 h-8.
  • legacy.ts. /node-red registered. Its index is a Nuxt page now, so the carve-out that deliberately kept just /node-red on 11ty while /node-red/* went to Nitro is gone too.

One deliberate exception: certified-node does not become a <UIcon>. It is Heroicons check-badge solid, but IntegrationsCertifiedIcon already renders it and .certified-icon styles it with fill and stroke plus a size override inside .certified-eyebrow, none of which apply to a mask span. Reusing that component keeps it rendering as it does today.

No useScrollToAnchor here, and no layouts this PR makes dead relative to main.

@dimitrieh dimitrieh mentioned this pull request Sep 16, 2026
5 tasks
# Conflicts:
#	nuxt/nuxt.config.ts
#	nuxt/server/middleware/legacy.ts
@dimitrieh

Copy link
Copy Markdown
Contributor Author

Conflicts resolved, main is merged in. Same shape as the other migration PRs: the registry files take the union, so NUXT_PREFIXES and the prerender list keep both sides and this PR's own route drops out of the "still on 11ty" comment.

# Conflicts:
#	nuxt/server/middleware/legacy.ts
# Conflicts:
#	nuxt/server/middleware/legacy.ts
@ZJvandeWeg

Copy link
Copy Markdown
Member

@macroscope-app review

@macroscopeapp

macroscopeapp Bot commented Sep 23, 2026

Copy link
Copy Markdown
Contributor

Manual reviews triggered for commit 3613294:

All prior checks · these links stay valid even if you push more commits.

@macroscopeapp

macroscopeapp Bot commented Sep 23, 2026

Copy link
Copy Markdown
Contributor

Review started; results will be posted when complete.

@macroscopeapp

macroscopeapp Bot commented Sep 23, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This replaces the live /node-red/ serving path with a substantial Nuxt page, new prerendering behavior, and a server-side certified-node data endpoint. The migration changes multiple runtime and data-loading boundaries and has no new tests in the PR, so the scope merits human review.

Not approved because:

  • automatic approval is not enabled for this workspace

A repo admin can enable approvability here. You can add or adjust custom eligibility rules. Learn more.

# Conflicts:
#	nuxt/server/middleware/legacy.ts
@dimitrieh

Copy link
Copy Markdown
Contributor Author

@Yndira-E @KristopherLeads PR conflicts are resolved.

@ZJvandeWeg

Copy link
Copy Markdown
Member

@dimitrieh They are back :) But also check out: #5793 (comment)

# Conflicts:
#	nuxt/server/middleware/legacy.ts
The name overrides, the one-card-per-collection split, the docs fallback and the sort
move out of the Nitro handler into nuxt/lib/certified-nodes.mjs, so `npm test` covers
them. The handler keeps the fetch and reuses COLLECTION_LABELS from types/integrations
instead of its own copy of the same map.
main's /platform/device-agent/ rebuild replaced its install block with
<DeviceAgentInstallTabs> and deleted <DeviceAgentInstallCommands>, which /node-red/ still
renders. Keep that component as /node-red/'s own, as main's edit to the .njk include
("used by /node-red/") intended, and drop the "shared with /platform/device-agent/"
notes. The .njk include loses its last user with src/node-red/index.njk, so it goes too.
@ZJvandeWeg
ZJvandeWeg merged commit d33d9f5 into main Sep 25, 2026
9 checks passed
@ZJvandeWeg
ZJvandeWeg deleted the nuxt/node-red branch September 25, 2026 17:23
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.

2 participants