Skip to content

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:

php
use function Dancycodes\Hyper\hyper;

public function increment()
{
    return hyper()->signals(['count' => 5]);
}

Signal Methods

signals()

Update reactive signals on the frontend.

php
signals(string|array $key, mixed $value = null): self

Update single signal:

php
return hyper()->signals('count', 10);

Update multiple signals:

php
return hyper()->signals([
    'count' => 10,
    'message' => 'Updated successfully',
    'isLoading' => false
]);

Chaining:

php
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).

php
forget(string|array|null $signals = null): self

Delete single signal:

php
return hyper()->forget('temporaryData');

Delete multiple signals:

php
return hyper()->forget(['temp1', 'temp2', 'cache']);

Delete all signals:

php
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.

php
view(string $view, array $data = [], array $options = [], bool $web = false): self

Parameters:

  • $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:

php
return hyper()->view('dashboard', ['stats' => $stats]);

With custom selector:

php
return hyper()->view('products.list', ['products' => $products], [
    'selector' => '#product-container',
    'mode' => 'inner'
]);

With web fallback:

php
return hyper()->view('dashboard', $data, [], web: true);

fragment()

Render a specific fragment from a Blade view (using @fragment directives).

php
fragment(string $view, string $fragment, array $data = [], array $options = []): self

Parameters:

  • $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:

php
return hyper()->fragment('todos.index', 'todo-list', [
    'todos' => Todo::all()
]);

With options:

php
return hyper()->fragment('products.show', 'reviews', ['reviews' => $reviews], [
    'selector' => '#reviews-section',
    'mode' => 'inner'
]);

Fragment in Blade:

blade
@fragment('todo-list')
<div id="todo-list">
    @foreach($todos as $todo)
        <x-todo-item :todo="$todo" />
    @endforeach
</div>
@endfragment

fragments()

Render multiple fragments in a single response.

php
fragments(array $fragments): self

Parameters:

  • $fragments - Array of fragment configurations

Usage:

php
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.

php
html(string $html, array $options = []): self

Usage:

php
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).

php
outer(string $selector, string $html): self
php
return hyper()->outer('#card', '<div id="card" class="updated">New content</div>');

inner()

Morph only the inner HTML (preserving the element itself).

php
inner(string $selector, string $html): self
php
return hyper()->inner('#container', '<p>Updated inner content</p>');

replace()

Completely replace the element (no morphing).

php
replace(string $selector, string $html): self
php
return hyper()->replace('#old-element', '<div id="new-element">Fresh start</div>');

append()

Add HTML as the last child.

php
append(string $selector, string $html): self
php
return hyper()->append('#list', '<li>New item</li>');

prepend()

Add HTML as the first child.

php
prepend(string $selector, string $html): self
php
return hyper()->prepend('#notifications', '<div class="alert">Latest!</div>');

before()

Insert HTML before the element.

php
before(string $selector, string $html): self
php
return hyper()->before('#section', '<hr>');

after()

Insert HTML after the element.

php
after(string $selector, string $html): self
php
return hyper()->after('#content', '<footer>End of content</footer>');

remove()

Remove elements from the DOM.

php
remove(string $selector): self
php
return hyper()->remove('#temporary-notification');

JavaScript Execution Methods

js()

Execute JavaScript code in the browser.

php
js(string $script, array $options = []): self

Parameters:

  • $script - JavaScript code to execute
  • $options - Execution options
    • attributes - Array of HTML attributes for the script tag
    • autoRemove - Whether to remove the script tag after execution (default: true)

Basic usage:

php
return hyper()->js('alert("Hello from server!")');

With options:

php
return hyper()->js('console.log("Processing complete")', [
    'attributes' => ['id' => 'processing-script'],
    'autoRemove' => false
]);

Accessing signals:

php
return hyper()->js('$count = $count + 1');

script()

Alias for js() method.

php
script(string $script, array $options = []): self
php
return hyper()->script('window.scrollTo(0, 0)');

Event Dispatch Methods

dispatch()

Dispatch a custom browser event (CustomEvent) from the server, enabling Livewire-style component communication.

php
dispatch(string $eventName, array $data = [], array $options = []): self

Parameters:

  • $eventName - Name of the event to dispatch
  • $data - Event data (available in event.detail)
  • $options - Event options:
    • selector - Target specific elements (default: global window)
    • bubbles - Whether event bubbles (default: true)
    • cancelable - Whether event is cancelable (default: true)
    • composed - Whether event crosses shadow DOM boundaries (default: true)

Global event:

php
return hyper()->dispatch('post-created', ['id' => 123]);

With data:

php
return hyper()->dispatch('user-login', [
    'userId' => 42,
    'username' => 'john_doe',
    'email' => 'john@example.com'
]);

Targeted dispatch:

php
return hyper()->dispatch('update-stats', ['count' => 5], [
    'selector' => '#dashboard'
]);

With custom options:

php
return hyper()->dispatch('notification', ['message' => 'Saved!'], [
    'bubbles' => false,
    'cancelable' => false
]);

Chaining with other methods:

php
return hyper()
    ->signals(['count' => $newCount])
    ->dispatch('count-updated', ['count' => $newCount])
    ->fragment('dashboard', 'stats', $data);

Frontend usage:

