Skip to content

Feature catalog: one file, Edge/Hub/Fleet availability badges - #5525

Open
dimitrieh wants to merge 6 commits into
mainfrom
feature-catalog/single-catalog
Open

Feature catalog: one file, Edge/Hub/Fleet availability badges#5525
dimitrieh wants to merge 6 commits into
mainfrom
feature-catalog/single-catalog

Conversation

@dimitrieh

@dimitrieh dimitrieh commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Description

Follow-up to #5524. That PR disconnected the changelog from the tier badges because they were showing a tier that no longer exists. This makes the catalog correct and turns the badges back on.

The problem

Two catalogs had drifted apart:

  • src/_data/featureCatalog.yaml held the docs links, changelog links, solutions and subfeature structure, but its tier axis was Cloud/Self-Hosted x Enterprise, which predates the Edge/Hub/Fleet repackaging.
  • nuxt/content/feature-catalog.yml had the right plans and nothing else.

Only a minority of feature ids overlapped, so this is a merge rather than an update.

Separately, the badges had already gone dark almost everywhere. PostHog shows tier-badge-click running at roughly 100 to 150 clicks a month from around 30 people through July, nearly all of them on /docs/* pages, dropping to zero after the week of 27 July. The docs Nuxt migration (#5177, 29 July) is the cause: the docsFeatureBadges transform in .eleventy.js still ran and still emitted HTML, but it wrote into nuxt/public/ where the Nuxt route shadows it, so the output was discarded. Same for releaseFeatures on release blogs.

What this does

Two commits.

Commit 1, the catalog.

  • Merges everything into nuxt/content/feature-catalog.yml and deletes the legacy file, the dead Eleventy transforms, and the orphaned tier-badges.njk include.
  • Badges name the plans a feature is included in: "Available in Edge / Hub / Fleet". Rendered on changelog entries and back on docs pages.
  • Features that exist only to carry a changelog or docs link are marked showOnPricing: false.
  • A feature whose availability is not settled can omit tiers entirely and publishes no badge. A schema refine stops that leaking onto the pricing page.
  • useFeatureCatalog.ts is rewired onto the content collection; lookups moved to nuxt/lib/feature-catalog.mjs so node --test covers them.

Commit 2, the release blogs.

The features: frontmatter on release blogs drove the same injection and broke the same way. Rebuilt against the parsed markdown tree rather than the output HTML, so a heading containing a link or inline code still matches and nothing can be injected into an attribute.

All five release blogs named ids from the deleted catalog, so none of them would have resolved. Remapped, with three judgement calls worth a look:

  • Certified Nodes is now two features, so that heading takes both ids and badges the union of their plans.
  • tiers: { cloud: all, selfHosted: all } becomes the plan triple.
  • 2.28's "More Flexibility for Self-Hosted Deployments" loses its badge. That section is about a deployment model and no plan badge would be true of it.

Note this adds badges to five published posts. They render nothing today, so it is additive, but it is a visible change to live pages.

Pricing page is unchanged

Verified programmatically, not by eye: same features, same order, same tier values, before and after. The only visible difference is info popovers appearing on four comparison rows that gained a description (Device Fleet Updates, Device Group Management, Git Integration, High Availability).

Not in scope

The release blog features: injection is dead for the same reason and is not rebuilt here. The handbook now says so instead of describing automation that does not run. Subfeature badges keyed to a heading fragment (/docs/user/expert/chat/#support-mode) are also not restored; page-level docs badges are.

Related Issue(s)

Follows #5524

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 6, 2026

Copy link
Copy Markdown

Deploy Preview for flowforge-website ready!

Name Link
🔨 Latest commit ec0a47d
🔍 Latest deploy log https://app.netlify.com/projects/flowforge-website/deploys/6a7472aa1b816b000830c949
😎 Deploy Preview https://deploy-preview-5525--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: 59 (🔴 down 3 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.

@netlify

netlify Bot commented Aug 6, 2026

Copy link
Copy Markdown

Deploy Preview for flowforge-website ready!

Name Link
🔨 Latest commit 3563dbc
🔍 Latest deploy log https://app.netlify.com/projects/flowforge-website/deploys/6a75ca6a24d51e00081a4c37
😎 Deploy Preview https://deploy-preview-5525--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: 75 (🟢 up 8 from production)
Accessibility: 96 (no change from production)
Best Practices: 100 (no change from production)
SEO: 92 (🟢 up 7 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

dimitrieh commented Aug 6, 2026

Copy link
Copy Markdown
Contributor Author

Every page this changes, with preview links

Preview: https://deploy-preview-5525--flowforge-website.netlify.app

Verified by fetching each page and reading the rendered badge text, not by eye. Every page below returned 200.

Docs pages: availability badge added above the H1

This is the surface that had been dark since 29 July, and where the clicks were.

Page Badge reads Catalog feature
/docs/user/expert/ Edge Hub Fleet flowfuse-expert-ai
/docs/user/introduction/ Edge Hub Fleet node-red-hosting
/docs/device-agent/introduction/ Edge Hub Fleet edge-devices
/docs/user/snapshots/ Edge Hub Fleet snapshots
/docs/install/introduction/ Edge Hub Fleet installation-support
/docs/premium-support/ Edge Hub Fleet enterprise-support
/docs/user/custom-hostnames/ Edge Hub Fleet custom-hostnames
/docs/install/file-storage/ Edge Hub Fleet persistent-files
/docs/user/persistent-context/ Edge Hub Fleet persistent-context
/docs/user/teambroker/ Edge Hub Fleet mqtt-broker
/docs/device-agent/quickstart/ Edge Hub Fleet edge-development
/docs/user/devops-pipelines/ Edge Hub Fleet devops-pipelines
/docs/user/custom-npm-packages/ Edge Hub Fleet private-npm-registry
/docs/user/ff-tables/ Edge Hub Fleet flowfuse-tables
/docs/user/device-groups/ Edge Fleet device-group-management
/docs/user/high-availability/ Hub high-availability
/docs/user/logs/ Edge Hub Fleet audit-log
/docs/user/role-based-access-control/ Edge Hub Fleet role-based-access-control
/docs/user/instance-settings/ Edge Hub Fleet endpoint-security
/docs/user/user-settings/ Edge Hub Fleet two-factor-authentication
/docs/admin/sso/ Edge Hub Fleet single-sign-on
/docs/user/team/ Edge Hub Fleet team-members
/docs/user/concepts/ Edge Hub Fleet blueprints-converge
/docs/user/shared-library/ Edge Hub Fleet team-library
/docs/user/projectnodes/ Edge Hub Fleet project-nodes

Changelog entries: availability badge added under the title

Page Badge reads Catalog feature
/changelog/2026/02/ff-expert-update-banner/ Edge Hub Fleet flowfuse-expert-ai
/changelog/2026/02/ff-expert-debug-log-context/ Edge Hub Fleet flowfuse-expert-support-mode
/changelog/2026/05/expert-application-building/ Edge Hub Fleet flowfuse-expert-application-building
/changelog/2026/02/device-agent-nodejs-options/ Edge Hub Fleet edge-devices
/changelog/2026/04/snapshot-diff-viewer/ Edge Hub Fleet snapshot-comparison
/changelog/2026/03/embedded-editor-tab-title/ Edge Hub Fleet embedded-editor-tab-title
/changelog/2026/03/snapshot-detail-modal-immersive-editor/ Edge Hub Fleet immersive-editor-snapshots
/changelog/2026/04/immersive-editor-drawer/ Edge Hub Fleet immersive-editor-drawer
/changelog/2026/07/expert-tables-automation/ Edge Hub Fleet flowfuse-tables
/changelog/2026/03/azure-dev-ops-gitops/ Hub git-integration-azure
/changelog/2026/07/scoped-pats/ Edge Hub Fleet scoped-personal-access-tokens
/changelog/2026/07/application-sso-groups/ Edge Hub Fleet single-sign-on
/changelog/2026/07/team-and-application-dashboards/ Edge Hub Fleet dashboards-view

Changelog listing: badges appear on the entries above

Page Entries badged
/changelog/ 8
/changelog/2/ 5
/changelog/3/ onwards 0, nothing older than February is in the catalog

Release blogs: badges under each section heading, changelog and docs links at the end of it

Page Sections badged Changelog and docs links Notes
/blog/2026/03/flowfuse-release-2-28/ 4 6 "More Flexibility for Self-Hosted Deployments" gets no badge on purpose, see below
/blog/2026/04/flowfuse-release-2-29/ 3 7 Azure DevOps section reads Hub only
/blog/2026/05/flowfuse-release-2-30/ 3 4
/blog/2026/06/flowfuse-release-2-31/ 3 2 Certified Nodes badges the union of the IT and OT bundles
/blog/2026/07/flowfuse-release-2-33/ 4 6

Pricing: same rows, four new info popovers

/pricing/

The feature set, order and tier values are identical before and after, checked by diffing the parsed catalogs rather than the page. The only visible difference is an info icon on four comparison rows that gained a description: Device Fleet Updates, Device Group Management, Git Integration, High Availability.

Handbook: three pages of copy

Page What changed
/handbook/engineering/product/features/ Table rebuilt on Edge/Hub/Fleet columns. The six Solutions columns (MES, SCADA, UNS, Edge Conn., IT/OT, Data Int.) are gone, data and rendering both. Included cells carry a light green wash so a plan reads down its column. New "Not on pricing" tag, and "TBD" for a row whose availability is unset, though no row reads TBD today.
/handbook/engineering/releases/writing-changelog/ Points at the new catalog file. Describes plan badges instead of tier badges, and the showOnPricing and unset-tiers cases.
/handbook/engineering/releases/release-blogs/ Documents what features: actually renders now, with a worked example covering the multi-id and inline-tiers forms.

Nothing else moves

Docs pages outside the table above render no badge, because no catalog feature names them as its docsLink. Non-release blog posts pass through untouched. Spot checked both.

The site carried two catalogs. src/_data/featureCatalog.yaml had the docs
links, changelog links, solutions and subfeature structure, but its tier axis
was Cloud/Self-Hosted x Enterprise, which predates the Edge/Hub/Fleet
repackaging. nuxt/content/feature-catalog.yml had the right plans but none of
the metadata. Only a minority of feature ids overlapped.

Merge them into nuxt/content/feature-catalog.yml and delete the legacy file.
Features that exist only to carry a changelog or docs link are marked
showOnPricing: false, so the pricing page renders exactly the rows it rendered
before, in the same order, with the same tier values.

Badges now name the plans a feature is included in rather than a tier that no
longer exists. They come back on changelog entries and, more importantly, on
docs pages: the docs badge injection had been silently dead since the docs
moved to Nuxt, because the Eleventy transform still wrote HTML into
nuxt/public/ where the Nuxt route shadows it. Those transforms are removed
along with the orphaned tier-badges include.

A feature with no settled availability can omit tiers entirely and publishes
no badge; a schema refine keeps that from leaking onto the pricing page.

The release blog features: injection was dead for the same reason and is not
rebuilt here. The handbook now says so rather than describing automation that
does not run.
Release blog posts carry a `features:` block naming a heading and a catalog
feature. An Eleventy transform used to read it and inject availability badges,
changelog links and a docs link into each named section. It broke when the blog
moved to Nuxt, the same way the docs badges did: the transform still ran and
still emitted HTML, into nuxt/public/ where the Nuxt route shadows it.

Rebuild it against the parsed markdown tree rather than the output HTML. The
old version matched headings with a regex over rendered HTML and stripped tags
to compare text, which misses a heading containing a link or inline code and
edits a raw string. Splicing nodes into the MDC array makes heading matching
exact and injection structurally safe.

The five release blogs named ids from the deleted catalog, so none of them
would have resolved. Remapped, with three judgement calls: Certified Nodes is
now two features so that heading takes both ids and badges the union of their
plans; the `tiers: {cloud: all, selfHosted: all}` shorthand becomes the plan
triple; and 2.28's "More Flexibility for Self-Hosted Deployments" loses its
badge, because that section is about a deployment model and no plan badge
would be true of it.

MDC's propsToData joins an all-strings array prop with spaces, which turned the
plan list into one string and made the badge component's v-for iterate its
characters. Release blogs pass the plans comma separated instead.

A test fails on any `features:` id the catalog does not have, since a stale id
otherwise just renders nothing at all.
The six solution columns (MES, SCADA, UNS, Edge Connectivity, IT/OT
Middleware, Data Integration) do not match how the platform is thought about,
so the data and its rendering both go.

Removed from the catalog entries, the content schema, the CatalogFeature type
and the handbook table. Nothing else read the field. The table is now Feature
against Edge, Hub and Fleet, which fits without scrolling sideways.

Pricing is untouched: same rows, order, tiers and descriptions.
Scanning the table meant picking out individual check marks. Included cells now
carry a light green background and a green check, so the shape of a plan reads
down the column at a glance. Excluded cells keep their dash, dimmed so it
recedes rather than competing.
The green background carries the scanning on its own. Tinting the check marks,
dashes and TBD labels on top of it only made them harder to read.
Nuxt Content resolves a markdown component tag against a registry it builds
while parsing, and reaches it through an async loader. The badge and
changelog-link nodes are spliced in after parsing, so that path renders
nothing in a production build even though it works in dev. Passing the
components to ContentRenderer directly skips the registry.
@dimitrieh
dimitrieh force-pushed the feature-catalog/single-catalog branch from 6222f7a to 3563dbc Compare August 7, 2026 12:07
@dimitrieh

Copy link
Copy Markdown
Contributor Author

@KristopherLeads @Yndira-E @sumitshinde-84 This affects the source file that informs the pricing page (and connects features across pricing, docs, release blog posts, and changelogs)

Affects quite a number of pages. My suggestion is to go through the links posted above in the comment and see if it aligns with expectations.

Goal here is that control lies in one place mostly, the feature catalogue page.

#
# Sections and the titles, descriptions and tiers of everything that reaches /pricing are
# owned by the pricing page. Features that no longer appear there keep their entry with
# showOnPricing: false so the handbook table, docs badges and changelog links still resolve.

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 think features that aren’t shown on the pricing page shouldn’t render badges. From a user’s perspective, clicking through to the pricing table and not finding the feature feels broken.

If I can’t find the feature that made me clicked on the badge, I’d assume it’s been deprecated, isn’t available in my plan, or that the badge was added by mistake.

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.

@Yndira-E you're right. How is it decided currently what shows up on the pricing page, as the list has shrunk from before 🤔 ?

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.

@KristopherLeads might have the answer, as he worked on this recently

<NuxtLink
v-for="plan in planList"
:key="plan"
to="/pricing/#comparison"

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 These badges didn’t link anywhere before. The previous implementation tracked clicks but didn’t have an href/to at all.

I understand you gathered some data, and at least in the docs it looks like users are clicking on them, so I’m not opposed to linking them somewhere. Just wanted to flag that this reintroduces a behaviour we intentionally moved away from before.

Once we have per-plan landing pages, linking there instead of /pricing/#comparison might make more sense than sending users to a feature list. Landing on a plan page doesn’t create the same “where’s the feature I clicked on?” expectation.

Not sure yet what those pages will look like, though, so consider this more of a thought for the future than a request to change anything now.

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.

@Yndira-E yes, this got reintroduced by claude.. i am ok with unlinking (again) for now, or linking to the feature catalogue page in stead. wdyt?

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.

Which one is the feature catalogue page? the handbook one?

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.

@Yndira-E The feature catalogue is a data file that informs the badges, the handbook page, and the pricing page. One place to maintain and upkeep the data, many places in which it is used/adjusted if changed

https://github.com/FlowFuse/website/pull/5525/changes#diff-f621edbac8c43c11a968e06f7493b846f91733be8aa75de0217a936cd83a6d6d

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.

but that's a data file, not a page? right?

you said:

linking to the feature catalogue page in stead.

I'm trying to understand which page is that.

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.

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.

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.

so it would be the handbook, as I suspected.

No, handbook is for internal use, the new pages will be ready real soon, let's keep it as is for now, but this needs to be resolved before merging: #5525 (comment)

@dimitrieh
dimitrieh requested a review from Yndira-E August 8, 2026 17:30
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