x-flow-run-button

Triggers a workflow run by calling $flow.run(startId, handlers, options) against the surrounding canvas. JavaScript handlers (onEnter, pickBranch, …) can't be serialized from PHP, so the component reads them from a property on the canvas DOM element — pre-register on <x-flow> via x-init.

<x-flow
    :nodes="$nodes"
    :edges="$edges"
    x-init="$el.runHandlers = {
        onEnter: async (node, ctx) => { /* ... */ },
        pickBranch: (node, edges, ctx) => edges[0].id,
    }"
>
    <x-flow-panel position="top-right">
        <x-flow-run-button start-id="trigger" />
    </x-flow-panel>
</x-flow>

The button auto-disables while canvas.runState is running or paused.

Props

Prop Type Required Purpose
start-id string yes Node ID to start the run from.
options array no Forwarded to $flow.run()payload, defaultDurationMs, particleOnEdges, particleOptions, muteUntakenBranches, lock, logLimit.
handlers-key string no Property name on the canvas DOM element holding the handlers object. Defaults to runHandlers.
target string no CSS selector for the canvas when used outside it.

Slot

Default content is the running-state-aware label: Run workflow / Running…. Slot content overrides both:

<x-flow-run-button start-id="trigger">
    <span class="flex items-center gap-2">
        <i class="i-heroicons-play"></i>
        Start onboarding
    </span>
</x-flow-run-button>

When you take over the slot, you also opt out of the default label swap. Handle the running state yourself if you need it via x-show against isRunning from the surrounding scope.

Server-driven path

Consumers that prefer the server side can ignore the JS handlers route and use wire:click against WithWireFlow::flowRun():

<button type="button" wire:click="$call('flowRun', 'trigger')">Run from server</button>

The standard Livewire loading state handles the disabled-during-dispatch UX.