Skip to content

use-cases: serve /use-cases/ from Nuxt - #5780

Merged
Yndira-E merged 5 commits into
mainfrom
nuxt/use-cases
Sep 16, 2026
Merged

Yndira-E merged 5 commits into
mainfrom
nuxt/use-cases

Conversation

@dimitrieh

Copy link
Copy Markdown
Contributor

Description

Moves /use-cases/ to Nuxt. The six architecture pages become .vue pages; the two operational use-cases stay data-driven and render through pages/use-cases/[slug].vue.

FAQ answers now go through an escaping renderer rather than being printed raw.

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)

@netlify

netlify Bot commented Sep 11, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for flowfuse-website ready!

Name Link
🔨 Latest commit 507eefb
🔍 Latest deploy log https://app.netlify.com/projects/flowfuse-website/deploys/6aaa9ed9669bca0007603eee
😎 Deploy Preview https://deploy-preview-5780--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

Rebased on main (which now carries the six merged PRs from this set).

A review pass over the whole migration found three things here:

  • /use-cases/production-monitoring/ and /use-cases/shop-floor-communication/ render through [slug].vue over a data collection, so @nuxtjs/sitemap's static-route discovery cannot see them and content-urls.get.ts cannot either (it keys on path). They had also left sitemap-legacy.xml when their .njk files were deleted, so they were in neither sitemap. Added to sitemap.urls, reusing the same collector the prerender list uses.
  • /use-cases/it-ot-middleware/ lost px-3 md:px-12 and md:px-6 on two containers. The .njk carried both those and md:px-0; Tailwind emits padding utilities in ascending scale order, so the larger value was the winning rule and desktop side padding had gone to zero. Restored verbatim.
  • The <LiteYoutube> on /use-cases/edge-connectivity/ passed a title already ending in "- YouTube video", which the component appends again, so the accessible name read "... - YouTube video - YouTube video".

Also tidied the stale list in legacy.ts, which still named /webinars and /free-consultation as 11ty routes after they migrated, and the llms note that named sections this set moves.

@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.

Comment thread nuxt/composables/useScrollToAnchor.ts Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Removed. The anchor keeps its href="#whitepapers" and the site-wide scroll-behavior: smooth in style.css animates the jump, so the composable was only restating the default. That file survives the teardown as nuxt/assets/css/style.css, so the behaviour does not go away with src/.

// already falls through to the 11ty proxy by default). Remove entries here as they migrate:
// /about, /blueprints, /careers, /community, /events
// /free-consultation, /industries, /landing, /node-red, /partners, /platform,
// /use-cases, /webinars

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@dimitrieh this needs to be added to the NUXT_PREFIXES or it won't render the pages on dev mode

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Added /use-cases to NUXT_PREFIXES. It also needed a /whitepaper/images/ carve-out, which is the cause of the broken covers you flagged separately.

@@ -1,6 +0,0 @@
{
"layout": "use-case",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@dimitrieh remember to remove the unused layouts

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Deleted use-case.njk along with its alias in .eleventy.js. Checked across every open migration branch rather than just this one, since each was cut from main independently: the only consumers were in src/use-cases/, which this PR removes.

@@ -1,289 +0,0 @@
---
layout: solution

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@dimitrieh I'd say this layout is dead code too

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Agreed, solution.njk is dead too. It and its .eleventy.js alias are gone, same check as the other layout.

]

