Skip to content

Releases: plan2net/webp

14.5.1

26 May 14:15

Choose a tag to compare

Changed

  • parameters_avif and parameters_jxl now ship ImageMagick-compatible defaults; converter_avif and converter_jxl default to MagickConverter. Enabling AVIF or JPEG XL via formats_enabled works out of the box on the typical TYPO3 host — no manual parameter string required. Override either to switch to libvips or an external binary.

Fixed

  • webp:diagnose parameter-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.

Documentation

  • README adds dedicated parameters_avif and parameters_jxl sections with per-backend recipes (ImageMagick, libvips, external binaries).

14.5.0

26 May 13:39

Choose a tag to compare

Added

  • WebP, AVIF, and JPEG XL output in any combination. A new formats_enabled setting (default webp) lets you pick which sibling formats this install produces — e.g. formats_enabled = webp,avif to ship both, or webp,avif,jxl to 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 for jxl). The existing converter / parameters / mime_types keys 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 four Accept headers (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.

Changed

  • Sibling lifecycle (move / rename / replace / delete) now covers all three formats. Any on-disk .avif or .jxl sibling follows its original alongside the existing .webp handling.
  • Default filter_pattern now matches .avif and .jxl siblings as well as .webp. Custom values are left untouched; admins who pinned a webp-only regex keep their value.

Fixed

  • 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:diagnose degrades gracefully on installs that haven't run the TYPO3 Database Analyzer after upgrade — the affected sections detect the missing format column and point the admin at the analyzer instead of throwing.
  • webp:diagnose no longer certifies PhpGdConverter as AVIF/JPEG XL capable. PhpGd is WebP-only at runtime; the diagnose check now mirrors that.
  • webp:diagnose Accept-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.
  • PhpGdConverter clamps quality values above 100 (PHP imagewebp documents 0–100).
  • ext_emconf.php now declares php >= 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.json now suggests typo3/cms-frontend for installs that pick the PhpGd backend (PhpGd imports TYPO3\CMS\Frontend\Imaging\GifBuilder).

Upgrade notes

  • Run the TYPO3 Database Analyzer. tx_webp_queue and tx_webp_failed gain a format column; existing rows remain valid (format defaults to webp) but the schema must match. Stop the Scheduler before running the analyzer if you're worried about concurrent enqueues during the ALTER TABLE — queued work is a transient working set and TRUNCATE tx_webp_queue before 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:flush or Install Tool → Maintenance → Flush cache resolves it.
  • Re-save the Extension Configuration if you customised filter_pattern to the previous webp-only default. The old default '/\.(jpe?g|png|gif)\.webp$/i' does not hide .avif / .jxl siblings. The new default covers all three; admins who pinned a webp-only regex keep their value untouched.

14.4.1

21 May 09:04

Choose a tag to compare

A bugfix release: webp:diagnose no longer crashes on classic-mode (non-Composer) TYPO3 v12 installs.

Bug fixes

  • webp:diagnose no longer requires symfony/process. Classic-mode TYPO3 v12 core does not bundle that package, so the command crashed with Class "Symfony\Component\Process\Process" not found. The MagickConverter health check now uses PHP's native proc_open with the same 5-second timeout behaviour. symfony/process is dropped from composer.json require entirely. A new smoke test (Tests/Functional/Command/DiagnoseCommandTest) keeps the command exercised in every PHP × TYPO3 CI matrix cell. Closes #116.

Upgrade notes

  • No schema changes, no upgrade wizard, no BC concerns.

14.4.0

19 May 08:26

Choose a tag to compare

libvips becomes a first-class WebP conversion backend, either in-process via jcupitt/vips 2.x + PHP ext-ffi (typically 2–3× faster than MagickConverter at equivalent quality, substantially less memory) or as the vips CLI binary through the existing ExternalConverter. Both routes preserve animated GIFs as animated WebP.

New features

  • libvips (native) backend. A new VipsConverter calling libvips in-process via jcupitt/vips (2.x) + PHP ext-ffi. Pick libvips (native) in the converter dropdown. Parameters are space-separated key=value pairs per mime type (e.g. image/jpeg::Q=85 smart_subsample=true effort=4|…) passed straight to libvips's webpsave — see the option reference for the full list.
  • Animated GIFs survive as animated WebP. VipsConverter loads all frames automatically (n=-1) and emits multi-frame WebP when mixed=true is set. The vips CLI binary via ExternalConverter also preserves animation when the GIF entry uses %s[n=-1] on the source argument.
  • webp:diagnose reports libvips availability. Distinguishes ext-ffi missing / disabled / preload mode, jcupitt/vips not installed, and libvips shared library unreachable via Vips\Config::version(). Warns on PHP 8.3+ if zend.max_allowed_stack_size=-1 is not set (jcupitt/vips runs FFI callbacks off the main thread).

Upgrade notes

  • No schema changes, no upgrade wizard, no BC concerns. Default backend stays MagickConverter — existing installs are unaffected until you opt in.
  • To use the native backend, install libvips-tools on the host (Debian/Ubuntu pulls in libvips42 / libvips42t64 as a dependency), enable PHP's ext-ffi with ffi.enable=true in php.ini (not preload — jcupitt/vips does not support preloading), composer require jcupitt/vips, and set the converter to libvips (native) in the extension configuration. On PHP 8.3+ also set zend.max_allowed_stack_size=-1. Full recipe in the README's Using libvips natively section.

14.3.0

16 May 07:18

Choose a tag to compare

A new webp:diagnose CLI command walks the full delivery chain end-to-end and points at the first failing link.

New features

  • webp:diagnose CLI command. Run vendor/bin/typo3 webp:diagnose for a single-pass health check covering:
    • Storages — WebP mode, driver, .webp sibling counts, silent-off cases, phantom storage rows with unregistered drivers.
    • Converter — class, binary availability, parameter string.
    • Async pipeline — queue size, oldest entry age, scheduler task state.
    • Failed-conversion cache — recent rows, dominant configuration_hash warning.
    • Optional HTTP probe (--url=<url>) — Accept-header rewrite + Vary: Accept check.
    • Optional per-file deep dive (--file=<uid>) — metadata, sibling lookups, failed-attempts rows.
  • Output uses coloured markers ( ok, ! warning, failure). Exit code is 1 only on real failures, so the command works as a deployment gate.

Upgrade notes

  • No schema changes, no upgrade wizard, no BC concerns.

14.2.0

16 May 04:39

Choose a tag to compare

WebP generation now works on non-Local FAL drivers (S3, Azure, custom). A per-storage opt-in field controls which storages produce .webp siblings; the publish and lifecycle paths were rewritten on top of FAL public APIs so any conformant driver works out of the box.

New features

  • Per-storage opt-in for non-Local FAL drivers. A new Generate WebP variants field on each sys_file_storage record (tx_webp_mode) selects Auto (on for Local drivers, off for everything else), Enabled, or Disabled. Set it to Enabled on a non-Local storage to opt in. Closes #108.
  • README and reST documentation for remote storages and the CDN-edge serving recipe (CloudFront Function / Cloudflare Worker rewriting Accept: image/webp to the sibling URL).

Changes

  • WebP publish routed through FAL public APIs. ResourceStorage::updateProcessedFile() for processing-folder targets, Folder::addFile(..., DuplicationBehavior::REPLACE) for source-folder targets. Replaces the previous direct filesystem writes. The driver overwrites atomically on REPLACE, so 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). Works driver-agnostically; remote-driver storages no longer accumulate orphan .webp on cross-storage moves.
  • Sibling now follows the original on rename. Previously only inter-folder moves were tracked, so a BE "rename" left the .webp stranded at the old filename.

