putyourlightson / laravel-datastar
A reactive hypermedia framework for Laravel.
Fund package maintenance!
bencroker
Requires
- php: ^8.2
- laravel/framework: ^11.0
- starfederation/datastar-php: 1.0.0-beta.6
Requires (Dev)
- craftcms/ecs: dev-main
- craftcms/phpstan: dev-main
- pestphp/pest: ^3.0
This package is auto-updated.
Last update: 2025-01-13 19:38:28 UTC
README
Datastar Package for Laravel
A reactive hypermedia framework for Laravel.
Warning
This package is in beta and its API may change.
This package integrates the Datastar hypermedia framework with Laravel, allowing you to create reactive frontends driven by Blade views or controllers. It aims to replace the need for front-end frameworks such as React, Vue.js and Alpine.js + htmx, and instead lets you manage state and use logic from your Laravel backend.
Use-cases:
- Live search and filtering
- Loading more elements / Infinite scroll
- Paginating, ordering and filtering lists
- Submitting forms and running actions
- Pretty much anything to do with reactive front-ends
License
This package is licensed for free under the MIT License.
Requirements
This package requires Laravel 11.0.0 or later.
Installation
Install manually using composer.
composer require putyourlightson/laravel-datastar:^1.0.0-beta.1
Overview
The Datastar package for Laravel allows you to handle backend requests by sending SSE events using Blade directives in views or using controllers. The former requires less setup and is more straightforward, while the latter provides more flexibility.
Here’s a trivial example that toggles some backend state using the Blade view _datastar/toggle.blade.php
to handle the request.
<div data-signals-enabled="false"> <div data-text="$enabled ? 'ON' : 'OFF'"></div> <button data-on-click="{{ datastar()->get('_datastar/toggle') }}"> <span id="button-text">Enable</span> </button> </div>
{{-- _datastar/toggle.blade.php --}} @php $enabled = $signals->enabled; // Do something with the state and toggle the enabled state. $enabled = !$enabled; @endphp @mergesignals(['enabled' => $enabled]) @mergefragments <span id="button-text"> {{ $enabled ? 'Disable' : 'Enable' }} </span> @endmergefragments
Usage
Start by reading the Getting Started guide to learn how to use Datastar on the frontend. The Datastar package for Laravel only handles backend requests.
Note
The Datastar VSCode extension and IntelliJ plugin have autocomplete for all data-*
attributes.
When working with signals, note that you can convert a PHP array into a JSON object using the json_encode
function.
@php $signals = ['foo' => 1, 'bar' => 2]; @endphp <div data-signals="{{ json_encode($signals) }}"></div>
Datastar Helper
The datastar()
helper function is available in Blade views and returns a Datastar
helper that can be used to generate action requests to the Datastar controller. The Datastar controller renders a view containing one or Blade directives that each send an SSE event. Signals are also sent as part of the request, and are made available in Datastar views using the $signals
variable.
datastar()->get()
Returns a @get()
action request to render a view at the given path.
{{ datastar()->get('path/to/view') }}
datastar()->post()
Works the same as datastar()->get()
but returns a @post()
action request to render a view at the given path. A CSRF token is automatically generated and sent along with the request.
{{ datastar()->post('path/to/view') }}
datastar()->put()
Works the same as datastar()->post()
but returns a @put()
action request.
{{ datastar()->put('path/to/view') }}
datastar()->patch()
Works the same as datastar()->post()
but returns a @patch()
action request.
{{ datastar()->patch('path/to/view') }}
datastar()->delete()
Works the same as datastar()->post()
but returns a @delete()
action request.
{{ datastar()->delete('path/to/view') }}
Blade Directives
@mergefragments
Merges one or more fragments into the DOM.
@mergefragments <div id="new-fragment">New fragment</div> @endmergefragments
@removefragments
Removes one or more HTML fragments that match the provided selector from the DOM.
@removefragments('#old-fragment')
@mergesignals
Updates the signals with new values.
@mergesignals(['foo' => 1, 'bar' => 2])
@removesignals
Removes signals that match one or more provided paths.
@removesignals(['foo', 'bar'])
@executescript
Executes JavaScript in the browser.
@executescript alert('Hello, world!'); @endexecutescript
Using Controllers
You can send SSE events using your own controller instead of a Blade view using the DatastarEventStream
trait. Return the getStreamedResponse()
method, passing a callable into it that sends zero or more SSE events using methods provided.
// routes/web.php use App\Http\Controllers\MyController; Route::resource('/my-controller', MyController::class);
<?php namespace App\Http\Controllers; use Illuminate\Routing\Controller; use Putyourlightson\Datastar\DatastarEventStream; use Symfony\Component\HttpFoundation\StreamedResponse; class MyController extends Controller { use DatastarEventStream; public function index(): StreamedResponse { return $this->getStreamedResponse(function() { $signals = $this->getSignals(); $this->mergeSignals(['enabled' => $signals->enabled ? false : true]); $this->mergeFragments(' <span id="button-text">' . ($signals->enabled ? 'Enable' : 'Disable') . '</span> '); }); } }
DatastarEventStream Trait
mergeFragments()
Merges one or more fragments into the DOM.
$this->mergeFragments('<div id="new-fragment">New fragment</div>');
removeFragments()
Removes one or more HTML fragments that match the provided selector from the DOM.
$this->removeFragments('#old-fragment');
mergeSignals()
Updates the signals with new values.
$this->mergeSignals(['foo' => 1, 'bar' => 2]);
removeSignals()
Removes signals that match one or more provided paths.
$this->removeSignals(['foo', 'bar']);
executeScript()
Executes JavaScript in the browser.
$this->executeScript('alert("Hello, world!")');
Signals
When working with signals, either in views rendered by the Datastar controller or by calling $this->getSignals()
, you are working with a Signals model, which provides a simple way to manage signals.
@php // Getting signal values. $username = $signals->username; $username = $signals->get('username'); $username = $signals->get('user.username'); // Setting signal values. $username = $signals->username('bobby'); $username = $signals->set('username', 'bobby'); $username = $signals->set('user.username', 'bobby'); $username = $signals->setValues(['user.username' => 'bobby', 'success' => true]); // Removing signal values. $username = $signals->remove('username'); $username = $signals->remove('user.username'); @endphp
Note
Signals updates cannot be wrapped in {% mergefragment %}
tags, since each update creates a server-sent event which will conflict with the fragment’s contents.
Created by PutYourLightsOn.