HyperResponse
The HyperResponse class is Laravel Hyper's fluent response builder for creating reactive server responses. It provides a chainable API for updating signals, patching DOM elements, executing JavaScript, and managing client-side navigation—all through server-sent events (SSE).
Creating a HyperResponse
Use the hyper() helper function to create a HyperResponse instance:
use function Dancycodes\Hyper\hyper;
public function increment()
{
return hyper()->signals(['count' => 5]);
}Signal Methods
signals()
Update reactive signals on the frontend.
signals(string|array $key, mixed $value = null): selfUpdate single signal:
return hyper()->signals('count', 10);Update multiple signals:
return hyper()->signals([
'count' => 10,
'message' => 'Updated successfully',
'isLoading' => false
]);Chaining:
return hyper()
->signals(['count' => 10])
->signals('message', 'Success!');forget()
Delete signals from the frontend signal store by setting them to null (following Datastar's deletion pattern).
forget(string|array|null $signals = null): selfDelete single signal:
return hyper()->forget('temporaryData');Delete multiple signals:
return hyper()->forget(['temp1', 'temp2', 'cache']);Delete all signals:
return hyper()->forget();Note: Locked signals (ending with _) are properly removed from server-side session storage when deleted.
View Rendering Methods
view()
Render a complete Blade view and patch it into the DOM.
view(string $view, array $data = [], array $options = [], bool $web = false): selfParameters:
$view- Blade view name (e.g.,'dashboard'or'products.index')$data- Data to pass to the view$options- Patch options (selector, mode, etc.)$web- Whether to set as fallback for non-Hyper requests
Basic usage:
return hyper()->view('dashboard', ['stats' => $stats]);With custom selector:
return hyper()->view('products.list', ['products' => $products], [
'selector' => '#product-container',
'mode' => 'inner'
]);With web fallback:
return hyper()->view('dashboard', $data, [], web: true);fragment()
Render a specific fragment from a Blade view (using @fragment directives).
fragment(string $view, string $fragment, array $data = [], array $options = []): selfParameters:
$view- Blade view containing the fragment$fragment- Fragment name (as defined in@fragment('name'))$data- Data to pass to the fragment$options- Patch options
Basic usage:
return hyper()->fragment('todos.index', 'todo-list', [
'todos' => Todo::all()
]);With options:
return hyper()->fragment('products.show', 'reviews', ['reviews' => $reviews], [
'selector' => '#reviews-section',
'mode' => 'inner'
]);Fragment in Blade:
@fragment('todo-list')
<div id="todo-list">
@foreach($todos as $todo)
<x-todo-item :todo="$todo" />
@endforeach
</div>
@endfragmentfragments()
Render multiple fragments in a single response.
fragments(array $fragments): selfParameters:
$fragments- Array of fragment configurations
Usage:
return hyper()->fragments([
[
'view' => 'dashboard',
'fragment' => 'stats',
'data' => ['stats' => $stats]
],
[
'view' => 'dashboard',
'fragment' => 'activity',
'data' => ['activities' => $activities]
]
]);DOM Manipulation Methods
All DOM manipulation methods are powered by Datastar's morphing algorithm, which intelligently updates only what changed while preserving element state, event listeners, and focus.
html()
Patch raw HTML content into the DOM.
html(string $html, array $options = []): selfUsage:
return hyper()->html('<div class="alert">Success!</div>', [
'selector' => '#notifications',
'mode' => 'prepend'
]);Morph Methods
These methods use specific Datastar patch modes. Each accepts a selector and HTML content.
outer()
Morph the outer HTML (including the element itself).
outer(string $selector, string $html): selfreturn hyper()->outer('#card', '<div id="card" class="updated">New content</div>');inner()
Morph only the inner HTML (preserving the element itself).
inner(string $selector, string $html): selfreturn hyper()->inner('#container', '<p>Updated inner content</p>');replace()
Completely replace the element (no morphing).
replace(string $selector, string $html): selfreturn hyper()->replace('#old-element', '<div id="new-element">Fresh start</div>');append()
Add HTML as the last child.
append(string $selector, string $html): selfreturn hyper()->append('#list', '<li>New item</li>');prepend()
Add HTML as the first child.
prepend(string $selector, string $html): selfreturn hyper()->prepend('#notifications', '<div class="alert">Latest!</div>');before()
Insert HTML before the element.
before(string $selector, string $html): selfreturn hyper()->before('#section', '<hr>');after()
Insert HTML after the element.
after(string $selector, string $html): selfreturn hyper()->after('#content', '<footer>End of content</footer>');remove()
Remove elements from the DOM.
remove(string $selector): selfreturn hyper()->remove('#temporary-notification');JavaScript Execution Methods
js()
Execute JavaScript code in the browser.
js(string $script, array $options = []): selfParameters:
$script- JavaScript code to execute$options- Execution optionsattributes- Array of HTML attributes for the script tagautoRemove- Whether to remove the script tag after execution (default:true)
Basic usage:
return hyper()->js('alert("Hello from server!")');With options:
return hyper()->js('console.log("Processing complete")', [
'attributes' => ['id' => 'processing-script'],
'autoRemove' => false
]);Accessing signals:
return hyper()->js('$count = $count + 1');script()
Alias for js() method.
script(string $script, array $options = []): selfreturn hyper()->script('window.scrollTo(0, 0)');Event Dispatch Methods
dispatch()
Dispatch a custom browser event (CustomEvent) from the server, enabling Livewire-style component communication.
dispatch(string $eventName, array $data = [], array $options = []): selfParameters:
$eventName- Name of the event to dispatch$data- Event data (available inevent.detail)$options- Event options:selector- Target specific elements (default: globalwindow)bubbles- Whether event bubbles (default:true)cancelable- Whether event is cancelable (default:true)composed- Whether event crosses shadow DOM boundaries (default:true)
Global event:
return hyper()->dispatch('post-created', ['id' => 123]);With data:
return hyper()->dispatch('user-login', [
'userId' => 42,
'username' => 'john_doe',
'email' => 'john@example.com'
]);Targeted dispatch:
return hyper()->dispatch('update-stats', ['count' => 5], [
'selector' => '#dashboard'
]);With custom options:
return hyper()->dispatch('notification', ['message' => 'Saved!'], [
'bubbles' => false,
'cancelable' => false
]);Chaining with other methods:
return hyper()
->signals(['count' => $newCount])
->dispatch('count-updated', ['count' => $newCount])
->fragment('dashboard', 'stats', $data);Frontend usage:
{{-- Listen for events in Blade --}}
<div data-on:post-created="$message = event.detail.id">
Waiting for post creation...
</div>
{{-- Or with JavaScript --}}
<script>
window.addEventListener('post-created', (event) => {
console.log('Post created:', event.detail.id);
});
</script>Use cases:
- Notify other components of state changes
- Trigger animations or UI updates
- Coordinate between independent page sections
- Implement pub/sub patterns
URL Management Methods
These methods update the browser's address bar without triggering a full page reload.
url()
Set the browser URL using History API.
url(mixed $url = null, string $mode = 'push'): selfParameters:
$url- URL to set (string), query parameters (array), ornullfor current URL$mode- Either'push'(default) or'replace'
Push new URL:
return hyper()->url('/dashboard');Replace current URL:
return hyper()->url('/products?page=2', 'replace');Update query parameters:
return hyper()->url(['page' => 2, 'sort' => 'name']);pushUrl()
Push a new URL to browser history (creates new history entry).
pushUrl(mixed $url = null): selfreturn hyper()->pushUrl('/users?page=2');replaceUrl()
Replace current URL in browser history (doesn't create new history entry).
replaceUrl(mixed $url = null): selfreturn hyper()->replaceUrl('/users?page=1');routeUrl()
Set URL using a Laravel route name.
routeUrl(string $routeName, array $params = [], string $mode = 'push'): selfParameters:
$routeName- Laravel route name$params- Route parameters$mode- Either'push'or'replace'
return hyper()->routeUrl('products.show', ['product' => $product->id]);pushRoute()
Push a named route to browser history.
pushRoute(string $routeName, array $params = []): selfreturn hyper()->pushRoute('users.index', ['page' => 2]);replaceRoute()
Replace current URL with a named route.
replaceRoute(string $routeName, array $params = []): selfreturn hyper()->replaceRoute('dashboard');Navigation Methods
These methods perform client-side navigation similar to single-page applications.
navigate()
Navigate to a URL using Hyper's client-side navigation.
navigate(string|array $url, string $key = 'true', array $options = []): selfParameters:
$url- Target URL (string) or query parameters (array)$key- Navigation key for targeting specific page regions$options- Navigation options:merge- Whether to merge query parameters (default: auto-detected)only- Array of query parameters to preserveexcept- Array of query parameters to excludereplace- UsereplaceStateinstead ofpushState
Basic navigation:
return hyper()->navigate('/dashboard');With navigation key:
return hyper()->navigate('/sidebar', 'sidebar');With query merging:
return hyper()->navigate('/products?page=2', 'true', ['merge' => true]);navigateWith()
Navigate with explicit merge control.
navigateWith(string|array $url, string $key = 'true', bool $merge = false, array $options = []): selfreturn hyper()->navigateWith('/products', 'main', merge: true);navigateMerge()
Navigate and merge with current query parameters.
navigateMerge(string|array $url, string $key = 'true', array $options = []): selfreturn hyper()->navigateMerge('/products?category=electronics');
// Preserves existing query parameters, adds category=electronicsnavigateClean()
Navigate with a clean slate (no query parameter merging).
navigateClean(string|array $url, string $key = 'true', array $options = []): selfreturn hyper()->navigateClean('/dashboard');
// Clears all query parametersnavigateOnly()
Navigate preserving only specific query parameters.
navigateOnly(string|array $url, array $only, string $key = 'true'): selfreturn hyper()->navigateOnly('/products?page=1', ['search', 'category']);
// Keeps search and category, resets pagenavigateExcept()
Navigate preserving all except specific query parameters.
navigateExcept(string|array $url, array $except, string $key = 'true'): selfreturn hyper()->navigateExcept('/products', ['page']);
// Keeps all parameters except page (useful for resetting pagination)navigateReplace()
Navigate using replaceState instead of pushState.
navigateReplace(string|array $url, string $key = 'true', array $options = []): selfreturn hyper()->navigateReplace('/modal');
// Doesn't add to browser historyupdateQueries()
Update query parameters while maintaining current path.
updateQueries(array $queries, string $key = 'filters', bool $merge = true): selfreturn hyper()->updateQueries(['category' => 'electronics', 'sort' => 'price']);clearQueries()
Clear specific query parameters.
clearQueries(array $paramNames, string $key = 'clear'): selfreturn hyper()->clearQueries(['page', 'sort']);resetPagination()
Reset to page 1 while preserving other filters.
resetPagination(string $key = 'pagination'): selfreturn hyper()->resetPagination();
// Sets page=1, keeps all other query parametersreload()
Force a full page reload.
reload(): selfreturn hyper()->reload();Streaming Methods
stream()
Execute a callback in streaming mode, where each method call sends events immediately instead of accumulating them.
stream(Closure $callback): selfParameters:
$callback- Function that receives theHyperResponseinstance
Usage:
return hyper()->stream(function ($hyper) {
$hyper->signals(['status' => 'Starting...']);
sleep(1);
$hyper->signals(['status' => 'Processing...']);
sleep(1);
$hyper->signals(['status' => 'Complete!']);
});Processing with progress:
return hyper()->stream(function ($hyper) {
$items = Item::all();
$total = $items->count();
foreach ($items as $index => $item) {
processItem($item);
$hyper->signals([
'progress' => (($index + 1) / $total) * 100,
'current' => $item->name
]);
}
});Exception handling in streams:
The stream callback automatically handles exceptions, redirects, and debug output (dd(), dump()) gracefully, displaying Laravel's native error pages.
Conditional Methods
when()
Conditionally execute a callback.
when(mixed $condition, callable $callback, callable $fallback = null): selfParameters:
$condition- Boolean or callable returning boolean$callback- Function to execute if condition is true$fallback- Optional function to execute if condition is false
Basic usage:
return hyper()
->signals(['count' => $count])
->when($count > 10, function ($hyper) {
$hyper->signals(['message' => 'Count is high!']);
});With fallback:
return hyper()
->when(auth()->check(),
fn($h) => $h->signals(['user' => auth()->user()->name]),
fn($h) => $h->signals(['user' => 'Guest'])
);unless()
Conditionally execute a callback when condition is false.
unless(mixed $condition, callable $callback, callable $fallback = null): selfreturn hyper()
->signals(['items' => $items])
->unless($items->isEmpty(), function ($hyper) {
$hyper->signals(['hasItems' => true]);
});whenHyper()
Execute callback only for Hyper requests.
whenHyper(callable $callback, callable $fallback = null): selfreturn hyper()
->whenHyper(
fn($h) => $h->fragment('products', 'list', $data),
fn($h) => $h->view('products.index', $data)
);whenNotHyper()
Execute callback only for non-Hyper requests.
whenNotHyper(callable $callback, callable $fallback = null): selfreturn hyper()
->whenNotHyper(fn($h) => $h->web(view('dashboard', $data)));whenHyperNavigate()
Execute callback for Hyper navigate requests.
whenHyperNavigate(string|array|null $key = null, callable $callback = null, callable $fallback = null): selfCheck for any navigate request:
return hyper()->whenHyperNavigate(function ($hyper) {
$hyper->fragment('layout', 'content', $data);
});Check for specific navigation key:
return hyper()
->whenHyperNavigate('sidebar', function ($hyper) {
$hyper->fragment('layout', 'sidebar', $data);
})
->whenHyperNavigate('main', function ($hyper) {
$hyper->fragment('layout', 'main', $data);
});Progressive Enhancement Methods
web()
Set a fallback response for non-Hyper requests (progressive enhancement).
web(mixed $response): selfParameters:
$response- Laravel response or callable returning a response
Basic usage:
return hyper()
->fragment('contacts.index', 'contact-list', $data)
->web(view('contacts.index', $data));With callable:
return hyper()
->fragment('products', 'list', $data)
->web(fn() => view('products.index', $data));How it works:
- For Hyper requests: Returns the fragment
- For regular requests: Returns the full view
- Enables graceful degradation without JavaScript
Response Conversion
toResponse()
Convert the HyperResponse to a Laravel response (implements Responsable interface).
toResponse($request = null): ResponseThis method is called automatically by Laravel. You typically don't need to call it directly.
public function index()
{
return hyper()->signals(['data' => $data]);
// Laravel automatically calls toResponse()
}Method Chaining
All HyperResponse methods return $this, enabling fluent method chaining:
return hyper()
->signals(['loading' => false, 'count' => $count])
->fragment('dashboard', 'stats', ['stats' => $stats])
->js('console.log("Updated!")')
->when($count > 100, fn($h) => $h->signals(['alert' => 'High count!']));Related Documentation
- Signals Helper - Server-side signal management
- Request Macros - Request helper methods
- Blade Directives - Blade integration
- Fragments - Fragment patterns
- Streaming - Streaming responses