Bug fixes

  • TYPO3 v12 compatibility for the new FAL publish path. v12 ships SYS/mediafile_ext without webp, so the publish step tripped ResourceConsistencyService::isFileExtensionAllowed. ext_localconf.php now appends webp to that list when absent.

Upgrade notes

  • Run the database analyzer after upgrade so the new tx_webp_mode column is added to sys_file_storage.
  • For non-Local storages (S3, Azure, custom), edit the storage record and set Generate WebP variants to Enabled. Strongly recommended to also enable async = 1 — synchronous mode adds the driver's upload latency to every page render that processes an image (~100–500 ms per S3 PUT).
  • CDN serving (Accept-header rewrite) is the edge's job. See the new Remote storages README section for CloudFront Function / Cloudflare Worker recipes.

14.1.1

15 May 08:30

Choose a tag to compare

`typo3/cms-install` and `typo3/cms-scheduler` are now optional dependencies rather than hard requires. Sites that don't use async conversion mode or the legacy upgrade wizard no longer need to pull them in.

Changes

  • `typo3/cms-install` moved to `suggest`. Only required if you need the upgrade wizard that clears legacy `tx_webp_failed` rows during a `configuration_hash` column resize.
  • `typo3/cms-scheduler` moved to `suggest`. Only required when `async = 1` — the scheduler task drains `tx_webp_queue` out-of-band.

