Skip to content

Examples ​

These examples use the same FlowViewer component you import in an app. Use the previews to check how common Node-RED export shapes render before wiring your own data.

Basic flow preview ​

Groups preview ​

HTTP API preview ​

MQTT routing preview ​

Subflows preview ​

Subflow definitions render as their own tabs, and subflow instances render as regular nodes on the parent tab.

Basic readonly viewer ​

Use this when you want to embed a Node-RED flow as documentation, a status page, or a support view.

vue
<script setup lang="ts">
import { FlowViewer } from 'vue-node-red-flow-viewer'
import 'vue-node-red-flow-viewer/style.css'
import flow from './flow.json'
</script>

<template>
  <div class="flow-viewer">
    <FlowViewer :flow-data="flow" />
  </div>
</template>

<style scoped>
.flow-viewer {
  height: 520px;
}
</style>

Multi-tab flow with tab switching ​

Use v-model:flow-id when the parent needs to show or store the active tab. The viewer still renders its built-in tabs when the export contains more than one tab or subflow.

vue
<script setup lang="ts">
import { computed, ref } from 'vue'
import { FlowViewer } from 'vue-node-red-flow-viewer'
import type { NodeRedNode } from 'vue-node-red-flow-viewer'
import 'vue-node-red-flow-viewer/style.css'
import flow from './flow.json'

const flowData = flow as NodeRedNode[]

const tabs = computed(() =>
  flowData
    .filter((node) => node.type === 'tab' || node.type === 'subflow')
    .map((node) => ({
      id: node.id,
      label: node.label || node.name || node.id,
    })),
)

const activeFlowId = ref(tabs.value[0]?.id ?? null)
</script>

<template>
  <section class="flow-layout">
    <header class="flow-toolbar">
      <button
        v-for="tab in tabs"
        :key="tab.id"
        type="button"
        :class="{ active: tab.id === activeFlowId }"
        @click="activeFlowId = tab.id"
      >
        {{ tab.label }}
      </button>
    </header>

    <FlowViewer v-model:flow-id="activeFlowId" :flow-data="flowData" />
  </section>
</template>

<style scoped>
.flow-layout {
  height: 620px;
  display: flex;
  flex-direction: column;
  border: 1px solid #d4d4d4;
}

.flow-toolbar {
  display: flex;
  gap: 8px;
  padding: 8px;
  border-bottom: 1px solid #d4d4d4;
}

.flow-toolbar button {
  padding: 6px 10px;
  border: 1px solid #c7c7c7;
  background: #ffffff;
  cursor: pointer;
}

.flow-toolbar button.active {
  border-color: #8f0000;
  color: #8f0000;
}
</style>

Custom-themed dark viewer ​

Use CSS variables when the viewer needs to match an application theme.

vue
<script setup lang="ts">
import { FlowViewer } from 'vue-node-red-flow-viewer'
import 'vue-node-red-flow-viewer/style.css'
import flow from './flow.json'
</script>

<template>
  <div class="flow-viewer dark-flow">
    <FlowViewer
      :flow-data="flow"
      :options="{
        gridlines: true,
        images: true,
        labels: true,
        linklines: true,
      }"
    />
  </div>
</template>

<style scoped>
.flow-viewer {
  height: 520px;
}

.dark-flow {
  --nr-flow-bg: #111820;
  --nr-grid-color: #2e4053;
  --nr-border-color: #465667;
  --nr-accent-color: #ff6b5f;
  --nr-wire-color: #9fb4c8;
  --nr-port-color: #56687a;
  --nr-port-border-color: #b3c3d2;
  --nr-tab-bg: #18222d;
  --nr-tab-active-bg: #253443;
  --nr-tab-hover-bg: #22303e;
  --nr-tab-text: #bfccd8;
  --nr-tab-active-text: #ffffff;
  --nr-btn-bg: #253443;
  --nr-btn-bg-hover: #314456;
}
</style>

Not affiliated with, endorsed by, or sponsored by Node-RED or nodered.org.