diff --git a/docs/hot-reload.md b/docs/hot-reload.md new file mode 100644 index 00000000..02f273eb --- /dev/null +++ b/docs/hot-reload.md @@ -0,0 +1,114 @@ +# Hot Reload + +FrankenPHP includes a built-in **hot reload** feature designed to vastly improve the developer experience. + +This feature provides a workflow similar to **Hot Module Replacement (HMR)** found in modern JavaScript tooling (like Vite or Webpack). +Instead of manually refreshing the browser after every file change (PHP code, templates, JavaScript and CSS files...), +FrankenPHP updates the content in real-time. + +Hot Reload natively works with WordPress, Laravel, Symfony, and any other PHP application or framework. + +When enabled, FrankenPHP watches your current working directory for filesystem changes. +When a file is modified, it pushes a [Mercure](mercure.md) update to the browser. + +Depending on your setup, the browser will either: + +* **Morph the DOM** (preserving scroll position and input state) if [Idiomorph](https://github.com/bigskysoftware/idiomorph) is loaded. +* **Reload the page** (standard live reload) if Idiomorph is not present. + +## Configuration + +To enable hot reloading, enable Mercure, then add the `hot_reload` option to the `php_server` directive in your `Caddyfile`. + +> [!WARNING] +> This feature is intended for **development environments only**. +> Do not enable `hot_reload` in production, as watching the filesystem incurs performance overhead and exposes internal endpoints. + +```caddyfile +localhost + +mercure { + anonymous +} + +root public/ +php_server { + hot_reload +} +``` + +You can also explicitly specify the Mercure topic to use as well as which directories or files to watch by providing paths to the `hot_reload` option: + +```caddyfile +localhost + +mercure { + anonymous +} + +root public/ +php_server { + hot_reload { + topic hot-reload-topic + watch src/ + watch templates/ + watch public/js/ + watch public/css/ + } +} +``` + +### Worker Mode + +If you are running your application in [Worker Mode](https://frankenphp.dev/docs/worker/), your application script remains in memory. +This means changes to your PHP code will not be reflected immediately, even if the browser reloads. + +For the best developer experience, you should combine `hot_reload` with the `watch` option in the `worker` directive. + +* `hot_reload`: Refreshes the **browser** when files change. +* `watch`: Refreshes the **application kernel** (restarts the worker) when files change. + +```caddy +localhost + +mercure { + anonymous +} + +root public/ +php_server { + hot_reload + worker { + file my_worker.php + watch + } +} +``` + +## Client-Side Integration + +While the server detects changes, the browser needs to subscribe to these events to update the page. FrankenPHP exposes the Mercure Hub URL required for the subscription via the `$_SERVER['FRANKENPHP_HOT_RELOAD']` environment variable. + +You must include the URL in a meta tag and load the FrankenPHP Hot Reload library. + +Add the following to your main layout or HTML template: + +```php + +