Upgrade notes

  • No action required for existing installs. Anyone who already has cms-install and cms-scheduler installed sees no difference.
  • Async mode (`async = 1`) still needs cms-scheduler. Without it, queued conversions stay pending — install cms-scheduler if you want to use async mode.

14.1.0

15 May 06:49

Choose a tag to compare

WebP conversion can now run asynchronously via a TYPO3 Scheduler task, off the page-render path. Image-heavy pages and large fileadmin setups stop spiking CPU during requests. Plus an UpgradeWizard for sites upgrading from older releases, and a few correctness fixes.

New features

  • Opt-in async conversion mode — set the new async = 1 extension setting and the AfterFileProcessing listener enqueues conversions to a new tx_webp_queue table instead of running the converter inside the request. Conversions then run out-of-band when the scheduler task fires. Existing siblings stay in place; the extension does not retroactively backfill. Closes #17.
  • webp:process-queue CLI command + Scheduler task — drains the queue in batches. Register System → Scheduler → Add task → "Process conversion queue (webp)" with your preferred frequency and batch size. Same command also accepts --folder=PATH to sweep filesystem folders that don't go through FAL, such as typo3temp/assets/online_media/ for YouTube/Vimeo preview thumbnails. Closes #73.
  • Randomized throttle — set async_throttle_ms = 500 (for example) and the worker pauses a random random(N/2, N*3/2) milliseconds between conversions. Mirrors wget --random-wait to avoid lock-step bursts that saturate the box on predictable beats. Applies to both queue mode and --folder mode.
  • UpgradeWizard for legacy tx_webp_failed rows — older releases shipped configuration_hash as VARCHAR(40); the current schema is VARCHAR(32). TYPO3's database analyzer refuses to shrink the column while existing rows hold longer values, blocking upgrades. The new wizard webp.truncateFailedAttemptsBeforeColumnResize empties the failed-attempts cache so the analyzer can complete the migration. Run it from the Install Tool when the analyzer flags this on upgrade. Closes #95.

Bug fixes

  • Non-ASCII filenames work with external convertersExternalConverter now preserves multibyte bytes when passing paths to external binaries like cwebp. PHP's escapeshellarg() is locale-aware and silently drops multibyte bytes when LC_CTYPE=C, which mangled filenames like Mövenpick.png to Mvenpick.png before they reached the binary — the converter then produced no .webp with no error. Closes #89.
  • No more ext_emconf.php deprecation notice on every request under TYPO3 14.3composer.json now declares the version and providesPackages fields under extra.typo3/cms, which PackageManager recognises as composer-only-capable so it stops parsing ext_emconf.php.

Upgrade notes

  • Default behavior unchanged. async defaults to 0. Existing installs keep their synchronous conversion path on upgrade. Flip the flag via the Extension Configuration backend module (System → Settings → Extension Configuration → webp on TYPO3 v14; Admin Tools → Settings → Extension Configuration → webp on v12/v13).
  • Run the database analyzer after upgrade so the new tx_webp_queue table is created. Required before flipping async = 1. If the analyzer flags a configuration_hash column-resize blocker, run the webp.truncateFailedAttemptsBeforeColumnResize wizard from the Install Tool first.
  • New typo3/cms-scheduler dependency. Composer pulls it in automatically. After flipping async = 1, register a scheduler task: System → Scheduler → Add task → "Process conversion queue (webp)" and configure batch size + frequency to taste. Without a task, queued conversions just sit in tx_webp_queue — the page render still succeeds, you just get no .webp siblings until the task runs.

14.0.0

14 May 05:45

Choose a tag to compare

TYPO3 v14 support and automatic .webp sibling cleanup on FAL operations. A single code path now covers TYPO3 v12, v13, and v14.

New features

  • TYPO3 v14 compatibility — same install works on v12.4, v13.4, and v14 (tested against current 14.3.x); CI matrix exercises PHP 8.2/8.3/8.4 across all three lines.
  • Sibling lifecycle synced with FAL — moving, deleting, or replacing an image keeps its .webp sibling in sync. When a storage has a recycler, the sibling follows the file into the recycler so a restore keeps the pair intact. Closes #88.

Breaking change

  • Custom converters need a constructor update. Plan2net\Webp\Converter\Converter::__construct now takes a second argument: Plan2net\Webp\Service\Configuration $configuration. Third-party converter implementations have to add this parameter.

Fixes

  • .webp source files no longer create phantom rows in sys_file_processedfile.
  • FileReference inputs are normalised to their underlying File before the repository lookup, fixing a latent v12/v13 bug where the wrong UID was queried.
  • FileNameFilter no longer emits PHP 8+ warnings on invalid filter regex patterns.