ecoleplus/htmx-bridge

A strict PSR-7/PSR-15 HTMX Bridge for PHP 8.3+

Installs: 33

Dependents: 0

Suggesters: 0

Security: 0

Stars: 0

Forks: 0

pkg:composer/ecoleplus/htmx-bridge

dev-master 2025-12-26 19:34 UTC

This package is auto-updated.

Last update: 2025-12-26 19:34:10 UTC


README

A strict PSR-7 and PSR-15 compliant bridge for integrating HTMX with modern PHP 8.3+ applications.

This library provides type-safe Decorators and Middleware to easily inspect HTMX requests and generate HTMX-aware responses without coupling your domain logic to specific framework implementations.

Features

  • Strictly Typed: Utilizes PHP 8.3+ typing for robustness.
  • PSR-7 Immutability: Fully respects HTTP Message immutability conventions.
  • PSR-15 Middleware: Plug-and-play integration with Mezzio, Slim, Laravel, or any PSR-15 compliant dispatcher.
  • Event Merging: Intelligently merges multiple HTMX triggers (HX-Trigger) into a single JSON header.
  • Comprehensive Coverage: Supports advanced HTMX headers like HX-Boosted, HX-Trigger-After-Swap, HX-Push-Url, and more.

Installation

composer require ecoleplus/htmx-bridge

Usage

1. Register Middleware

Add EcolePlus\HtmxBridge\Middleware\HtmxRequestMiddleware to your middleware pipeline early in the stack. This will decorate the incoming ServerRequestInterface with HTMX capabilities.

// Example in a Mezzio/Laminas pipeline
$app->pipe(EcolePlus\HtmxBridge\Middleware\HtmxRequestMiddleware::class);

// Example in Slim Framework
$app->add(new EcolePlus\HtmxBridge\Middleware\HtmxRequestMiddleware());

2. Inspecting Requests

In your controller or request handler, you can check if the request is an HTMX request and retrieve metadata.

use EcolePlus\HtmxBridge\Contract\HtmxRequestInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;

public function handle(ServerRequestInterface $request): ResponseInterface
{
    // 1. Check if the request object implements our interface
    if ($request instanceof HtmxRequestInterface && $request->isHtmx()) {
        
        // 2. Access HTMX specific data
        $targetId = $request->getTargetId();
        $triggeredBy = $request->getTriggerId();
        
        // ... application logic for partial rendering ...
    }

    // ... standard full-page render logic ...
}

3. Constructing Responses

Use the HtmxResponseDecorator to build HTMX-aware responses fluently. Since it is immutable, remember to chain methods or capture the return value.

use EcolePlus\HtmxBridge\Decorator\HtmxResponseDecorator;
use Laminas\Diactoros\Response\JsonResponse;

// Create a standard PSR-7 response
$response = new JsonResponse(['status' => 'ok']);

// Wrap and decorate
return (new HtmxResponseDecorator($response))
    ->withPushUrl('/new-url')                 // Update browser URL
    ->withTrigger('userCreated', ['id' => 1]) // Client-side event
    ->withTriggerAfterSwap('showToast', [])   // Event after swap
    ->withReswap('innerHTML')                 // HTMX swap strategy
    ->getResponse();                          // Unwrap back to PSR-7 Response

API Reference

Request (HtmxRequestInterface)

  • isHtmx(): bool - Returns true if HX-Request is present.
  • isBoosted(): bool - Returns true if HX-Boosted is present.
  • isHistoryRestoreRequest(): bool - Returns true if restoring history.
  • getCurrentUrl(): ?string - Returns HX-Current-Url.
  • getPrompt(): ?string - Returns user input from HX-Prompt.
  • getTargetId(): ?string - Returns HX-Target ID.
  • getTriggerId(): ?string - Returns HX-Trigger element ID.
  • getTriggerName(): ?string - Returns HX-Trigger-Name.

Response (HtmxResponseInterface)

All methods are immutable and return a new instance.

  • withPushUrl(string|false $url) - Updates browser history.
  • withReplaceUrl(string|false $url) - Replaces current URL.
  • withReswap(string $value) - Sets swap method (e.g., innerHTML).
  • withRetarget(string $selector) - Changes update target.
  • withRefresh() - Triggers a full page refresh.
  • withRedirect(string $url) - Client-side redirect via HTMX.
  • withTrigger(string $event, array $data = []) - Triggers event immediately.
  • withTriggerAfterSwap(string $event, array $data = []) - Triggers event after swap.
  • withTriggerAfterSettle(string $event, array $data = []) - Triggers event after settle.

License

MIT License