Skip to content

Latest commit

 

History

25 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Hot Reload Bundle

CI Packagist Version Packagist Downloads License PHP Symfony GitHub stars

Found this useful? Install from Packagist · Give it a star on GitHub so more developers can find it.

Hot Reload Bundle — Symfony integration for FrankenPHP Hot Reload (dunglas/frankenphp-hot-reload). When enabled, it injects the Mercure hub meta tag, optional Idiomorph, and the frankenphp-hot-reload ESM module into HTML responses so the browser can morph or reload after PHP (and watched) file changes. Dev-only · PHP 8.2+ · Symfony 7.4+ and 8.0–8.2.

📋 Compatible with Symfony 7.4+ and 8.0–8.2 — PHP 8.2+ (Symfony 8.x requires PHP 8.4+).

FrankenPHP Friendly Worker Mode

This bundle is FrankenPHP worker mode friendly.

Pair with worker { …; watch } in your Caddyfile.

Features

  • Auto-injectHotReloadResponseSubscriber inserts assets before </head> (else </body>) on HTML responses.
  • Twig helper{{ nowo_hot_reload_assets() }} for manual layouts when auto_inject is off.
  • Env-aware — Renders only when enabled and (mercure_url or FRANKENPHP_HOT_RELOAD is set, or require_frankenphp_env: false).
  • Doctor commandphp bin/console nowo:hot-reload:check lists what is configured vs missing (Caddy mercure / hot_reload, env gate, auto-inject, client_mode). The same checklist is on the profiler panel.
  • Multi-tab client modesclient_mode: cdn (default), visibility, shared_worker, or always for HTTP/1.1-friendly Mercure strategies (see docs/USAGE.md).
  • Idiomorph — Optional DOM morphing instead of a full page reload (on by default).
  • Web Debug Toolbar — Profiler panel (nowo_hot_reload) with tabs: Environment checks, Runtime, Client assets, CSP, Help; truncated Mercure URL in the toolbar (full value on hover).
  • Preserve selectors — Marks Symfony Web Debug Toolbar ([id^="sfwdt"], .sf-toolbar, .sf-minitoolbar) with data-frankenphp-hot-reload-preserve (optional MutationObserver).
  • CSP-aware — Optional request-attribute nonce on the preserve boot script; can augment existing Content-Security-Policy script-src for jsDelivr (see docs/CSP.md).

Installation

composer require nowo-tech/hot-reload-bundle --dev

With Symfony Flex, the recipe registers the bundle and adds config. Without Flex, see docs/INSTALLATION.md.

Manual registration in config/bundles.php (prefer dev / test only):

return [
  // ...
  Nowo\HotReloadBundle\NowoHotReloadBundle::class => ['dev' => true, 'test' => true],
];

Server side: enable Mercure (anonymous) and php_server { hot_reload } in your Caddyfile. For worker mode, add worker { file …; watch }. Full environment guide: Configure the environment.

Environment setup

Hot Reload needs FrankenPHP + Caddy, not only Symfony YAML. FRANKENPHP_HOT_RELOAD is injected by FrankenPHP on HTTP requests — do not put it in .env.

  1. Register the bundle for dev / test only.
  2. Keep nowo_hot_reload.enabled: true and auto_inject: true (or call {{ nowo_hot_reload_assets() }}).
  3. Caddyfile: order mercure after encode, mercure { anonymous }, php_server { hot_reload } (worker: also worker { …; watch }).
  4. Recreate the FrankenPHP process/container after Caddy or Compose env changes.
  5. Validate:
php bin/console nowo:hot-reload:check
php bin/console nowo:hot-reload:check --caddyfile=path/to/Caddyfile

Then load an HTML page and open the Web Debug Toolbar Hot Reload panel (same checklist). Step-by-step Caddyfile, Docker notes, and troubleshooting: docs/ENVIRONMENT.md.

Requirements

  • PHP >=8.1 (<8.6); Symfony 8.x requires PHP 8.4+
  • Symfony 7.4+ and 8.0–8.2 (symfony/* ^7.4 || ^8.0)
  • FrankenPHP with Hot Reload + Mercure configured in the Caddyfile (dev)
  • twig/extra-bundle + twig/string-extra (REQ-TWIG-004) — required for {{ nowo_hot_reload_assets() }} and the profiler panel; enable TwigExtraBundle in the host app

Configuration

nowo_hot_reload:
  enabled: true
  auto_inject: true
  require_frankenphp_env: true
  allow_production: false
  # mercure_url: null  # defaults to $_SERVER['FRANKENPHP_HOT_RELOAD']
  # client_mode: shared_worker  # cdn|visibility|shared_worker|always
  idiomorph: true
  # idiomorph_script_url: 'https://cdn.jsdelivr.net/npm/idiomorph@0.7.4'
  # hot_reload_script_url: 'https://cdn.jsdelivr.net/npm/frankenphp-hot-reload@1.0.1/+esm'
  preserve_selectors:
    - '[id^="sfwdt"]'
    - '.sf-toolbar'
    - '.sf-minitoolbar'
  # csp_nonce_request_attribute: '_csp_nonce'
  csp_augment_script_src: true

Usage

With auto_inject: true (default), no template changes are needed when FrankenPHP sets FRANKENPHP_HOT_RELOAD (or you set mercure_url).

Manual Twig injection:

{{ nowo_hot_reload_assets() }}

Official references:

Demo

  • demo/symfony8 — Symfony 8.2 (PHP 8.5), host port 8011 by default (PORT in .env)

The demo runs FrankenPHP + Caddy in Docker. See docs/DEMO-FRANKENPHP.md.

Global demo commands: make -C demo help (e.g. make -C demo up-symfony8).

Development

make up
make install
make test
make cs-check
make phpstan
make release-check

Documentation

Additional documentation

Tests and coverage

  • Tests: PHPUnit (PHP)
  • PHP line coverage: maintained via make test-coverage / make release-check (see CI)

License and author

MIT · Nowo.tech · Héctor Franco Aceituno

About

Symfony bundle that injects FrankenPHP Hot Reload client assets (Mercure meta, Idiomorph, ESM module) into HTML responses in development. Compatible with Symfony 7.4+ and 8.0-8.2. PHP 8.1+ (Symfony 8.x requires PHP 8.4+).

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages