wazum / typo3-live-reload
Live-reloads the open frontend tabs affected by a content or source-file change, using TYPO3 cache tags and rendered-file tags to reload only the affected tabs.
Package info
github.com/wazum/typo3-live-reload
Type:typo3-cms-extension
pkg:composer/wazum/typo3-live-reload
Requires
- php: ^8.2
- typo3/cms-core: ^13.4 || ^14.3
- typo3/cms-frontend: ^13.4 || ^14.3
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.65
- phpstan/phpstan: ^2.0
- phpunit/phpunit: ^11.5 || ^12
- typo3/cms-adminpanel: ^13.4 || ^14.3
- typo3/cms-install: ^13.4 || ^14.3
- typo3/testing-framework: ^9.0
Suggests
- praetorius/vite-asset-collector: Resolves the Vite dev server URL automatically when viteServerPublicUrl is not configured
- typo3/cms-adminpanel: Adds the Live Reload admin panel module with connection status, cache tags, and broadcast feed
Provides
None
Conflicts
None
Replaces
None
README
Live Reload
Save a Fluid partial in your editor — or a record in the TYPO3 backend.
The browser tabs that show it reload. All other tabs stay as they are.
The idea
The usual live reload setup watches the template folder and reloads every open tab. Tabs that never showed the changed file lose their scroll position, their form input and their open dialogs.
This extension reloads only the tabs that show the change. Each page knows what it rendered: its TYPO3 cache tags and the Fluid files it used. Each change becomes the same kind of tag. A tab reloads only when its tags and the tags of the change overlap.
What reloads
| You change | What reloads |
|---|---|
| A Fluid template, partial or layout | the tabs that rendered it |
A Fluid component (<my:atom.button>) |
the tabs that rendered it |
| A ViewHelper class | the tabs whose templates use it |
| A record in the TYPO3 backend | the tabs that show it |
The caches, in the backend or with typo3 cache:flush |
all open tabs |
| CSS or TypeScript | Vite's hot update, often without a reload (through vite-asset-collector) |
Vite's own hot reload can't handle the Fluid rows, because server-rendered Fluid never enters its module graph.
How it works
- While TYPO3 renders a page, the extension records the page's cache tags and the Fluid
files the render used. A middleware writes them into the page as
window.__liveReload, together with a small client script. - When an editor saves a record, TYPO3 flushes its cache tags. The extension collects them and sends them on after the editor's response has gone out.
- When you save a watched file, the Vite plugin turns it into a
file:tag. PHP is not involved — the watcher is the signal. - In the Development context, the Vite dev server sends the tags to every tab over the WebSocket it already holds open, once per batch. TYPO3 also keeps the tags in a table, and tabs without a dev server poll a small endpoint for them.
- Each tab compares the tags with its own and reloads only when they overlap.
Installation
composer require --dev wazum/typo3-live-reload
That is all you need for content reloads. In the Development context they work at once: open some frontend pages, edit content in the backend, and the right tabs reload. Without a Vite dev server, each tab asks a small endpoint for changes.
For file reloads, add the plugin to vite.config.ts. It ships with the Composer package,
so you don't need an npm package:
import { defineConfig } from 'vite' import { liveReload } from './vendor/wazum/typo3-live-reload/Resources/Private/Vite/dist/index.js' export default defineConfig({ plugins: [ // ...your other plugins liveReload({ watch: { paths: ['packages'] }, // your extension/template directories }), ], })
The import path is relative to vite.config.ts. With the plugin, Vite pushes changes over
the WebSocket it already holds open, so the tabs stop polling. Leave out watch if you
only want content reloads.
Important
Turn on the frontend.cache.autoTagging feature toggle. Only new TYPO3 installations
have it on by default:
$GLOBALS['TYPO3_CONF_VARS']['SYS']['features']['frontend.cache.autoTagging'] = true;
Without it, content reloads only happen for edits on the page you are looking at.
You need TYPO3 13.4 or 14.3, PHP 8.2 or newer, and Vite 5.1 or newer if you use the dev server.
Good to know
- Visitors get nothing. The extension only runs in the contexts you allow (by default
Development), and a plainProductioncontext never counts. Outside Development, it also needs a backend login. - Editors can use it on a staging site without a dev server. A saved record reloads their preview tabs (reloads for editors).
- Saving in the backend is never slower, and a failed broadcast never breaks a save.
- If a change breaks the page, you see the TYPO3 error page as usual. Fix the error, and
the tab reloads by itself. A few errors, such as a broken
Services.yamlor PHP running out of memory, need one manual reload after the fix. - A page without tag data reloads on every change, so it never misses one.
- The scroll position stays, even when a framework such as Turbo sets
history.scrollRestoration = 'manual'. - A cancelable
typo3:live-reloadevent fires before each reload, so you can morph the page in place instead. - CSP nonces are handled for you (Content Security Policy).
- The Admin Panel module shows the connection, the page's cache tags and a live feed of broadcasts. It can also pause reloads for your session.
Documentation
| Document | What it covers |
|---|---|
| File reloads | how files are recorded, the watch option, the page cache, limits |
| Content reloads | cache tags, reloads for editors, tags from other extensions, limits |
| Configuration | all settings, the dev server URLs, the shared secret, Vite plugin options |
| Morph instead of reload | updating the page in place with Turbo or idiomorph |
| Admin Panel | the status dot, the three tabs, pausing reloads |
| Content Security Policy | what the extension does for CSP and what is left for you |
| CHANGELOG.md | what changed in each release |
Licence
GPL-2.0-or-later, see LICENSE.

