+// The homepage hero's cross-fading background, ported from src/index.njk plus
+// src/_data/heroImages.js.
+//
+// The .njk read src/images/home/hero/config.json and filtered it to the files that exist,
+// so a slide could be removed by deleting the image. The list is imported directly here;
+// a config entry with no file is a missing image either way, and the build now surfaces
+// that rather than silently dropping the slide.
+//
+// The .njk's inline script queried .hero-slide and ran two timers with no teardown. This
+// is one interval, cleared on unmount, and it still honours prefers-reduced-motion by
+// never starting.
+import slides from '../../src/images/home/hero/config.json'
+
+const FIRST_ADVANCE_MS = 3200
+const INTERVAL_MS = 4400
+
+const current = ref(0)
+let startTimer: ReturnType | undefined
+let cycleTimer: ReturnType | undefined
+
+function advance() {
+ current.value = (current.value + 1) % slides.length
+}
+
+onMounted(() => {
+ if (slides.length < 2) return
+ if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return
+ startTimer = setTimeout(() => {
+ advance()
+ cycleTimer = setInterval(advance, INTERVAL_MS)
+ }, FIRST_ADVANCE_MS)
+})
+
+onUnmounted(() => {
+ clearTimeout(startTimer)
+ clearInterval(cycleTimer)
+})
+
+
+
+
+
diff --git a/nuxt/content.config.ts b/nuxt/content.config.ts
index e204031adc..743570775a 100644
--- a/nuxt/content.config.ts
+++ b/nuxt/content.config.ts
@@ -220,7 +220,7 @@ export default defineContentConfig({
}),
})
}),
- // ThankYouStoriesBlock.vue also queries this `stories` collection - no separate one needed.
+ // ExploreMoreStories.vue also queries this `stories` collection - no separate one needed.
// Source files stay at src/webinars/ (still served by 11ty, see LEGACY_PREFIXES
// in nuxt/server/middleware/legacy.ts) - only queried for the "Latest/Upcoming
// Webinar" tile on the thank-you pages, so no `sitemap` field either.
diff --git a/nuxt/lib/custom-cta-destinations.ts b/nuxt/lib/custom-cta-destinations.ts
index 6a251d91d2..4aa2319344 100644
--- a/nuxt/lib/custom-cta-destinations.ts
+++ b/nuxt/lib/custom-cta-destinations.ts
@@ -49,7 +49,7 @@ export const CUSTOM_CTA_DESTINATIONS = {
},
// href varies - always the single most-recently-dated webinar (past or
// upcoming), never the general webinars listing (see
- // ThankYouExploreMore.vue's query). Named for that destination, not for
+ // ExploreMoreContent.vue's query). Named for that destination, not for
// the fact that it's shown as a post-conversion suggestion.
latestWebinar: {
event: 'cta-latest-webinar',
diff --git a/nuxt/lib/faq-answer.mjs b/nuxt/lib/faq-answer.mjs
new file mode 100644
index 0000000000..d24b83d4d2
--- /dev/null
+++ b/nuxt/lib/faq-answer.mjs
@@ -0,0 +1,72 @@
+// Renders one FAQ answer into a list of HTML blocks. Kept free of Nuxt and Vue imports so
+// it can be unit tested with `node --test`; is the only caller.
+//
+// Answers are authored as plain text, and any literal "<...>" in them - "", ""
+// and similar placeholders in the docs-derived answers - must stay literal. So the whole
+// string is escaped first, and only a small markdown subset is enabled afterwards, which
+// means a URL or a label cannot reintroduce markup.
+//
+// The subset covers what the 11ty answers expressed with raw tags under `| safe`:
+//
+// [label](url) inline link, http(s) or site-absolute only
+// **bold**
+// *italic*
+// blank line a new paragraph (the .njk answers used
tags)
+// "- item" lines an unordered list (the .njk answers used
)
+// "1. item" lines an ordered list (the .njk answers used
`)
+ return `<${tag}>${items.join('')}${tag}>`
+}
+
+// A paragraph made entirely of list-item lines renders as a list; anything else renders as
+// a paragraph with its lines joined, which is how the source wrapped long answers.
+function renderBlock (paragraph) {
+ const lines = paragraph.split('\n').map(line => line.trim()).filter(Boolean)
+ if (lines.length && lines.every(line => UNORDERED_ITEM.test(line))) return renderList(lines, false)
+ if (lines.length && lines.every(line => ORDERED_ITEM.test(line))) return renderList(lines, true)
+ return inline(lines.join(' '))
+}
+
+export function renderFaqAnswer (answer) {
+ if (!answer) return []
+ return answer
+ .split(/\n\s*\n/)
+ .map(paragraph => paragraph.trim())
+ .filter(Boolean)
+ .map(renderBlock)
+}
+
+// A block that is a list must not be wrapped in
, which is invalid; asks
+// this rather than sniffing the markup itself.
+export function isListBlock (block) {
+ return block.startsWith('
') || block.startsWith('')
+}
diff --git a/nuxt/lib/faq-answer.test.mjs b/nuxt/lib/faq-answer.test.mjs
new file mode 100644
index 0000000000..d97a513f21
--- /dev/null
+++ b/nuxt/lib/faq-answer.test.mjs
@@ -0,0 +1,88 @@
+import { test } from 'node:test'
+import assert from 'node:assert/strict'
+
+import { isListBlock, renderFaqAnswer } from './faq-answer.mjs'
+
+test('escapes markup so placeholders stay literal', () => {
+ assert.deepEqual(renderFaqAnswer('use here'), ['use <ip> here'])
+ assert.deepEqual(renderFaqAnswer(''), ['<script>alert(1)</script>'])
+ assert.deepEqual(renderFaqAnswer('a & b'), ['a & b'])
+})
+
+test('renders site-absolute and http links', () => {
+ assert.deepEqual(
+ renderFaqAnswer('see the [pricing page](/pricing)'),
+ ['see the pricing page'],
+ )
+ assert.deepEqual(
+ renderFaqAnswer('[device-agent](https://github.com/FlowFuse/device-agent)'),
+ ['device-agent'],
+ )
+})
+
+test('leaves a non-http, non-absolute link target as text', () => {
+ assert.deepEqual(renderFaqAnswer('[x](javascript:alert(1))'), ['[x](javascript:alert(1))'])
+})
+
+test('renders bold and italic', () => {
+ assert.deepEqual(renderFaqAnswer('save you *a lot* of clicking'), ['save you a lot of clicking'])
+ assert.deepEqual(renderFaqAnswer('**Fleet Mode** deploys'), ['Fleet Mode deploys'])
+})
+
+test('an unclosed marker stays text rather than swallowing the answer', () => {
+ assert.deepEqual(renderFaqAnswer('2 * 3 is six'), ['2 * 3 is six'])
+})
+
+test('a blank line starts a new paragraph', () => {
+ assert.deepEqual(
+ renderFaqAnswer('First point.\n\nSecond point.'),
+ ['First point.', 'Second point.'],
+ )
+})
+
+test('empty input renders no paragraphs', () => {
+ assert.deepEqual(renderFaqAnswer(''), [])
+ assert.deepEqual(renderFaqAnswer(undefined), [])
+})
+
+test('renders an unordered list when every line is a bullet', () => {
+ assert.deepEqual(
+ renderFaqAnswer('- first\n- second'),
+ ['
first
second
'],
+ )
+})
+
+test('renders an ordered list, and links inside items', () => {
+ assert.deepEqual(
+ renderFaqAnswer('1. go to [pricing](/pricing)\n2. pick a plan'),
+ ['
'],
+ )
+})
+
+test('a paragraph that only partly looks like a list stays a paragraph', () => {
+ assert.deepEqual(
+ renderFaqAnswer('Here is why:\n- because'),
+ ['Here is why: - because'],
+ )
+})
+
+test('joins the wrapped lines of a paragraph with spaces', () => {
+ assert.deepEqual(
+ renderFaqAnswer('one line\nwrapped onto another'),
+ ['one line wrapped onto another'],
+ )
+})
+
+test('a list and a paragraph in one answer render as separate blocks', () => {
+ assert.deepEqual(
+ renderFaqAnswer('Uses include:\n\n- monitoring\n- alerting\n\nAnd more.'),
+ ['Uses include:', '
monitoring
alerting
', 'And more.'],
+ )
+})
+
+test('isListBlock marks only list blocks', () => {
+ assert.equal(isListBlock('
x
'), true)
+ assert.equal(isListBlock('
x
'), true)
+ assert.equal(isListBlock('plain text'), false)
+ assert.equal(isListBlock('bold text'), false)
+})
diff --git a/nuxt/nuxt.config.ts b/nuxt/nuxt.config.ts
index 56ccb724cf..54f57c669e 100644
--- a/nuxt/nuxt.config.ts
+++ b/nuxt/nuxt.config.ts
@@ -407,6 +407,8 @@ export default defineNuxtConfig({
'/resources/roi-calculator',
'/product',
'/pricing/request-quote/',
+ // The homepage itself: nothing links to it that the crawler starts from.
+ '/',
// /ai is only linked from 11ty-generated HTML (nav, homepage), which the
// Nuxt prerender crawler never parses, so it has to be listed explicitly
// or the route is missing from nuxt/dist and every link to it breaks.
diff --git a/nuxt/pages/index.vue b/nuxt/pages/index.vue
new file mode 100644
index 0000000000..6414362107
--- /dev/null
+++ b/nuxt/pages/index.vue
@@ -0,0 +1,394 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ The Edge-Native Platform for Industrial IT, OT, and IIOT Applications
+
+
+
+ Build industrial applications in minutes with AI, then deploy and govern production from cloud to edge.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{{ metric.number }}
+
{{ metric.text }}
+
+
+
+
+
+
+
+
Industrial innovation is accelerating. Execution is not.
+
Teams can access data and build applications faster than ever. But the operational logic that drives throughput, quality, and response still lives in custom code, isolated scripts, and one-off solutions that don't scale.
+
+
+
+
+
+
+
+
+
+
+ {{ section.title }}
+
+
+
+
+
{{ section.description }}
+
+
+
+
+
+
+
+
+
$50B
+
Annual cost of unplanned downtime across industrial manufacturers globally
+
+
+
800h
+
Average equipment downtime per year experienced by manufacturers (over 15 hours per week)
+
+
+
+
+
+
+
+
The missing operational layer
+
FlowFuse is the industrial application platform that sits between your systems and your operations
+
Whether you're extending an existing system, standardizing a proven solution across sites, or connecting OT and IT data flows, FlowFuse gives your team the platform to build once and run everywhere.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{{ item.feature }}
+
{{ item.capability }}
+
+
+
+
+
+
+ {{ item.description }}
+
+
+ {{ item.linkText }}
+
+
+
+
+
+
+
+
+
+
+
What mature adoption looks like
+
From one-off solutions to an operational application system
+
These are not use cases. They are production applications running across the business. Built once, governed centrally, deployed across every site.
+
+
+
Operational Application System
+
+
+
+
+ {{ category.title }}
+
+
+
+
+
{{ item.name }}
+
{{ item.description }}
+
+
+
{{ item.name }}
+
{{ item.description }}
+
+
+
+
+
+
+
+
+
Every problem solved becomes a reusable application
+
+
That's how a small team manages operations across dozens of sites, without rebuilding from scratch every time.
+
Ready to build yours?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Real results from industrial teams
+
See how manufacturers and industrial operators are using FlowFuse to standardize, scale, and govern their operations.
+
+
+
+
+
+
+
+
+
AI in industrial operations
+
AI makes building faster. FlowFuse makes it operational.
+
+
+
+
+
+
+
+
AI accelerates the build
+
+
FlowFuse Expert, our industrial-tuned AI assistant, lets your team describe what they need in plain language, and generates flows, data transformations, and dashboard logic. No waiting on scarce developers.
Speed without governance creates new debt. FlowFuse provides the production layer where AI-assisted work becomes visible, versioned, secure, and reusable, across the enterprise.
+
+
+
+ Book a demo
+
+
+
+
+
+
+
+
+
+
+
Frequently Asked Questions
+
+
+
+
+
+
+
+
+
+
Get Started with FlowFuse
+
Your first operational application could be running this week. Book a demo to see how, or start a free trial and build it yourself.
diff --git a/nuxt/public/images/home/blog.png b/nuxt/public/images/home/blog.png
new file mode 100644
index 0000000000..62b4a77af5
Binary files /dev/null and b/nuxt/public/images/home/blog.png differ
diff --git a/nuxt/public/images/home/collect.png b/nuxt/public/images/home/collect.png
new file mode 100644
index 0000000000..86ce6d3c06
Binary files /dev/null and b/nuxt/public/images/home/collect.png differ
diff --git a/nuxt/public/images/home/collect_graphic.png b/nuxt/public/images/home/collect_graphic.png
new file mode 100644
index 0000000000..e7a9f3e4fa
Binary files /dev/null and b/nuxt/public/images/home/collect_graphic.png differ
diff --git a/nuxt/public/images/home/connect.png b/nuxt/public/images/home/connect.png
new file mode 100644
index 0000000000..5aa27b5660
Binary files /dev/null and b/nuxt/public/images/home/connect.png differ
diff --git a/nuxt/public/images/home/data-silos.jpg b/nuxt/public/images/home/data-silos.jpg
new file mode 100644
index 0000000000..6f260f8fae
Binary files /dev/null and b/nuxt/public/images/home/data-silos.jpg differ
diff --git a/nuxt/public/images/home/flowfuse-home-ui.png b/nuxt/public/images/home/flowfuse-home-ui.png
new file mode 100644
index 0000000000..dc792ce984
Binary files /dev/null and b/nuxt/public/images/home/flowfuse-home-ui.png differ
diff --git a/nuxt/public/images/home/hero/config.json b/nuxt/public/images/home/hero/config.json
new file mode 100644
index 0000000000..ee452c678a
--- /dev/null
+++ b/nuxt/public/images/home/hero/config.json
@@ -0,0 +1,5 @@
+[
+ { "file": "hero-1.jpg", "alt": "Industrial manufacturing facility", "mobileOverlay": true },
+ { "file": "hero-2.jpg", "alt": "Industrial shipping port with cargo containers and cranes", "mobileOverlay": true },
+ { "file": "hero-3.jpg", "alt": "Large-scale solar panel array at an industrial energy facility", "mobileOverlay": false }
+]
diff --git a/nuxt/public/images/home/hero/hero-1.jpg b/nuxt/public/images/home/hero/hero-1.jpg
new file mode 100644
index 0000000000..35f3eb12d9
Binary files /dev/null and b/nuxt/public/images/home/hero/hero-1.jpg differ
diff --git a/nuxt/public/images/home/hero/hero-2.jpg b/nuxt/public/images/home/hero/hero-2.jpg
new file mode 100644
index 0000000000..0b84b462eb
Binary files /dev/null and b/nuxt/public/images/home/hero/hero-2.jpg differ
diff --git a/nuxt/public/images/home/hero/hero-3.jpg b/nuxt/public/images/home/hero/hero-3.jpg
new file mode 100644
index 0000000000..a6a2e52899
Binary files /dev/null and b/nuxt/public/images/home/hero/hero-3.jpg differ
diff --git a/nuxt/public/images/home/home-dashboard.png b/nuxt/public/images/home/home-dashboard.png
new file mode 100644
index 0000000000..f099c3cc6a
Binary files /dev/null and b/nuxt/public/images/home/home-dashboard.png differ
diff --git a/nuxt/public/images/home/home-data-integration.png b/nuxt/public/images/home/home-data-integration.png
new file mode 100644
index 0000000000..32db38409d
Binary files /dev/null and b/nuxt/public/images/home/home-data-integration.png differ
diff --git a/nuxt/public/images/home/home-edge-connectivity.png b/nuxt/public/images/home/home-edge-connectivity.png
new file mode 100644
index 0000000000..a16574caeb
Binary files /dev/null and b/nuxt/public/images/home/home-edge-connectivity.png differ
diff --git a/nuxt/public/images/home/home-itot-middleware.png b/nuxt/public/images/home/home-itot-middleware.png
new file mode 100644
index 0000000000..97a3bf0d53
Binary files /dev/null and b/nuxt/public/images/home/home-itot-middleware.png differ
diff --git a/nuxt/public/images/home/home-mes.png b/nuxt/public/images/home/home-mes.png
new file mode 100644
index 0000000000..8206a05ccd
Binary files /dev/null and b/nuxt/public/images/home/home-mes.png differ
diff --git a/nuxt/public/images/home/home-node-red.png b/nuxt/public/images/home/home-node-red.png
new file mode 100644
index 0000000000..69b039ea7a
Binary files /dev/null and b/nuxt/public/images/home/home-node-red.png differ
diff --git a/nuxt/public/images/home/home-pipeline.png b/nuxt/public/images/home/home-pipeline.png
new file mode 100644
index 0000000000..26b847fecd
Binary files /dev/null and b/nuxt/public/images/home/home-pipeline.png differ
diff --git a/nuxt/public/images/home/home-scada.png b/nuxt/public/images/home/home-scada.png
new file mode 100644
index 0000000000..628f84fb95
Binary files /dev/null and b/nuxt/public/images/home/home-scada.png differ
diff --git a/nuxt/public/images/home/home-solution-background.svg b/nuxt/public/images/home/home-solution-background.svg
new file mode 100644
index 0000000000..e93165f8fd
--- /dev/null
+++ b/nuxt/public/images/home/home-solution-background.svg
@@ -0,0 +1,34 @@
+
diff --git a/nuxt/public/images/home/home-uns.png b/nuxt/public/images/home/home-uns.png
new file mode 100644
index 0000000000..eb0162f90f
Binary files /dev/null and b/nuxt/public/images/home/home-uns.png differ
diff --git a/nuxt/public/images/home/interact_graphic.png b/nuxt/public/images/home/interact_graphic.png
new file mode 100644
index 0000000000..330eaba361
Binary files /dev/null and b/nuxt/public/images/home/interact_graphic.png differ
diff --git a/nuxt/public/images/home/newsletter.png b/nuxt/public/images/home/newsletter.png
new file mode 100644
index 0000000000..3eb8841f91
Binary files /dev/null and b/nuxt/public/images/home/newsletter.png differ
diff --git a/nuxt/public/images/home/visualise_graphic.png b/nuxt/public/images/home/visualise_graphic.png
new file mode 100644
index 0000000000..48330c5feb
Binary files /dev/null and b/nuxt/public/images/home/visualise_graphic.png differ
diff --git a/nuxt/public/images/home/webinar.png b/nuxt/public/images/home/webinar.png
new file mode 100644
index 0000000000..6fb71d4ddd
Binary files /dev/null and b/nuxt/public/images/home/webinar.png differ
diff --git a/nuxt/server/middleware/legacy.ts b/nuxt/server/middleware/legacy.ts
index f1ae2474d0..f3f118556b 100644
--- a/nuxt/server/middleware/legacy.ts
+++ b/nuxt/server/middleware/legacy.ts
@@ -4,7 +4,7 @@ import { defineEventHandler, proxyRequest } from 'h3'
// Extend this list as pages are migrated. Trailing slashes are matched automatically.
// Note: /sitemap-legacy.xml is deliberately NOT listed here — it only exists in
// nuxt/public/ after a production build, so in dev it must keep proxying to 11ty's _site/.
-const NUXT_ROUTES = new Set(['/ai', '/terms', '/privacy-policy', '/integrations', '/sitemap.xml', '/robots.txt', '/llms.txt', '/llms-full.txt', '/contact-us', '/book-demo', '/support', '/professional-services', '/dashboard/tags-and-canvas-feedback'])
+const NUXT_ROUTES = new Set(['/', '/ai', '/terms', '/privacy-policy', '/integrations', '/sitemap.xml', '/robots.txt', '/llms.txt', '/llms-full.txt', '/contact-us', '/book-demo', '/support', '/professional-services', '/dashboard/tags-and-canvas-feedback'])
// Path prefixes handled by Nuxt. Used for dynamic routes like /integrations/{id}.
const NUXT_ROUTE_PREFIXES = ['/integrations/', '/raw/']
@@ -19,7 +19,7 @@ const NUXT_PREFIXES = ['/handbook', '/ebooks', '/whitepaper', '/pricing', '/docs
// Top-level routes still on 11ty, not yet ported to Nuxt (everything not listed above
// already falls through to the 11ty proxy by default). Remove entries here as they migrate:
-// / (homepage), /about, /blueprints, /careers, /community, /events
+// /about, /blueprints, /careers, /community, /events
// /free-consultation, /industries, /landing, /node-red, /partners, /platform,
// /use-cases, /vs, /webinars
diff --git a/src/index.njk b/src/index.njk
deleted file mode 100644
index fbe928a6ba..0000000000
--- a/src/index.njk
+++ /dev/null
@@ -1,436 +0,0 @@
----
-metaTitle: "Build Industrial Applications at Scale"
-layout: default
-sitemapPriority: 1.0
-sections:
- - svgPath: "components/icons/arrow-path.svg"
- title: "Every solution starts from scratch"
- description: "Operational logic stays local. The same problem gets solved differently at every site, by every team, every time."
- - svgPath: "components/icons/link-slash.svg"
- title: "Your core systems don't cover everything"
- description: "MES, ERP, and SCADA solve standard problems well. The workflows in the gaps (quality gates, shift handovers, custom validation) fall back to custom code and manual workarounds."
- - svgPath: "components/icons/building-office-2.svg"
- title: "What works on one line won't scale to fifty"
- description: "A working solution on one machine requires rebuilding from scratch for the next site. There is no system to standardize, deploy, and govern what works"
-capabilities:
- - capability: "Build operational workflows your core systems can't"
- feature: "Low-code development with FlowFuse Expert"
- description: "Create the operational applications that MES, ERP, and SCADA platforms struggle to support natively, from quality validation and workforce assignment to shift handovers and production visibility. Describe what you need in plain language and FlowFuse Expert generates the starting logic directly in your workspace."
- imagePath: "images/home/home-node-red.png"
- imageAlt: "FlowFuse UI"
- linkText: "Learn more about FlowFuse Expert"
- linkHref: "/ai/"
- - capability: "Standardize proven workflows across every site"
- feature: "Device Agent and DevOps Pipelines"
- description: "Turn a successful workflow on one machine or line into a repeatable operational standard across plants. Roll out updates with version control, staged deployments, and centrally managed industrial devices. No more rebuilding from scratch for every site, or leaving improvements siloed in one location."
- imagePath: "images/home/home-pipeline.png"
- imageAlt: "FlowFuse flow editor"
- linkText: "See how device management works"
- linkHref: "/platform/device-agent/"
- - capability: "Connect shop floor events to enterprise systems"
- feature: "Flow-based IT/OT connectivity"
- description: "Move production events, work orders, alarms, and operational data securely between PLCs, edge devices, MES, ERP, cloud platforms, and operator interfaces, without brittle point-to-point integrations or exposing inbound firewall ports."
- imagePath: "images/home/home-dashboard.png"
- imageAlt: "FlowFuse Dashboard"
- linkText: "Explore production monitoring"
- linkHref: "/use-cases/production-monitoring/"
-solutions:
- - href: "/use-cases/it-ot-middleware/"
- image: "./images/home/home-itot-middleware.png"
- imageAlt: "Image of workers on a factory shop floor with desks, computers and dashboards on the screen"
- icon: "components/icons/cog.svg"
- title: "IT/OT Middleware"
- description: "Connect disparate systems and industrial protocols with a unified platform. Accelerate development and enable seamless collaboration between IT and OT teams to optimize real-time data flow."
- - href: "/use-cases/scada/"
- image: "./images/home/home-scada.png"
- imageAlt: "Image of a woman working on a computer with industrial dashboards on the screen in industrial environment"
- icon: "components/icons/adjustments-horizontal.svg"
- title: "SCADA"
- description: "Modernize your SCADA systems with a modular and flexible platform. Build custom interfaces and control logic in a fraction of the time, gaining full visibility of your operations in an agile and secure way."
- - href: "/use-cases/mes/"
- image: "./images/home/home-mes.png"
- imageAlt: "A factory centrally connected with various devices and systems"
- icon: "components/icons/chart.svg"
- title: "MES"
- description: "Implement custom Manufacturing Execution Systems (MES) with greater speed. Rapidly develop and deploy the specific workflows you need, connecting the production plan to the plant floor with ultimate efficiency."
-metrics:
- - number: "50%"
- text: "Reduction in scrap rate with real-time operational monitoring"
- - number: "10x"
- text: "Faster from idea to deployed operational application with FlowFuse Expert"
- - number: "20+"
- text: "Manufacturing sites standardized from a single platform without rebuilding"
-operationalSystem:
- categories:
- - title: "PRODUCTION & OPERATIONS"
- items:
- - name: "Production Monitoring"
- url: "/use-cases/production-monitoring/"
- description: "OEE tracking across lines, shifts, and plants."
- - name: "Continuous Improvement"
- description: "Digital CI workflow from suggestion to closure."
- - title: "OPERATIONAL WORKFLOWS"
- items:
- - name: "Workforce Assignment"
- description: "Dynamic operator allocation using training, ergonomics, and demand data."
- - name: "Shop Floor Communication"
- url: "/use-cases/shop-floor-communication/"
- description: "Real-time alerts, escalation, and cross-site coordination."
- - title: "SYSTEM EXTENSIONS"
- items:
- - name: "Quality Validation"
- description: "Inline inspection and QA checks outside the core system."
- - name: "Track & Trace"
- description: "Part, component, and batch traceability across the plant."
- - title: "OPERATIONAL INFRASTRUCTURE"
- items:
- - name: "Equipment Monitoring"
- description: "PLC and device health monitoring across controller types."
- - name: "Operational Data Pipelines"
- description: "Structured controller data flows, diagnostics, and routing."
- - name: "System Diagnostics"
- description: "Error tracking and root cause analysis across deployed applications."
-meta:
- faq:
- - question: "What's the difference between Node-RED and FlowFuse?"
- answer: >
- Node-RED is the open-source runtime FlowFuse is built on. It's how you build the logic. FlowFuse adds everything after the build: deployment across sites, version control, team access management, and enterprise security. You can use FlowFuse without prior Node-RED experience.
- - question: "Do I need Node-RED experience to use FlowFuse?"
- answer: >
- No. FlowFuse Expert, our AI-assisted development tool, lets your team describe what they need in plain language and generates the logic. Your team can build without a steep learning curve.
- - question: "Can FlowFuse work with our existing systems?"
- answer: >
- Yes, FlowFuse is designed for brownfield environments. It connects to and extends your existing MES, ERP, SCADA, PLCs, and other systems without replacing them or requiring modifications to core platforms.
- - question: "How does FlowFuse handle security and compliance?"
- answer: >
- FlowFuse is SOC 2 Type 1 and Type 2 certified. It supports RBAC, SSO, audit logs, and air-gapped self-hosted deployments for environments with strict network isolation requirements.
- - question: "How long does a typical deployment take?"
- answer: >
- Most teams are operational within days. FlowFuse is designed to start with a single use case and expand, not require a multi-month implementation before delivering value.
-hubspot:
- script: "hubspot/hs-form.njk"
- formId: 159c173d-dd95-49bd-922b-ff3ef243e90c
- cta: "cta-blog-subscribe"
- reference: "homepage"
----
-{% from "components/cta/cta-sign-up.njk" import ctaSignUp %}
-{% from "components/cta/cta-book-demo.njk" import ctaBookDemo %}
-
-
- {% if heroImages.length %}
-
- {# heroTagLine, not tagLine: tagLine also renders into every page's
- via base.njk and into llms.txt, where the persona clause
- would push the title past the search-result truncation length. #}
- {{ site.messaging.heroTagLine | safe }}
-
- {% image "./images/home/flowfuse-home-ui.png", "FlowFuse Home UI", [960] %}
-
-
-
-
-
-
-
-
-
-
- {% set socialProofEyebrowBg = true %}
- {% include "social-proof.njk" %}
-
-
-
-
-
-
- {% for metric in metrics %}
-
-
{{ metric.number }}
-
{{ metric.text | safe }}
-
- {% endfor %}
-
-
-
-
-
-
-
Industrial innovation is accelerating. Execution is not.
-
Teams can access data and build applications faster than ever. But the operational logic that drives throughput, quality, and response still lives in custom code, isolated scripts, and one-off solutions that don't scale.
-
-
- {% for section in sections %}
-
-
-
-
- {% include section.svgPath %}
-
-
-
- {{ section.title }}
-
-
-
-
-
{{ section.description | safe }}
-
-
-
- {% endfor %}
-
-
-
-
-
-
$50B
-
Annual cost of unplanned downtime across industrial manufacturers globally
-
-
-
800h
-
Average equipment downtime per year experienced by manufacturers (over 15 hours per week)
-
-
-
-
-
-
-
-
The missing operational layer
-
FlowFuse is the industrial application platform that sits between your systems and your operations
-
Whether you're extending an existing system, standardizing a proven solution across sites, or connecting OT and IT data flows, FlowFuse gives your team the platform to build once and run everywhere.
Every problem solved becomes a reusable application
-
-
That's how a small team manages operations across dozens of sites, without rebuilding from scratch every time.
-
Ready to build yours?
-
- {{ ctaBookDemo('highlight', 'oas') }}
-
-
-
-
-
-
-
-
-
-
-
-
-
Real results from industrial teams
-
See how manufacturers and industrial operators are using FlowFuse to standardize, scale, and govern their operations.
- {% set hideReadMore = true %}
- {% set browseAllUrl = "/customer-stories/" %}
- {% set browseAllText = "Browse all customer stories" %}
- {% include "testimonials.njk" %}
-
-
-
-
-
-
-
-
AI in industrial operations
-
AI makes building faster. FlowFuse makes it operational.
-
-
-
-
-
- {% include "components/icons/bolt.svg" %}
-
-
AI accelerates the build
-
-
FlowFuse Expert, our industrial-tuned AI assistant, lets your team describe what they need in plain language, and generates flows, data transformations, and dashboard logic. No waiting on scarce developers.
- {% include "components/icons/shield-check.svg" %}
-
-
FlowFuse governs the result
-
-
Speed without governance creates new debt. FlowFuse provides the production layer where AI-assisted work becomes visible, versioned, secure, and reusable, across the enterprise.
-
- {#- No plain-text-link variant exists yet in the shared Cta*
- system (CLAUDE.md reserves `text` for that), and ghost is
- too heavy (bold/uppercase/button padding) for this inline
- sentence-style link - kept hand-written until that variant
- exists, but still fires the same unified event/props
- shape as the real CtaBookDemo would, tagged variant="text"
- so it's identifiable in PostHog as this one-off style. -#}
-
- Book a demo
- {% include "components/icons/arrow-long-right.svg" %}
-
-
-
-
-
-
-
-
-
-
Frequently Asked Questions
-
- {% include "faq.njk" %}
-
-
-
-
-
-
- {% set cta = {
- title: "Get Started with FlowFuse",
- description: "Your first operational application could be running this week. Book a demo to see how, or start a free trial and build it yourself.",
- buttonText: "BOOK A DEMO",
- buttonLink: "/book-demo/",
- position: "get-started"
- } %}
- {% include "cta-get-started.njk" %}
-
-