Configuration 

The extension works out of the box with sensible defaults. All three operating modes -- on-demand frontend processing, on-upload compression, and bulk CLI -- activate automatically after installation. This page documents the extension points that can be tweaked.

SourceSetViewHelper 

The SourceSetViewHelper generates responsive <img> tags with srcset attributes.

Basic ViewHelper usage
{namespace nr=Netresearch\NrImageOptimize\ViewHelpers}

<nr:sourceSet path="{f:uri.image(image: image)}"
              width="1200"
              height="800"
              alt="{image.properties.alternative}"
              sizes="(max-width: 768px) 100vw, 50vw"
              responsiveSrcset="1"
/>
Copied!

Parameters 

path

path
Type
string
Required

true

Public path to the source image (for example /fileadmin/foo.jpg), typically generated via f:uri.image().

width

width
Type
int|float
Default
0

Base width in pixels for the rendered <img>. 0 resolves automatically from the source file. Clamped by the processor to 1--8192 when baked into the variant URL.

height

height
Type
int|float
Default
0

Base height in pixels. 0 preserves aspect ratio relative to width. Clamped by the processor to 1--8192.

set

set
Type
array
Default
[]

Responsive set in the form {maxWidth: {width: int, height: int}}. Each entry becomes a <source media="(max-width: <maxWidth>px)"> tag.

alt

alt
Type
string
Default
empty string

Alternative text for the image. Always rendered (even when empty) to keep assistive-tech compatibility.

title

title
Type
string
Default
empty string

HTML-escaped title attribute.

class

class
Type
string
Default
empty string

CSS classes for the <img> tag. Include lazyload to switch from native to JS-based lazy loading (see Lazy loading).

mode

mode
Type
string
Default
cover

Render mode. cover resizes images to fully cover the given dimensions (crop/fill). fit resizes images to fit within the given dimensions.

lazyload

lazyload
Type
boolean
Default
false

Add loading="lazy" (native lazy loading).

responsiveSrcset

responsiveSrcset
Type
boolean
Default
false

Enable width-based responsive srcset instead of the density-based 2x output (preserved for backward compatibility).

widthVariants

widthVariants
Type
string|array
Default
480, 576, 640, 768, 992, 1200, 1800

Width variants for responsive srcset (comma-separated string or array). Only honored when responsiveSrcset is enabled.

sizes

sizes
Type
string
Default
auto, (min-width: 992px) 991px, 100vw

Responsive sizes attribute for the generated <img> tag.

fetchpriority

fetchpriority
Type
string
Default
empty string

Native HTML fetchpriority attribute. Allowed values: high, low, auto. Omitted when empty.

attributes

attributes
Type
array
Default
[]

Extra HTML attributes merged into the rendered tag.

Source set configuration 

Define source sets per media breakpoint via the set attribute:

Source set with breakpoint-specific dimensions
<nr:sourceSet
    path="{f:uri.image(
        image: image,
        width: '960',
        height: '690',
        cropVariant: 'default'
    )}"
    set="{
        480:{width: 160, height: 90},
        800:{width: 400, height: 300}
    }"
/>
Copied!

Render modes 

cover
Default. Resizes images to fully cover the provided width and height.
fit
Resizes images so they fit within the provided width and height.
Using fit mode
<nr:sourceSet
    path="{f:uri.image(
        image: image,
        width: '960',
        height: '690',
        cropVariant: 'default'
    )}"
    width="960"
    height="690"
    mode="fit"
/>
Copied!

Lazy loading 

Both modes support lazy loading via the native loading="lazy" attribute. When using JS-based lazy loading (class="lazyload"), the data-srcset attribute is added automatically.

Backward compatibility 

By default responsiveSrcset is false, preserving the existing 2x density-based srcset behavior. All existing templates continue to work without modifications.

Variant URL format 

Processed variants are served from a dedicated URL path. The ViewHelper generates these URLs automatically, but any markup that writes a URL of this form will be intercepted by the ProcessingMiddleware:

URL template
/processed/<original-path>.<mode-config>.<ext>[?<query>]
Copied!
<original-path>
Public path of the source image, including the /fileadmin/ (or other storage) prefix. Path traversal sequences (..) are rejected at URL-parsing time.
<mode-config>

Concatenation of one or more of:

w<n>
Target width in pixels.
h<n>
Target height in pixels.
q<n>
Quality (1--100).
m<n>
Processing mode (0 = cover, 1 = scale/fit).
<ext>
Source image extension. The processor decides at response time whether to serve the original, the .webp sidecar, or the .avif sidecar based on the Accept header and the query flags below.
Example URL
/processed/fileadmin/photos/hero.w1200h800m0q85.jpg
Copied!

Variant negotiation 

When the processor generates a variant, it writes the original file to disk and additionally produces a .webp and an .avif sidecar (same base name). On each request it inspects the Accept header and returns the best match the client supports, preferring AVIF over WebP over the original format.

Two query parameters let callers opt out of sidecar generation for individual URLs:

skipWebP=1
Do not produce or serve a WebP variant for this URL. The Content-Type always matches the source extension.
skipAvif=1
Do not produce or serve an AVIF variant for this URL. If WebP is still allowed and the client supports it, WebP is served.

These flags are useful when specific consumers (for example e-mail clients or legacy RSS renderers) cannot handle modern formats.

Cache headers 

Processed variant URLs are effectively content-addressed -- any change to dimensions, quality, or format produces a different URL. The processor therefore responds with an immutable, long-lived cache header:

Cache-Control: public, max-age=31536000, immutable
Copied!

This value is a compile-time constant and not user-configurable.

Image driver selection 

Intervention Image is instantiated through \Netresearch\NrImageOptimize\Service\ImageManagerFactory, which selects the best available driver at runtime:

  1. Imagick when the imagick PHP extension is loaded (preferred -- supports AVIF natively if the underlying ImageMagick build does).
  2. GD when imagick is unavailable and the gd extension is loaded.

If neither extension is present, the factory throws a RuntimeException with a descriptive message. Use the backend maintenance module to verify driver availability on your host.

Middleware registration 

Configuration/RequestMiddlewares.php registers the ProcessingMiddleware on the frontend pipeline before typo3/cms-frontend/site. This ordering is required so the middleware can intercept /processed/ URLs before TYPO3's frontend routing claims them. The registration has no user-configurable options.

Processor limits 

The processor enforces the following bounds when parsing a URL:

MAX_DIMENSION
Width and height are clamped to 1--8192 pixels to prevent denial-of-service via excessive memory allocation.
MIN_QUALITY / MAX_QUALITY
Quality is clamped to 1--100.
LOCK_MAX_RETRIES
Up to 10 attempts (at 100 ms intervals) to acquire the per-variant processing lock before returning HTTP 503. Prevents duplicate work when multiple clients hit the same uncached variant simultaneously.