All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
14.5.1 - 2026-05-26
parameters_avifandparameters_jxlnow ship ImageMagick-compatible defaults;converter_avifandconverter_jxldefault toMagickConverter. Enabling AVIF or JPEG XL viaformats_enabledworks out of the box on the typical TYPO3 host — no manual parameter string required. Override either to switch to libvips or an external binary.
webp:diagnoseparameter-parsing check now distinguishes empty, malformed-global, and missing-per-mime cases and emits the concrete recommended value for the configured converter, instead of pointing at the README.
- README adds dedicated
parameters_avifandparameters_jxlsections with per-backend recipes (ImageMagick, libvips, external binaries).
14.5.0 - 2026-05-26
- WebP, AVIF, and JPEG XL output in any combination. A new
formats_enabledsetting (defaultwebp) lets you pick which sibling formats this install produces — e.g.formats_enabled = webp,avifto ship both, orwebp,avif,jxlto ship all three. Each non-webp format has its own converter, parameters, and mime-types tab in the Extension Configuration form (converter_avif,parameters_avif,mime_types_avif; same forjxl). The existingconverter/parameters/mime_typeskeys remain the source of truth for the WebP slot. The 4-converter × 3-format support matrix (VipsConverter,MagickConverter,ExternalConverter,PhpGdConverter) is in the README. Closes #94. webp:diagnose --format=<webp|avif|jxl>to restrict the report to one format. The delivery probe now sends fourAcceptheaders (avif/jxl/webp/*/*) and verifies the server returns the highest-priority format the install actually generates. Storages, converter health, async pipeline, failed-attempts cache, and per-file deep-dive all report per format.webp:process-queue --folder=<path>now sweeps for every enabled output format, not just WebP.
- Sibling lifecycle (move / rename / replace / delete) now covers all three formats. Any on-disk
.avifor.jxlsibling follows its original alongside the existing.webphandling. - Default
filter_patternnow matches.avifand.jxlsiblings as well as.webp. Custom values are left untouched; admins who pinned a webp-only regex keep their value.
- A previously-good sibling is no longer deleted when a fresh conversion attempt turns out larger than the original. The failed-attempts cache already prevents the next render from retrying with the same parameters; we keep the file the webserver was happily serving.
- Renaming a source file no longer overwrites a same-named file at the destination. The orphaned source sibling is cleaned up and the next render produces a fresh destination sibling, instead of silently replacing whatever was there.
- Enabling a format without its converter or parameters no longer generates an error on every render. The listener skips the unconfigured format with a one-line notice instead.
webp:diagnosedegrades gracefully on installs that haven't run the TYPO3 Database Analyzer after upgrade — the affected sections detect the missingformatcolumn and point the admin at the analyzer instead of throwing.webp:diagnoseno longer certifies PhpGdConverter as AVIF/JPEG XL capable. PhpGd is WebP-only at runtime; the diagnose check now mirrors that.webp:diagnoseAccept-header probe grades against the format actually available on disk, instead of always comparing against the highest-priority enabled format — eliminates the spurious "server prefers webp over avif" warning when a file has no AVIF sibling yet.PhpGdConverterclampsqualityvalues above 100 (PHPimagewebpdocuments 0–100).ext_emconf.phpnow declaresphp >= 8.2.0, matching the long-standing composer constraint. TER installs on PHP 8.1 no longer fetch the extension only to fatal on first request.- Async-mode label in the Extension Configuration backend module no longer breaks mid-sentence — TYPO3's EM UI was splitting the label on the
webp:colon. composer.jsonnowsuggeststypo3/cms-frontendfor installs that pick the PhpGd backend (PhpGd importsTYPO3\CMS\Frontend\Imaging\GifBuilder).
- Run the TYPO3 Database Analyzer.
tx_webp_queueandtx_webp_failedgain aformatcolumn; existing rows remain valid (formatdefaults towebp) but the schema must match. Stop the Scheduler before running the analyzer if you're worried about concurrent enqueues during theALTER TABLE— queued work is a transient working set andTRUNCATE tx_webp_queuebefore the analyzer is also fine. - Flush all caches after deploy. The compiled DI container caches references to the renamed service classes; a stale container will fatal on the first request that touches them.
vendor/bin/typo3 cache:flushor Install Tool → Maintenance → Flush cache resolves it. - Re-save the Extension Configuration if you customised
filter_patternto the previous webp-only default. The old default'/\.(jpe?g|png|gif)\.webp$/i'does not hide.avif/.jxlsiblings. The new default covers all three; admins who pinned a webp-only regex keep their value untouched.
14.4.1 - 2026-05-21
webp:diagnoseno longer requiressymfony/process, which is not bundled in TYPO3 v12.4 core. Classic-mode (non-Composer) installs on v12 hit a fatalClass "Symfony\Component\Process\Process" not foundwhen running the command. The MagickConverter health check now uses PHP's nativeproc_openwith the same 5-second timeout behaviour, removing the runtime dependency onsymfony/processentirely (also dropped fromcomposer.jsonrequire). Closes #116.
14.4.0 - 2026-05-19
- libvips as a first-class conversion backend. Pick libvips (native) from the converter dropdown to use a new
VipsConverterthat calls libvips in-process viajcupitt/vips(2.x) + PHPext-ffi— typically 2–3× faster thanMagickConverterat equivalent quality, substantially less memory, and animated GIFs survive as animated WebP automatically (n=-1load +mixed=truesave). ThevipsCLI binary also works through the existingExternalConverterand preserves GIF animation when the GIF entry uses%s[n=-1]on the source argument. Parameter format for the native backend is space-separatedkey=valuepairs per mime type, passed straight to libvips'swebpsave.webp:diagnosereports libvips availability (ext-ffi state, package, shared library reachable viaVips\Config::version()) and warns on PHP 8.3+ ifzend.max_allowed_stack_size=-1is not set. README and reST documentation updated. CI matrix exercises the native backend on every PHP × TYPO3 cell.
14.3.0 - 2026-05-16
webp:diagnoseCLI command. Reports per-storage WebP mode (incl. phantom rows whose driver isn't registered), converter health (PHP GD / ImageMagick / GraphicsMagick / external binary), async pipeline + scheduler state, recent failed conversion attempts, an optional HTTP probe of the webserver's Accept-header rewrite (withVary: Acceptcheck), and an optional per-file deep dive. Single recommendation block points at the first finding; exit code is1only on real failures so the command works as a deployment gate. README and reST documentation updated.
14.2.0 - 2026-05-15
- Per-storage opt-in for
.webpgeneration on non-Local FAL drivers. A newtx_webp_modefield onsys_file_storage(Storage record → Generate WebP variants) selects Auto (default, preserves pre-14.2 behaviour — on for Local, off for everything else), Enabled (force on regardless of driver), or Disabled (force off). Closes #108. - README and reST documentation for remote storages and the CDN-edge serving recipe (CloudFront Function / Cloudflare Worker).
- WebP publish step now routes through FAL APIs (
ResourceStorage::updateProcessedFile()for processing-folder targets,Folder::addFile(..., DuplicationBehavior::REPLACE)for source-folder targets) instead of direct filesystem writes. The driver overwrites atomically onREPLACE— a transient upload failure no longer leaves the user without a previously-valid sibling. - WebP sibling lifecycle (move/rename/replace/delete/recycler) uses FAL public APIs (
ResourceStorage::moveFile,renameFile,getFile,deleteFile) instead of direct filesystem ops. Works driver-agnostically; remote-driver storages no longer accumulate orphans on cross-storage moves. - Sibling now follows the original on rename too — previously only inter-folder moves were tracked, so a BE "rename" left the
.webpstranded at the old filename.
- TYPO3 v12 ships
SYS/mediafile_extwithoutwebp, so the new FAL publish path trippedResourceConsistencyService::isFileExtensionAllowed.ext_localconf.phpnow appendswebpto that list if absent — no-op on v13/v14 where it's already there.
14.1.1 - 2026-05-15
typo3/cms-installandtypo3/cms-schedulermoved fromrequiretosuggest. The UpgradeWizard class only loads when cms-install's attribute-autoconfigure scans services, and the scheduler task wrapper only loads when cms-scheduler actually instantiates it — both are dormant on installs that don't have the packages. The scheduler-task registration inext_localconf.phpis now guarded withclass_existsfor explicit clarity. Users running async mode still need cms-scheduler installed; users running the upgrade wizard still need cms-install installed.
14.1.0 - 2026-05-15
- Opt-in async conversion mode (
async = 1): WebP conversions are queued in a newtx_webp_queuetable and processed out-of-band by a TYPO3 Scheduler task. Closes #17. - New CLI command
webp:process-queuewith optional--folder=PATHargument to convert images in non-FAL folders (e.g.,typo3temp/assets/online_media/). Closes #73. - New
async_throttle_msconfiguration to space conversions out with randomized jitter, preventing thundering-herd CPU/IO. - UpgradeWizard
webp.truncateFailedAttemptsBeforeColumnResizeto unblock upgrades from older releases that shippedtx_webp_failed.configuration_hashasVARCHAR(40); the wizard empties the cache of failed attempts so TYPO3's database analyzer can shrink the column toVARCHAR(32). Closes #95.
ExternalConverternow preserves non-ASCII bytes in filenames (e.g., German umlauts, accented characters) when passing paths to external converters likecwebp. PHP'sescapeshellarg()silently drops multibyte bytes underLC_CTYPE=C, which mangled filenames likeMövenpick.pngtoMvenpick.pngand caused conversion to silently fail. Closes #89.- TYPO3 14.3 no longer logs an
ext_emconf.phpdeprecation notice on every request;composer.jsonnow declaresextra.typo3/cms.versionandextra.typo3/cms.Package.providesPackagessoPackageManagerrecognises the extension as composer-only-capable.
14.0.0 - 2026-05-14
- TYPO3 v14 support; single code path covers v12, v13, and v14.
- Sibling lifecycle:
.webpsiblings next to original images are kept in sync with TYPO3's FAL operations (move, delete, replace). When a storage has a recycler, the sibling follows the file into the recycler so restore keeps the pair intact. Closes #88. - Comprehensive README overhaul: compatibility matrix, configuration summary, troubleshooting checklist, known limitations, and per-option reference for the previously-undocumented
mime_typesandfilter_patternkeys. - Regression test suite (unit + functional) and GitHub Actions CI matrix across PHP 8.2/8.3/8.4 × TYPO3 12/13/14.
- BC break for custom converters. The
Plan2net\Webp\Converter\Converterinterface constructor now takes a second argument:__construct(string $parameters, Plan2net\Webp\Service\Configuration $configuration). Third-party converter implementations need to update their constructor signature accordingly.
.webpsource files no longer create phantom rows insys_file_processedfile.- The listener now normalises
FileReferenceinputs to their underlyingFilebefore the repository lookup — fixes a latent v12/v13 bug where the wrong UID was being queried. FileNameFilterno longer emits PHP 8+ warnings on invalid filter regex patterns.