blade
{{-- 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.

php
url(mixed $url = null, string $mode = 'push'): self

Parameters:

  • $url - URL to set (string), query parameters (array), or null for current URL
  • $mode - Either 'push' (default) or 'replace'

Push new URL:

php
return hyper()->url('/dashboard');

Replace current URL:

php
return hyper()->url('/products?page=2', 'replace');

Update query parameters:

php
return hyper()->url(['page' => 2, 'sort' => 'name']);

pushUrl()

Push a new URL to browser history (creates new history entry).

php
pushUrl(mixed $url = null): self
php
return hyper()->pushUrl('/users?page=2');

replaceUrl()

Replace current URL in browser history (doesn't create new history entry).

php
replaceUrl(mixed $url = null): self
php
return hyper()->replaceUrl('/users?page=1');

routeUrl()

Set URL using a Laravel route name.

php
routeUrl(string $routeName, array $params = [], string $mode = 'push'): self

Parameters:

  • $routeName - Laravel route name
  • $params - Route parameters
  • $mode - Either 'push' or 'replace'
php
return hyper()->routeUrl('products.show', ['product' => $product->id]);

pushRoute()

Push a named route to browser history.

php
pushRoute(string $routeName, array $params = []): self
php
return hyper()->pushRoute('users.index', ['page' => 2]);

replaceRoute()

Replace current URL with a named route.

php
replaceRoute(string $routeName, array $params = []): self
php
return hyper()->replaceRoute('dashboard');

These methods perform client-side navigation similar to single-page applications.

Navigate to a URL using Hyper's client-side navigation.

php
navigate(string|array $url, string $key = 'true', array $options = []): self

Parameters:

  • $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 preserve
    • except - Array of query parameters to exclude
    • replace - Use replaceState instead of pushState

Basic navigation:

php
return hyper()->navigate('/dashboard');

With navigation key:

php
return hyper()->navigate('/sidebar', 'sidebar');

With query merging:

php
return hyper()->navigate('/products?page=2', 'true', ['merge' => true]);

Navigate with explicit merge control.

php
navigateWith(string|array $url, string $key = 'true', bool $merge = false, array $options = []): self
php
return hyper()->navigateWith('/products', 'main', merge: true);

Navigate and merge with current query parameters.

php
navigateMerge(string|array $url, string $key = 'true', array $options = []): self
php
return hyper()->navigateMerge('/products?category=electronics');
// Preserves existing query parameters, adds category=electronics

Navigate with a clean slate (no query parameter merging).

php
navigateClean(string|array $url, string $key = 'true', array $options = []): self
php
return hyper()->navigateClean('/dashboard');
// Clears all query parameters

Navigate preserving only specific query parameters.

php
navigateOnly(string|array $url, array $only, string $key = 'true'): self
php
return hyper()->navigateOnly('/products?page=1', ['search', 'category']);
// Keeps search and category, resets page

Navigate preserving all except specific query parameters.

php
navigateExcept(string|array $url, array $except, string $key = 'true'): self
php
return hyper()->navigateExcept('/products', ['page']);
// Keeps all parameters except page (useful for resetting pagination)

Navigate using replaceState instead of pushState.

php
navigateReplace(string|array $url, string $key = 'true', array $options = []): self
php
return hyper()->navigateReplace('/modal');
// Doesn't add to browser history

updateQueries()

Update query parameters while maintaining current path.

php
updateQueries(array $queries, string $key = 'filters', bool $merge = true): self
php
return hyper()->updateQueries(['category' => 'electronics', 'sort' => 'price']);

clearQueries()

Clear specific query parameters.

php
clearQueries(array $paramNames, string $key = 'clear'): self
php
return hyper()->clearQueries(['page', 'sort']);

resetPagination()

Reset to page 1 while preserving other filters.

php
resetPagination(string $key = 'pagination'): self
php
return hyper()->resetPagination();
// Sets page=1, keeps all other query parameters

reload()

Force a full page reload.

php
reload(): self
php
return hyper()->reload();

Streaming Methods

stream()

Execute a callback in streaming mode, where each method call sends events immediately instead of accumulating them.

php
stream(Closure $callback): self

Parameters:

  • $callback - Function that receives the HyperResponse instance

Usage:

php
return hyper()->stream(function ($hyper) {
    $hyper->signals(['status' => 'Starting...']);
    sleep(1);

    $hyper->signals(['status' => 'Processing...']);
    sleep(1);

    $hyper->signals(['status' => 'Complete!']);
});

Processing with progress:

php
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.

php
when(mixed $condition, callable $callback, callable $fallback = null): self

Parameters:

  • $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:

php
return hyper()
    ->signals(['count' => $count])
    ->when($count > 10, function ($hyper) {
        $hyper->signals(['message' => 'Count is high!']);
    });

With fallback:

php
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.

php
unless(mixed $condition, callable $callback, callable $fallback = null): self
php
return hyper()
    ->signals(['items' => $items])
    ->unless($items->isEmpty(), function ($hyper) {
        $hyper->signals(['hasItems' => true]);
    });

whenHyper()

Execute callback only for Hyper requests.

php
whenHyper(callable $callback, callable $fallback = null): self
php
return hyper()
    ->whenHyper(
        fn($h) => $h->fragment('products', 'list', $data),
        fn($h) => $h->view('products.index', $data)
    );

whenNotHyper()

Execute callback only for non-Hyper requests.

php
whenNotHyper(callable $callback, callable $fallback = null): self
php
return hyper()
    ->whenNotHyper(fn($h) => $h->web(view('dashboard', $data)));

whenHyperNavigate()

Execute callback for Hyper navigate requests.

php
whenHyperNavigate(string|array|null $key = null, callable $callback = null, callable $fallback = null): self

Check for any navigate request:

php
return hyper()->whenHyperNavigate(function ($hyper) {
    $hyper->fragment('layout', 'content', $data);
});

Check for specific navigation key:

php
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).

php
web(mixed $response): self

Parameters:

  • $response - Laravel response or callable returning a response

Basic usage:

php
return hyper()
    ->fragment('contacts.index', 'contact-list', $data)
    ->web(view('contacts.index', $data));

With callable:

php
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).

php
toResponse($request = null): Response

This method is called automatically by Laravel. You typically don't need to call it directly.

php
public function index()
{
    return hyper()->signals(['data' => $data]);
    // Laravel automatically calls toResponse()
}

Method Chaining

All HyperResponse methods return $this, enabling fluent method chaining:

php
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!']));