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
Requires
- php: >=8.3
- psr/http-message: ^2.0
- psr/http-server-handler: ^1.0
- psr/http-server-middleware: ^1.0
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 ifHX-Requestis present.isBoosted(): bool- Returns true ifHX-Boostedis present.isHistoryRestoreRequest(): bool- Returns true if restoring history.getCurrentUrl(): ?string- ReturnsHX-Current-Url.getPrompt(): ?string- Returns user input fromHX-Prompt.getTargetId(): ?string- ReturnsHX-TargetID.getTriggerId(): ?string- ReturnsHX-Triggerelement ID.getTriggerName(): ?string- ReturnsHX-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