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.
{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"
/>
Parameters
path
-
- Type
- string
- Required
true
Public path to the source image (for example
/fileadmin/foo.jpg), typically generated viaf:uri.image().
width
-
- Type
- int|float
- Default
- 0
Base width in pixels for the rendered
<img>.0resolves automatically from the source file. Clamped by the processor to 1--8192 when baked into the variant URL.
height
-
- Type
- int|float
- Default
- 0
Base height in pixels.
0preserves aspect ratio relative to width. Clamped by the processor to 1--8192.
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
-
- Type
- string
- Default
- empty string
Alternative text for the image. Always rendered (even when empty) to keep assistive-tech compatibility.
title
-
- Type
- string
- Default
- empty string
HTML-escaped title attribute.
class
-
- Type
- string
- Default
- empty string
CSS classes for the
<img>tag. Includelazyloadto switch from native to JS-based lazy loading (see Lazy loading).
mode
-
- Type
- string
- Default
- cover
Render mode.
coverresizes images to fully cover the given dimensions (crop/fill).fitresizes images to fit within the given dimensions.
lazyload
-
- Type
- boolean
- Default
- false
Add
loading="lazy"(native lazy loading).
responsiveSrcset
-
- Type
- boolean
- Default
- false
Enable width-based responsive
srcsetinstead of the density-based2xoutput (preserved for backward compatibility).
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
-
- Type
- string
- Default
- auto, (min-width: 992px) 991px, 100vw
Responsive
sizesattribute for the generated<img>tag.
fetchpriority
-
- Type
- string
- Default
- empty string
Native HTML
fetchpriorityattribute. Allowed values:high,low,auto. Omitted when empty.
attributes
-
- Type
- array
- Default
- []
Extra HTML attributes merged into the rendered tag.
Note
Quality and output format are not exposed as ViewHelper
arguments. Quality defaults to 100 and is baked into the
generated /processed/...q<n>... URL; the variant's
file extension is inherited from the source image. Use
the URL format and
variant negotiation
to influence the served format.
Source set configuration
Define source sets per media breakpoint via the set
attribute:
<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}
}"
/>
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.
<nr:sourceSet
path="{f:uri.image(
image: image,
width: '960',
height: '690',
cropVariant: 'default'
)}"
width="960"
height="690"
mode="fit"
/>
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:
/processed/<original-path>.<mode-config>.<ext>[?<query>]
<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
.webpsidecar, or the.avifsidecar based on theAcceptheader and the query flags below.
/processed/fileadmin/photos/hero.w1200h800m0q85.jpg
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-Typealways 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
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:
- Imagick when the
imagickPHP extension is loaded (preferred -- supports AVIF natively if the underlying ImageMagick build does). - GD when
imagickis unavailable and thegdextension 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/ 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.