Skip to content

Routing & URL state (advanced) ​

Plugins do not register Vue Router routes. The orchestrator encodes which composition fills each slot and which parameters apply β€” mainly in the app page path. Widgets receive those parameters as props; you read and write state with useRouteState().

Outline

This page is split into reading (what the URL means for your widget) and writing (how to change the URL, including pagination after reload).

Background (brief) ​

On dynamic pages the workbench already defined a default layout. The URL customizes that session state (slot β†’ composition, slotParams) β€” it does not create new composition types from scratch.

Low-level grammar lives in compose() (routeParser.ts). Product code normally uses CompositionSlot[] via parseRouteToCompositionSlots() (routeParserHelper.ts). Vue Router integration (routeStore.ts) diffs slots and dispatches store updates β€” plugins should use useRouteState, not routeStore directly.

For the full technical URL grammar (setters, assignments, anchors), see internal orchestrator URL documentation; the sections below focus on what plugin authors do.


Reading URL state ​

What you get ​

typescript
import useRouteState from "@raclettejs/core/orchestrator/composables/useRouteState"

const { compositionSlots } = useRouteState()

compositionSlots is a reactive list of CompositionSlot:

FieldMeaning
slotNamee.g. page (default), modal, inline
slotValueComposition pathname
slotParamsParameters from the URL (string / number / boolean after coercion)

Prefer props over parsing ​

WidgetsLayoutLoader merges slotParams for the widget’s slotType onto your component together with workbench config:

typescript
defineProps<{
  page?: number
  itemId?: string
  compositionName?: string
  slotType?: string
}>()

Declare prop names that match the keys you write into slotParams (see Writing URL state).

Read one slot ​

typescript
const { getCompositionLinkForSlotName } = useRouteState()
const pageSlot = getCompositionLinkForSlotName("page")
// pageSlot.value?.slotParams?.page

Debugging ​

composed exposes raw compose(route.fullPath) output when you need to compare URL strings with parsed slots.


Writing URL state ​

Update a slot (navigation) ​

typescript
const { updateSlot } = useRouteState()

updateSlot({
  slotName: "page",
  slotValue: "myListComposition",
  slotParams: {
    page: "2",
    pageSize: "20",
  },
})

updateSlot builds the URL and **router.push**es. Parameters are URL-encoded; use string values in slotParams when in doubt (coercion handles numbers/booleans on read).

Remove a slot ​

typescript
const { removeSlot } = useRouteState()
removeSlot("modal")

When admins configured interaction links in workbench, prefer:

typescript
const { triggerInteractionLinkById } = useRouteState()
triggerInteractionLinkById(linkId, { page: "1" })

See Workbench β€” Interaction links.


Pagination and reload ​

Raclette apps should restore UI state from the URL after refresh or shared links. Treat page index, filters, and selected ids as slotParams, not only in-memory widget state.

Pattern ​

  1. Write β€” when the user changes page, call updateSlot (or merge into the current slot) with slotParams: { page: String(page) }.
  2. Read β€” on mount, read page from props (from slotParams) and pass to $data queries.
  3. Defaults β€” if page is missing, default to 1 in the widget, but write back on first interaction so the URL reflects reality.
typescript
const props = defineProps<{ page?: string }>()
const currentPage = computed(() => Number(props.page ?? 1))

watch(currentPage, (p) => {
  updateSlot({
    slotName: "page",
    slotValue: compositionName, // from props or route
    slotParams: { page: String(p), pageSize: "20" },
  })
})

If pagination state lives only in $store or local refs, a full reload loses the current page β€” that is why writing slotParams is required for list widgets.

Partial updates ​

updateSlot replaces the targeted slot’s params via getInteractionLinkUrl (merge with existing slot, then navigate). Include all params you need to keep when changing one field, or re-read compositionSlots before merging.


API reference (quick) ​

useRouteState()Use
compositionSlotsRead all active slots
updateSlotNavigate with new slot + params
removeSlotClear a slot by name
getCompositionLinkForSlotNameReactive single slot
triggerInteractionLink / triggerInteractionLinkByIdWorkbench-defined navigation
getCurrentCompositionIdResolve composition id from path

See also ​