diff --git a/nuxt/content.config.ts b/nuxt/content.config.ts index 3b2ca98e0e..76d07e872c 100644 --- a/nuxt/content.config.ts +++ b/nuxt/content.config.ts @@ -145,12 +145,14 @@ export default defineContentConfig({ highlight: z.boolean().optional(), order: z.number(), features: z.array(z.string()), + bestFitFor: z.array(z.string()).optional(), button: z.object({ label: z.string(), to: z.string(), external: z.boolean().optional(), color: z.enum(['primary', 'secondary', 'highlight']).optional(), variant: z.enum(['solid', 'outline', 'soft', 'subtle', 'ghost', 'link']).optional(), + event: z.string().optional(), }), }) }), diff --git a/nuxt/content/feature-catalog.yml b/nuxt/content/feature-catalog.yml index abc283bf3b..b4f439dcdd 100644 --- a/nuxt/content/feature-catalog.yml +++ b/nuxt/content/feature-catalog.yml @@ -89,6 +89,14 @@ sections: - id: secure title: Secure features: + - id: certified-nodes-it + title: Certified Nodes - IT + description: "IT certified node bundle includes: Redis, MQTT, HTTP Request, AI nodes (Gemini, Claude, ChatGPT, Ollama), MCP Server" + tiers: { edge: false, hub: true } + - id: certified-nodes-ot + title: Certified Nodes - OT + description: "OT certified node bundle includes: OPC-UA, Modbus TCP & RTU, RTSP, EtherNet/IP, AI nodes (Gemini, Claude, ChatGPT, Ollama), MCP Server" + tiers: { edge: true, hub: false } - id: audit-log title: Audit Log tiers: { edge: true, hub: true } @@ -110,14 +118,6 @@ sections: - id: single-sign-on title: Single Sign-On (SSO) tiers: { edge: true, hub: true } - - id: certified-nodes-it - title: Certified Nodes - IT - description: "IT certified node bundle includes: Redis, MQTT, HTTP Request, AI nodes (Gemini, Claude, ChatGPT, Ollama), MCP Server" - tiers: { edge: false, hub: true } - - id: certified-nodes-ot - title: Certified Nodes - OT - description: "OT certified node bundle includes: OPC-UA, Modbus TCP & RTU, RTSP, EtherNet/IP, AI nodes (Gemini, Claude, ChatGPT, Ollama), MCP Server" - tiers: { edge: true, hub: false } - id: baa-for-hipaa title: BAA for HIPAA tiers: { edge: false, hub: true } diff --git a/nuxt/content/plans/edge.yml b/nuxt/content/plans/edge.yml index f8bff5ea23..3484ee3804 100644 --- a/nuxt/content/plans/edge.yml +++ b/nuxt/content/plans/edge.yml @@ -1,17 +1,20 @@ title: Edge tierId: edge order: 1 -description: Deploy, manage and scale industrial applications across production sites with centralized governance and certified industrial connectivity. +description: Deploy, manage, and scale industrial applications across your sites with centralized governance and certified industrial connectivity. badge: For OT teams features: - - Industrial applications - - PLC & machine connectivity - - OT-certified nodes - - MQTT Broker - - DevOps Pipelines + - Device Fleet Updates - Device Group Management + - "Certified Nodes: OT" + - Blueprints - OT APPS +bestFitFor: + - OT teams connecting PLCs, machines, and systems + - Businesses standardising and deploying automation across multiple sites + - Standard deployments across multiple sites. button: label: Contact us to: /contact-us/ external: true - variant: solid \ No newline at end of file + variant: solid + event: cta-contact-us \ No newline at end of file diff --git a/nuxt/content/plans/hub.yml b/nuxt/content/plans/hub.yml index e65d608349..8130a26031 100644 --- a/nuxt/content/plans/hub.yml +++ b/nuxt/content/plans/hub.yml @@ -1,17 +1,22 @@ title: Hub tierId: hub order: 2 -description: Integrate and orchestrate data across enterprise systems, APIs and databases with centralized governance. +description: Integrate and orchestrate data across enterprise systems, APIs and databases with centralised governance. badge: For IT teams features: - - Business system integration - - Data orchestration - - IT-certified nodes - Git Integration - High Availability - - DevOps Pipelines + - BAA for HIPAA + - Protected Instances + - Certified Nodes - IT + - Blueprints - IT APPS +bestFitFor: + - IT teams moving data between ERPs, databases, and cloud APIs. + - Complex data sets that need governed integration and orchestration. + - Custom deployments at the data and orchestration level. button: - label: Contact us - to: /contact-us/ + label: START FREE TRIAL + to: https://app.flowfuse.com/account/create external: true - variant: solid \ No newline at end of file + variant: solid + event: cta-join \ No newline at end of file diff --git a/nuxt/pages/pricing/index.vue b/nuxt/pages/pricing/index.vue index 5f7c505a53..2f5cf7dafa 100644 --- a/nuxt/pages/pricing/index.vue +++ b/nuxt/pages/pricing/index.vue @@ -7,6 +7,8 @@ const tableTiers = computed(() => (plans.value ?? []).map(p => ({ id: p.tierId, title: p.title, highlight: p.highlight, + button: p.button, + bestFitFor: p.bestFitFor, }))) const faqAccordionItems = computed(() => (faq.value?.items ?? []).map(item => ({ @@ -14,6 +16,28 @@ const faqAccordionItems = computed(() => (faq.value?.items ?? []).map(item => ({ content: item.answer, }))) +// The comparison table should only show features that differ between tiers. +// Features shared by every tier don't belong in a comparison — they're listed +// separately below as a plain "core features" dump, grouped by their original +// category so ~37 shared features don't read as one undifferentiated list. +const comparisonSections = computed(() => (featureCatalog.value?.sections ?? []) + .map(section => ({ ...section, features: section.features.filter(f => f.tiers.edge !== f.tiers.hub) })) + .filter(section => section.features.length > 0)) + +const coreFeatureSections = computed(() => (featureCatalog.value?.sections ?? []) + .map(section => ({ ...section, features: section.features.filter(f => f.tiers.edge === f.tiers.hub) })) + .filter(section => section.features.length > 0)) + +// window.capture is injected by the site's analytics script (see +// src/_includes/analytics/body.html) and is a no-op wrapper around +// posthog.capture — it's absent outside production, hence the guard. +function capture (eventName?: string, props?: Record) { + if (!eventName) return + if (typeof (window as any).capture === 'function') { + (window as any).capture(eventName, props) + } +} + // UPricingTable's feature-title slot types `feature` without `description`, // even though the featureCatalog content schema does define it. interface CatalogFeature { @@ -24,6 +48,13 @@ function featureDescription (feature: CatalogFeature) { return feature.description } +useSeoMeta({ + title: 'FlowFuse Pricing', + description: 'Packages built around the job, deploying and scaling automation across plants, or integrating the business systems and data sources you run on. All governed on one platform.', + ogUrl: 'https://flowfuse.com/pricing/', + twitterSite: '@FlowFuseinc', +}) + useSchemaOrg([ defineWebPage({ '@type': 'FAQPage' }), ...(faq.value?.items ?? []).map(item => defineQuestion({ @@ -38,27 +69,70 @@ useSchemaOrg([

FlowFuse Pricing

Choose the package that fits your team

-

Machines on the shop floor, scaling to more plants? Or business systems and data sources to bring under governance? There’s a FlowFuse package for both.

+

Whether you’re connecting one plant or standardizing across hundreds of business systems, FlowFuse has a product for you.

- + + + + + -

FlowFuse Comparison

+

FlowFuse Comparison

+ + +
+

FlowFuse Core Features

+

Included in every FlowFuse plan

+
+
+

{{ section.title }}

+
    +
  • + + {{ feature.title }} +
  • +
+
+
+
+

diff --git a/src/css/style.css b/src/css/style.css index 88e522ae3f..5150bbe45d 100644 --- a/src/css/style.css +++ b/src/css/style.css @@ -151,6 +151,7 @@ html, body { font-size: 16px; font-family: var(--font-sans); scroll-padding-top: 75px; + scroll-behavior: smooth; background-color: white; }