Skip to content

Golden Path β€” Vue structure ​

Only the widget folder contract is raclette-specific. How you structure Vue code beyond that is your choice; this page describes what we recommend when multiple widgets or larger features share code.

*Widget.vue is the entry ​

<Name>Widget.vue is the mount point the orchestrator loads. It should:

  • call usePluginApi() in setup(),
  • declare props (including route-driven slotParams),
  • compose child components and composables.

It should not accumulate all business logic when the feature grows.

Reuse across widgets ​

FolderPurpose
frontend/components/Presentational pieces shared by 2+ widgets
frontend/composables/Stateful logic, $data calls, formatters
frontend/types/Shared TypeScript types (optional)
frontend/
β”œβ”€β”€ index.ts
β”œβ”€β”€ widgets/
β”‚   β”œβ”€β”€ TodoList/
β”‚   β”‚   β”œβ”€β”€ TodoListWidget.vue
β”‚   β”‚   └── setup.ts
β”‚   └── TodoChart/
β”‚       β”œβ”€β”€ TodoChartWidget.vue
β”‚       └── setup.ts
β”œβ”€β”€ components/
β”‚   └── TodoRow.vue          # used by both widgets
└── composables/
    └── useTodoItems.ts

Import freely between widgets, components, and composables β€” standard Vue 3 module boundaries.

Vue best practices (brief) ​

  • Composition API in widgets (<script setup> is fine).
  • Keep side effects in composables with onUnmounted cleanup; usePluginApi cleans up $socket listeners on unmount.
  • Workbench-tuned values belong in setup.ts config editors, not hard-coded in the widget.
  • Pagination / filters β€” persist via URL slotParams, not only local state (Writing URL state).

Minimal layout ​

One self-contained *Widget.vue is acceptable for trivial UI. Move to the structure above when you add a second widget or shared behavior.

Cookbook ​

End-to-end files: Cookbook Β· Setting up a Todo plugin.

See also ​