const WHITEPAPERS = [
{ title: 'Accelerating Innovation in Manufacturing with FlowFuse', image: '/whitepaper/images/whitepaper-manufacturing.png', alt: 'Photo of a manufacturing company with a worker holding a laptop', link: '/whitepaper/accelerating-innovation-in-manufacturing-with-flowfuse/' },

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@dimitrieh The whitepaper images are not rendering on local

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed, and it was a dev-only fault rather than a bad path. The covers are at /whitepaper/images/..., /whitepaper is in NUXT_PREFIXES, but the files are still in src/whitepaper/images/ and only reach nuxt/public through the 11ty passthrough in a production build. So dev answered from Nuxt and 404d while the deploy preview was fine. Added the carve-out /resources/images/ and /vs/images/ already have.

@dimitrieh

Copy link
Copy Markdown
Contributor Author

Pushed:

  • use-case.njk and solution.njk deleted with their aliases in .eleventy.js. Nothing referenced either once src/use-cases/ went, checked across all the open migration branches, not just this one.
  • The scroll composable is gone and the anchor is plain again. The site-wide scroll-behavior: smooth in style.css already animates it, and that file survives the teardown as nuxt/assets/css/style.css.

Two things from this review moved to #5815 instead, because they are edits to legacy.ts and doing them per branch would just conflict eight ways: the /use-cases registration, and the whitepaper covers not rendering locally. That second one is the same cause, /whitepaper is a Nuxt prefix while the images are still in src/whitepaper/images/, so dev needs the carve-out /vs and /resources already have. Merge 5815 after this.

@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 carries the /whitepaper/images/ carve-out, which is what makes the whitepaper covers render locally.

@dimitrieh dimitrieh mentioned this pull request Sep 16, 2026
5 tasks
@dimitrieh
dimitrieh requested a review from Yndira-E September 16, 2026 09:55
Comment thread nuxt/composables/useCaseIcon.ts Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@dimitrieh why not assign the real Heroicons name directly in each .yml instead of transforming the old 11ty icon names through a new useCaseIcon.ts? Feels like we're carrying over an 11ty pattern we're trying to get away from.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Agreed, done. The .yml now names the glyph in full (i-heroicons-chart-bar-square) and <UIcon> resolves it directly; useCaseIcon.ts is gone.

It was also the convention already on main: every icon: key under nuxt/content/ is a full name. And this PR was inconsistent with itself, since pages/use-cases/uns.vue already passed feature.icon straight to <UIcon>.

Worth noting what the mapper was buying, since dropping it is a real trade: it fell back to a neutral dot for an unknown key. Now an unresolvable name renders nothing. That is the better failure, because it is visible in review instead of looking deliberate. nuxt/utils/navIcons.ts is the same pattern one layer over, and it fails silently in exactly that way: /vs/kepware/ and /vs/litmus/ name arrows-pointing-out and link, neither is in the registry, and NavIcon renders nothing, so both pages are missing an icon on live right now. Both keys are added in #5781.

dimitrieh added a commit that referenced this pull request Sep 16, 2026
Marketing retired Aerospace Components, Aviation & Aerospace, Electronics &
Appliances, Renewables, Semiconductors, Food & Beverage and Life Sciences.
/industries/automotive/ stays.

All seven were live and indexed, so the URLs 301 to /industries/ rather than
404ing. Their content, the [slug].vue route that served them, the seven
components/industry/ bands, the `industries` collection and its schema, the
sitemap and prerender entries and ~40 images all go with them, since the seven
.yml files were their only consumers.

The header dropdown and the footer group lose the same seven links, so nothing
in the chrome points at a redirect.

navIcons keeps two of the keys this branch added: /vs/kepware/ and /vs/litmus/
name `arrows-pointing-out` and `link` in content merged with #5783, but neither
was ever added to the registry, so NavIcon renders nothing for them on main
today. Both pages show one icon fewer than /vs/ignition/ on live.

components/use-case/Card.vue goes back to #5780, which adds the same file and is
the only branch still using it.
dimitrieh added a commit that referenced this pull request Sep 16, 2026
Marketing retired Aerospace Components, Aviation & Aerospace, Electronics &
Appliances, Renewables, Semiconductors, Food & Beverage and Life Sciences.
/industries/automotive/ stays.

All seven were live and indexed, so the URLs 301 to /industries/ rather than
404ing. Their content, the [slug].vue route that served them, the seven
components/industry/ bands, the `industries` collection and its schema, the
sitemap and prerender entries and ~40 images all go with them, since the seven
.yml files were their only consumers.

The header dropdown and the footer group lose the same seven links, so nothing
in the chrome points at a redirect.

navIcons keeps two of the keys this branch added: /vs/kepware/ and /vs/litmus/
name `arrows-pointing-out` and `link` in content merged with #5783, but neither
was ever added to the registry, so NavIcon renders nothing for them on main
today. Both pages show one icon fewer than /vs/ignition/ on live.

components/use-case/Card.vue goes back to #5780, which adds the same file and is
the only branch still using it.
@dimitrieh
dimitrieh requested a review from Yndira-E September 16, 2026 11:28
@Yndira-E

Copy link
Copy Markdown
Contributor

@dimitrieh let's hide the Common in these industries section for now, new pages are coming and we can bring it back when those are live

dimitrieh and others added 5 commits September 16, 2026 15:47
9 routes (the listing plus 8 use cases) move off 11ty. The group used three
different 11ty layouts, and the port keeps that split rather than flattening it:

- The two operational use-cases (the ones declaring `values:`) were pure
  frontmatter with no template body, which layouts/use-case.njk rendered as a
  fixed set of optional blocks. They become a `useCases` data collection plus
  one component per block under components/use-case/, rendered by
  pages/use-cases/[slug].vue - the same shape the application guide uses.
- The six architecture pages had real markup bodies, so they stay hand-written
  Vue pages. Each keeps a metadata-only collection entry so /use-cases/ still
  builds its cards from one place instead of a hand-maintained list.

layouts/use-case.njk's legacy `gap`/`workflow`/`outcomes` fall-back is dropped:
no remaining page used it, and it rendered visible "Placeholder copy" text.

Shared pieces extracted rather than repeated: UseCaseCard (the listing and
components/use-case-links.njk rendered identical markup), UseCaseClosingCta
(the layout and the listing differ only in the lead CTA, so that is a prop),
UseCaseSolutionHero, and useScrollToAnchor for smooth-scroll.njk's global
function. NavIcon gained a `size` prop so it covers ffIconLg as well as
navoption, and four icon keys page content asks for by name.

/use-cases/mes/, /scada/ and /uns/ each render TWO <h1> in production - one from
layouts/page.njk's `nohero` branch and one from the page itself, identical text
on /scada/. Only the page's own heading survives.

Page art moves into nuxt/public/images/, where the already-ported pages keep
theirs; Vite resolves a literal absolute src at build time, so an uncopied image
breaks the route's client chunk rather than just 404ing the image. Thumbnails
pointing into /blog/** and /whitepaper/** stay put and move at teardown.

Verified all 9 against production: H1s, heading outline, in-page CTA
destinations and HubSpot form mounts match, the h1 differences above excepted.
use-case.njk and solution.njk had no callers left once src/use-cases/ went, so
they and their layout aliases in .eleventy.js go with them.

The in-page anchor drops its JS handler: the site-wide scroll-behavior: smooth
in style.css already animates it, so the composable only restated the default.
Without the prefix the dev middleware keeps proxying to 11ty, so npm run dev
shows the old page while CI and the deploy preview look right: the middleware
returns early unless NODE_ENV is development, so nothing else exercises it.

The whitepaper covers this page links to live in src/whitepaper/images/ and only
reach nuxt/public through the 11ty passthrough in a production build, so dev
needs the same carve-out /resources and /vs already have.
The composable existed only to translate the 11ty include names
(src/_includes/components/icons/<name>.svg) into Iconify names at render time.
Content that is authored for Nuxt can just say i-heroicons-chart-bar-square, so
the .yml now carries the full name and <UIcon> resolves it directly.

This is the convention already on main: every icon: key under nuxt/content/ is
a full name (i-lucide-workflow and friends). This PR was inconsistent with
itself too, since pages/use-cases/uns.vue already passed feature.icon straight
to <UIcon>.

Losing the mapper also loses its fallback glyph for an unknown key, which is
the better trade: a name that resolves to nothing is visible in review, while a
neutral dot silently looked deliberate.
…ages land

The section links out to /industries/<slug>/ pages that are being reworked, so it
points at copy that is about to change. Hidden rather than removed: the component
and the industries: field in each use-case stay as they are, so bringing it back
is one line in pages/use-cases/[slug].vue.

Also drops src/_includes/components/use-case-chips.njk, the 11ty twin of the same
section - its only caller was layouts/use-case.njk, which this PR deletes.
@dimitrieh

Copy link
Copy Markdown
Contributor Author

Hidden in 507eefb. The component and the industries: field in each use-case stay where they are, so bringing it back is putting one line back in pages/use-cases/[slug].vue.

Same commit drops src/_includes/components/use-case-chips.njk, the 11ty copy of that section: its only caller was layouts/use-case.njk, which this PR deletes.

@Yndira-E
Yndira-E merged commit 472c303 into main Sep 16, 2026
8 checks passed
@Yndira-E
Yndira-E deleted the nuxt/use-cases branch September 16, 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.

2 participants