Skip to content

Nuxt Module ​

Wraps @macrulez/visual-linker-vue for Nuxt — auto-imports <VisualLinker> and useVisualLinker, registers the v-vl-block/v-vl-port directives, and makes the visualLinker key of nuxt.config.ts the shared configuration of every diagram in the project.

ts
// nuxt.config.ts
export default defineNuxtConfig({
  modules: ['@macrulez/visual-linker-nuxt'],

  visualLinker: {
    theme: { line: '#6366f1', lineHover: '#312e81' },
    lines: { curve: 'smoothstep', jumps: true },
    markers: { end: { shape: 'arrow', hover: { size: 10 } } },
    blocks: { draggable: true, drag: { grid: 20 } },
  },
})

The options of the module are exactly the engine's configuration; to change them while the app runs, see Shared Configuration.

Configuration ​

The visualLinker key is a VisualLinkerConfig — the same object that createVisualLinker() and the config prop of <VisualLinker> take, so there is no separate list of module-only names to learn. Its groups:

  • theme — color tokens, written as CSS variables. See Themes.
  • lines — curve, color, width, dashed, opacity, the visual states, bezier, smoothstep, routing, jumps, animated.
  • markers — start and end markers, with their own states, and the per-shape sizes.
  • ports — the built-in dot (show, radius, fill, stroke, the states), the default side and offset, and spread.
  • labels — the look of library-drawn connection labels, with states.
  • blocks — draggable and drag: { grid, bounds }.
  • interaction — hover, highlight, selectable and clipToScrollParents.

Every group and field is described in Configuration. Everything is optional, and the module hardcodes no default of its own: a field left out falls through to the engine's built-in value, so a future change to core's default is never silently shadowed by the Nuxt layer.

The options travel through runtimeConfig.public.visualLinker, so they must be plain JSON data: strings, numbers, booleans, objects and arrays. For blocks.drag.bounds that means 'container' or an inset object, not an HTMLElement — an element can still be given to one diagram through its own config or a block.

Example — every group at once:

ts
// nuxt.config.ts
export default defineNuxtConfig({
  modules: ['@macrulez/visual-linker-nuxt'],

  visualLinker: {
    theme: { line: '#6366f1', lineHover: '#312e81', portFill: '#ffffff' }, // colors in one place
    lines: {
      curve: 'smoothstep', // orthogonal routing for every connection
      width: 2,
      hover: { width: 3 }, // thicker under the pointer
      smoothstep: { cornerRadius: 10 }, // rounder bends than the 8px default
      routing: { avoidObstacles: true, padding: 12 }, // go around other blocks
      jumps: { radius: 6 }, // hop over crossing lines
      animated: { shape: 'dots', speed: 50 }, // a dotted pattern flows along every line
    },
    markers: {
      end: { shape: 'arrow', hover: { size: 10 } }, // an arrowhead that grows on hover
      sizes: { arrow: 8 }, // arrowheads a bit bigger than the other shapes
    },
    ports: { radius: 5, hover: { radius: 7 }, spread: { gap: 16, padding: 8 } }, // bigger dots, spread over a shared side
    labels: { background: '#ffffff', fontSize: 12 }, // the pill behind label text
    blocks: { draggable: true, drag: { grid: 20, bounds: 'container' } }, // every block can be dragged
    interaction: { hover: true, highlight: true, selectable: true, clipToScrollParents: 'pin' }, // reacting, keyboard-operable lines
  },
})

Changing it at runtime ​

The module installs the configuration as the app-wide shared configuration, a reactive object, so any component can change it and every diagram follows — for example to switch themes:

ts
import { darkTheme, useVisualLinkerConfig } from '@macrulez/visual-linker-vue'

const shared = useVisualLinkerConfig()
shared.theme = darkTheme

A call site's own config still wins over it, field by field.

Registration ​

The module automatically:

  • Registers <VisualLinker> as a global component
  • Auto-imports useVisualLinker
  • Registers the v-vl-block/v-vl-port directives in a universal plugin — on the server too, so the data-vl-* discovery attributes are already in the server-rendered HTML
  • Installs the visualLinker configuration in that same plugin as the shared configuration for every <VisualLinker>/useVisualLinker() call, which merge it under their own config

<VisualLinker> and useVisualLinker are already SSR-safe on the server — the engine and its drawing layer only exist client-side, after mount. No <ClientOnly> wrapper is needed anywhere.