Actions
An action runs on the server in response to a click and returns effects the client dispatches: a toast, a redirect, a component or page refresh, opening a modal. An action can both change data and drive the UI that follows.
How an action runs
Section titled “How an action runs”A click posts the action’s signed reference to its endpoint. The server verifies the reference (and the
trusted context baked into it), authorizes, runs handle(), and returns an ActionResult whose
effects the client then dispatches:
Defining an action
Section titled “Defining an action”Extend ActionDefinition and implement two methods: definition() describes the trigger (label,
icon, variant, confirmation), and handle() runs the work and returns an ActionResult. The
#[AsAction] attribute gives the action a stable id so it can be discovered and addressed by its
endpoint.
use Illuminate\Http\Request;use Lattice\Lattice\Actions\ActionDefinition;use Lattice\Lattice\Actions\ActionResult;use Lattice\Lattice\Actions\Components\Action;use Lattice\Lattice\Attributes\AsAction;use Lattice\Lattice\Ui\Enums\ButtonVariant;use Lattice\Lattice\Ui\Enums\Variant;
#[AsAction('app.products.archive')]class ArchiveProductAction extends ActionDefinition{ public function definition(Action $action): Action { return $action ->label('Archive') ->variant(ButtonVariant::Destructive) ->confirm('Archive product?', 'This hides it from the catalogue.'); }
public function handle(Request $request): ActionResult { $product = $this->product($request); $product->update(['status' => 'archived']);
return ActionResult::success() ->toast(Variant::Success, 'Product archived.') ->reloadComponent('app.products'); }}Placing an action
Section titled “Placing an action”Reference an action anywhere a component is accepted with Action::use(). The most common spot is a
table’s row actions, where ->context() scopes it to the record:
Action::use(ArchiveProductAction::class) ->context(['product_id' => $row['id']]);context() carries data from the page to the action; handle() reads it back with
$this->context($request, 'product_id'). The context is signed into the action’s reference, so it
can’t be tampered with on the way back.
Group related actions behind a single trigger with ActionGroup:
use Lattice\Lattice\Actions\Components\ActionGroup;
ActionGroup::make('row-actions')->actions([ Action::use(EditProductAction::class)->context(['product_id' => $row['id']]), Action::use(ArchiveProductAction::class)->context(['product_id' => $row['id']]),]);Render the same group inline when the actions should stay visible:
use Lattice\Lattice\Ui\Enums\Orientation;
ActionGroup::make('locale-switcher') ->label('Language') ->inline(Orientation::Horizontal) ->actions([ Action::use(SetLocaleAction::class)->context(['locale' => 'en']), Action::use(SetLocaleAction::class)->context(['locale' => 'de']), ]);The result
Section titled “The result”handle() returns an ActionResult. Start from ActionResult::success() or
ActionResult::failure(), optionally attaching data, then chain effects:
return ActionResult::success(['id' => $product->id]) ->toast('Saved.') ->reloadComponent('app.products');Authorization
Section titled “Authorization”Override authorize() to gate an action. It receives the request (with the trusted context merged
in) and returns a boolean; a denied action never reaches handle().
public function authorize(Request $request): bool{ return $this->product($request)->status !== 'archived';}Next steps
Section titled “Next steps”- Effects & results — every effect an action can return.
- Confirmation & forms — confirmation modals and collecting input before running.
- Bulk actions — acting on a table selection.