@macrulez/visual-linker-nuxt
Visual Linker Nuxt

Nuxt module wrapping
@macrulez/visual-linker-vue:
auto-imported <VisualLinker>/useVisualLinker, and a shared configuration
of every diagram taken from your nuxt.config.ts — no manual <ClientOnly>
wrapping needed, both are already SSR-safe on their own.
Part of the visual-linker monorepo.
Features
- Auto-imports
<VisualLinker>,useVisualLinkeranduseVisualLinkerConnect— registered/imported from@macrulez/visual-linker-vue, no explicitimportanywhere in your app - Registers
v-vl-block/v-vl-portglobally — on the server too, so thedata-vl-*discovery attributes are already in the server-rendered HTML - The whole configuration, set once —
visualLinkerinnuxt.config.tstakes the same structure as the engine (theme,lines,markers,ports,labels,blocks,interaction,performance), applied to every diagram - The configuration is shared through Vue's
provide— one reactive object per app, whichuseVisualLinkerConfig()exposes for runtime changes (a theme switch re-styles every diagram) - Nothing needs
<ClientOnly>— the component/composable are SSR-safe on their own
When you'd reach for this
You're already on Nuxt and want <VisualLinker>/useVisualLinker wired
up with zero manual setup — auto-imports, and one place to configure
style, theme and behavior in one structured config instead of passing the
same config at every call site.
- Passing the same
configto every<VisualLinker>on the page gets old — Setlines/ports/theme/etc. once innuxt.config.tsand every instance that doesn't override them picks up your project's defaults automatically. - You'd rather not remember to import the component in every page — Auto-imports mean
<VisualLinker>/useVisualLinker()are just available, the same way Nuxt's own built-ins are. - A team member reaches for
<ClientOnly>out of habit — There's nothing to wrap. Both already render an SSR-safe no-op and pick up the real diagram after hydration on their own.
Installation
npm install @macrulez/visual-linker-nuxt
// nuxt.config.ts
export default defineNuxtConfig({
modules: ['@macrulez/visual-linker-nuxt'],
visualLinker: {
lines: { curve: 'smoothstep' },
ports: { show: true },
},
})
Requires Nuxt ^3.9.0 || ^4.0.0.
Quick start
Once the module is registered, just use the component — no imports:
<template>
<VisualLinker :connections="connections">
<div v-for="b in blocks" :key="b.id" v-vl-block="b.id" class="card">{{ b.id }}</div>
</VisualLinker>
</template>
See
@macrulez/visual-linker-vue's README
for the full component/composable API.
More examples
What the module does
- Auto-imports
<VisualLinker>as a global component anduseVisualLinker/useVisualLinkerConnectas auto-imports, all sourced from@macrulez/visual-linker-vue— no explicitimportneeded in your components. - Forwards module options into
runtimeConfig.public.visualLinker. - Registers one universal plugin (
runtime/plugin.ts): thev-vl-block/v-vl-portdirectives — on the server too, so thedata-vl-*attributes are already in the SSR markup — and the app-wide shared config, taken from that runtime config. Every<VisualLinker>/useVisualLinker()merges it under its ownconfig, anduseVisualLinkerConfig()(from@macrulez/visual-linker-vue) hands you the same reactive object to change at runtime, e.g. to switch the theme.
No defaults are hardcoded in the module itself — a field left unset in
nuxt.config.ts falls all the way through to
@macrulez/visual-linker-core's own built-in default, so a future change
to core's default is never silently shadowed by this module.
Module options
The visualLinker key is a VisualLinkerConfig — exactly the object
createVisualLinker() and <VisualLinker :config> take, so there is no
separate list of module-only names to learn:
| Group | What it configures |
|---|---|
theme |
color tokens, written as CSS variables — lightTheme/darkTheme or your own |
lines |
curve, color/width/dashed, hover/selected/focus, bezier, smoothstep, routing, jumps, animated |
markers |
start/end markers (with their own states) and per-shape sizes |
ports |
the built-in dot (show, radius, fill, stroke, states), default side/offset, spread |
labels |
the look of library-drawn connection labels, with states |
blocks |
draggable, drag: { grid, bounds } (values must be plain data — 'container' or an inset object) |
interaction |
hover, highlight, selectable, clipToScrollParents, connect (without validate) |
performance |
cull and the limits for jumps and routing |
Everything is optional and nothing is hardcoded in the module: a field left
out falls through to @macrulez/visual-linker-core's own built-in default.
The options travel through runtimeConfig.public.visualLinker, so they must
be JSON-serializable (no HTMLElement for drag.bounds). interaction.connect.validate is a function, so the
module's options type leaves it out and a function passed anyway is dropped with a warning: set validate in the
config of the <VisualLinker> that needs it.
An app-wide look
// nuxt.config.ts
export default defineNuxtConfig({
modules: ['@macrulez/visual-linker-nuxt'],
visualLinker: {
theme: { line: '#6366f1', lineHover: '#312e81' },
lines: { curve: 'smoothstep', smoothstep: { cornerRadius: 10 }, jumps: true },
markers: { end: { shape: 'arrow', hover: { size: 10 } } },
blocks: { draggable: true, drag: { grid: 20 } },
},
})
Every <VisualLinker>/useVisualLinker() call in the app starts from this,
and a call site's own config overrides it field by field. The values are
also reactive at runtime: useVisualLinkerConfig().theme = darkTheme
(from @macrulez/visual-linker-vue) re-themes every diagram on the page.
Documentation & links
- 📖 Full documentation: npm.vuecraft.ru/en/packages/visual-linker
- 🌐 VueCraft: vuecraft.ru/en
- 👤 Author: macrulez.ru/en
- 💻 GitHub: macrulezru/visual-linker/packages/nuxt
- 📦 NPM: @macrulez/visual-linker-nuxt
- 🐛 Issues: github.com/macrulezru/visual-linker/issues
License
MIT
💖 Support the project
Open source takes time and effort. If this library saves you time or brings value, consider supporting further development.
Thank you for being part of this journey. ❤️
Related Packages
Reactive Vue 3 forms generated from JSON, Zod, Yup or Valibot schemas, with vali...
Reactive finite state machines and statecharts for Vue 3 — declarative transitio...
Headless Command+K palette for Vue 3 with fuzzy search, grouped and nested comma...
Nuxt module wrapping @macrulez/inview-vue: auto-imported composables/core engine...
Version History
| Version | Released | License |
|---|---|---|
| 0.4.6 | MIT | |
| 0.4.5 | MIT | |
| 0.4.3 | MIT | |
| 0.4.2 | MIT | |
| 0.4.1 | MIT | |
| 0.4.0 | MIT | |
| 0.3.0 | MIT | |
| 0.2.0 | MIT | |
| 0.1.0 | MIT |