Display Modes and Image Styles
|
This content was generated with the assistance of AI and should be verified against the official Drupal documentation before being relied on in production. This sub-section’s Drupal bibliography lists the reference material consulted while preparing these pages. |
Two configuration systems decide what a visitor and an editor see for every entity on a Drupal site. Display modes (view modes and form modes) decide which fields appear, in which order and through which formatter or widget. Image styles decide how an uploaded picture is turned into the files that a browser really downloads. They are both configuration entities, they are both edited in the administration interface, and they are both exported with configuration management. This page was checked against the official documentation on 2026-10-30 and is written for Drupal 11.4.x with PHP 8.3 or later. Nothing described here is among the modules or features that leave core in Drupal 12 (scheduled for the week of 2026-12-07), and the Drupal 10 line reaches its end of life on 2026-12-09, so new sites should not start on it.
The running example is the Meridian Museum. Its exhibition content type is shown as a full page, as a card in a
listing and as a hero banner on the home page; curators get a trimmed editing form of their own; and every photograph
must reach visitors as a small WebP or AVIF file instead of the 6000-pixel original that a photographer uploaded. The
related pages are Content types and fields,
Field types and entity references,
Media and the Media Library,
Breakpoints and responsive images,
Twig templates and debugging and
Performance and caching.
Part 1: View modes and form modes
Entities, bundles and displays
Every content entity type (node, media, user, comment, taxonomy term, block content and your own types) can be shown in
several contexts. A view mode is the name of such a context: full for the page of the entity itself, teaser for a
short version in a listing, search_index and search_result for search, rss for feeds and token for token
replacement. The User Guide defines a view mode as "the context in which an entity … is displayed" and a formatter as the
rule that shows a field’s values. For each combination of entity type, bundle and view mode there is one entity view
display, a configuration entity named core.entity_view_display.<entity_type>.<bundle>.<view_mode>. It stores, for each
field, whether it is shown, its weight, its label position and the formatter with its settings.
Form modes mirror this for editing. A form mode is a named variant of the entity edit form. The default form mode is
called default; the user entity also has a register form mode used by the account creation form. Each combination of
entity type, bundle and form mode has an entity form display,
core.entity_form_display.<entity_type>.<bundle>.<form_mode>, that stores, for each field, the widget, its settings
and its weight. The pieces fit together as follows.
The view mode and form mode definitions themselves are configuration entities too: core.entity_view_mode.<entity_type>.<mode>
and core.entity_form_mode.<entity_type>.<mode>. A mode definition has only an ID, a label, a target entity type and a
status; everything useful lives in the displays.
Screens and paths
-
Structure > Content types > Manage display (
/admin/structure/types/manage/exhibition/display) edits the view displays of one bundle. The Default tab is the fallback; further tabs appear for each view mode the bundle uses. -
Structure > Content types > Manage form display (
/admin/structure/types/manage/exhibition/form-display) edits the form displays. -
Structure > Display modes > View modes (
/admin/structure/display-modes/view) and Form modes (/admin/structure/display-modes/form) create and delete the modes themselves. -
The same Manage display tabs exist for media types, taxonomy vocabularies, users and block types.
Creating a mode does not make it available everywhere. At the bottom of Manage display, the Custom display settings
fieldset lists the view modes defined for the entity type, and a bundle only has its own display for a mode that you tick
there. This is the single most common surprise: a custom card mode that was never enabled for exhibition is
rendered with the default display, so an apparently changed configuration changes nothing.
The default display and the fallback chain
When code asks for an entity in a view mode, Drupal loads the display <type>.<bundle>.<mode>. If that display does not
exist or is not enabled, it falls back to <type>.<bundle>.default. This is why teaser and full work on a new bundle
without any configuration: both resolve to default until you enable Custom display settings for them. Teasers
usually differ from the full page in three ways: the body is shown through the Summary or trimmed formatter, the image
uses a smaller image style, and secondary fields such as the opening hours are hidden.
# config/sync/core.entity_view_mode.node.card.yml
langcode: en
status: true
dependencies:
module:
- node
id: node.card
label: Card
description: 'Compact card used in exhibition listings.'
targetEntityType: node
cache: true
# config/sync/core.entity_view_display.node.exhibition.card.yml (abridged)
langcode: en
status: true
dependencies:
config:
- core.entity_view_mode.node.card
- field.field.node.exhibition.field_hero_image
- field.field.node.exhibition.field_summary
- image.style.meridian_card_4x3
- node.type.exhibition
module:
- image
- text
- user
id: node.exhibition.card
targetEntityType: node
bundle: exhibition
mode: card
content:
field_hero_image:
type: image
label: hidden
settings:
image_link: content
image_style: meridian_card_4x3
image_loading:
attribute: lazy
third_party_settings: { }
weight: 0
region: content
field_summary:
type: text_trimmed
label: hidden
settings:
trim_length: 160
third_party_settings: { }
weight: 1
region: content
hidden:
field_gallery: true
links: true
field_related_objects: true
The dependencies block is generated for you. It shows why an image style cannot be deleted while a display uses it: the
display depends on image.style.meridian_card_4x3, and the configuration system refuses to delete a dependency that is
still in use (the delete form lists the dependent displays). Removing a style by editing exported YAML and importing it
causes the same error at import time, which is why a style is removed in a separate deployment after the displays have
stopped using it.
Choosing a view mode in each place that renders content
Where the view mode comes from depends on who renders the entity.
| Context | How the view mode is chosen |
|---|---|
Node page ( |
Always |
Views, with Show: Content |
A Row style setting in the view; the view |
Entity reference field with Rendered entity formatter |
The View mode setting of the formatter. |
Layout Builder block "Content" |
The view mode of the section’s default display. |
Media embedded in CKEditor 5 |
The Default view mode of the |
Custom code |
The argument to |
Rendering a referenced entity as a full node inside a listing is the most common performance mistake of site builders: it
loads and renders every field of every referenced entity. Prefer a light mode (teaser, card) for references and
reserve full for the entity’s own page. See
Field types and entity references for the loop-protection
behaviour of rendered entities.
Rendering a view mode in code
<?php
declare(strict_types=1);
namespace Drupal\meridian_collection\Controller;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Renders the three most recent exhibitions as cards.
*/
final class FeaturedExhibitionsController extends ControllerBase {
public function __construct(
private readonly EntityTypeManagerInterface $manager,
) {}
public static function create(ContainerInterface $container): static {
return new static($container->get('entity_type.manager'));
}
/**
* @return array<string, mixed>
*/
public function content(): array {
$storage = $this->manager->getStorage('node');
$ids = $storage->getQuery()
->accessCheck(TRUE)
->condition('type', 'exhibition')
->condition('status', 1)
->sort('created', 'DESC')
->range(0, 3)
->execute();
$nodes = $storage->loadMultiple($ids);
// viewMultiple() renders every node in one pass, which lets the
// formatters preload referenced entities.
return $this->manager->getViewBuilder('node')->viewMultiple($nodes, 'card');
}
}
Source: API: EntityViewBuilderInterface
The query calls accessCheck() explicitly because entity queries no longer assume it. The returned render array carries
cache tags (node:12, config:core.entity_view_display.node.exhibition.card) and the languages and user.permissions
contexts, so editing either the node or the display invalidates exactly the pages that used it.
A hook can also swap the mode just before rendering. Since Drupal 11.1 hooks are methods with the #[Hook] attribute on
autowired classes in src/Hook, and the method for hook_entity_view_mode_alter is registered like this.
<?php
declare(strict_types=1);
namespace Drupal\meridian_collection\Hook;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Hook\Attribute\Hook;
/**
* Uses the compact card for objects that are not on display.
*/
final class ViewModeHooks {
#[Hook('entity_view_mode_alter')]
public function alterViewMode(string &$view_mode, EntityInterface $entity): void {
if ($entity->getEntityTypeId() === 'collection_object'
&& $view_mode === 'teaser'
&& !$entity->get('on_display')->value) {
$view_mode = 'card';
}
}
}
Modules that must run on Drupal 10.x as well add a #[LegacyHook] procedural wrapper; a Drupal 11-only module needs
nothing else. Hooks for installation and updates stay procedural.
Form modes in practice
The Meridian curators edit exhibitions on a phone in the gallery, and the full editing form with 25 fields is too much
for them. A custom form mode curator shows only the title, the hero image, the on_display flag and the summary.
# config/sync/core.entity_form_mode.node.curator.yml
langcode: en
status: true
dependencies:
module:
- node
id: node.curator
label: Curator
targetEntityType: node
Source: Entity API
The mode is useless until code selects it. A route can ask the entity form builder for it through the _entity_form
route default, written as <entity_type>.<operation>. The operation is the form mode name.
# meridian_collection.routing.yml (excerpt)
meridian_collection.curator_edit:
path: '/curator/exhibition/{node}/edit'
defaults:
_entity_form: 'node.curator'
_title: 'Quick edit exhibition'
requirements:
_entity_access: 'node.update'
options:
parameters:
node:
type: entity:node
Three details are worth knowing. First, when an entity type has no form handler named after the mode, the default
handler class is used and only the form display changes, which is what happens for nodes. Second, the route performs the entity access check but nothing
here relaxes field-level access: a field hidden in a form mode is still validated and saved with its previous value, and
a field the user may not edit is not shown at all. Third, hiding a required field in a form mode makes the form
impossible to submit if the field has no default value, so required fields stay in every form mode that can save the
entity. A form mode is a presentation tool, not a permission mechanism.
For content-moderation sites, the transition buttons appear in whichever form mode shows the Moderation control
pseudo-field, so keep it in curator too. See
Content moderation, workflows and revisions.
View modes in Twig and template suggestions
A template can find out which view mode it is rendering: in node.html.twig the variable view_mode holds it, and
the theme system offers the suggestion node--exhibition--card.html.twig as well as node--card.html.twig. The
Meridian theme uses this to wrap the card in its exhibition-teaser component.
{# templates/content/node--exhibition--card.html.twig #}
{% set classes = ['exhibition-card', node.isPromoted() ? 'is-featured'] %}
<article{{ attributes.addClass(classes) }}>
{{ content.field_hero_image }}
<h3{{ title_attributes }}>
<a href="{{ url }}" rel="bookmark">{{ label }}</a>
</h3>
{{ content.field_summary }}
</article>
Source: Twig template naming conventions
Template suggestions, preprocess functions and how to find the right template with Twig debugging are covered in Template suggestions and preprocess and Twig templates and debugging. The cache behaviour of a render array is covered in Render API and cache metadata.
Performance and cache notes for view modes
-
The
cache: truekey of a view mode definition lets the entity view builder cache the rendered entity. Turn it off only for a mode whose output depends on something the cache contexts cannot express. -
Each rendered entity in a reference field adds a cache tag of the referenced entity, so editing a referenced object invalidates every page that embeds it. That is correct, and it is also why a heavily shared entity should use a light mode.
-
Layout Builder can override the display of a single entity (a per-entity layout). The override is stored on the entity, so later changes to the display configuration do not reach overridden entities. See Layout Builder.
Part 2: Image styles
Why image styles exist
An editor uploads a 7 MB photograph; the card shows it in a 400-pixel box. Shipping the original wastes bandwidth and ruins the page speed score, and resizing by CSS does not reduce the download. An image style is a named, ordered list of image effects that Drupal applies to the original to produce a derivative. The original is never modified, the derivative is created on the first request that needs it, and the result is cached on disk. Changing a style flushes its derivatives, which are then regenerated on demand.
Image styles live in the core image module. The configuration entity type is image_style, with configuration
names image.style.<machine_name>, and it exports the name, label and effects keys. The administration screen is
Configuration > Media > Image styles (/admin/config/media/image-styles) and the permission that guards it is
administer image styles.
Core effects
| Effect | What it does |
|---|---|
Scale |
Resizes keeping the aspect ratio so the result fits inside the width and height. Leaving one dimension empty keeps the ratio from the other. An Allow upscaling option decides whether small originals are enlarged. |
Scale and crop |
Resizes to cover the target box and crops the overflow around an anchor point. The result always has exactly the requested dimensions, so it is the usual choice for cards. |
Resize |
Forces exact dimensions without keeping the ratio. It distorts the picture and is rarely right. |
Crop |
Cuts a rectangle of a given size from an anchor position without scaling. |
Rotate |
Rotates by an angle, with an optional random mode and a background colour for the corners. |
Desaturate |
Converts to greyscale. |
Convert |
Changes the file format, for example from JPEG or PNG to WebP or AVIF. See the next section. |
Effects run in the order of their weights and each one receives the output of the previous one, so a Convert effect is
usually last. The Meridian meridian_card_4x3 style is a Scale and crop to 640 by 480 pixels followed by a Convert to
WebP.
Contrib modules add effects (focal point cropping, image-style-specific watermarking and so on), and a module can define
its own effect as a plugin in src/Plugin/ImageEffect. Core effects extend ConfigurableImageEffectBase and use the
#[ImageEffect] attribute, for example the image_convert plugin of class
Drupal\image\Plugin\ImageEffect\ConvertImageEffect.
Creating a style by hand and as configuration
The User Guide walks through the administration screen: add the style, add an effect, set the dimensions, then choose the style in the formatter settings of Manage display. The same style as exported configuration looks like this.
# config/sync/image.style.meridian_card_4x3.yml
langcode: en
status: true
dependencies: { }
name: meridian_card_4x3
label: 'Card 4:3 (640x480)'
effects:
3b9d5a10-7c2f-4f0a-9d1e-6a5b3c2d1e01:
uuid: 3b9d5a10-7c2f-4f0a-9d1e-6a5b3c2d1e01
id: image_scale_and_crop
weight: 1
data:
width: 640
height: 480
anchor: center-center
8c1e4b22-5d3a-4e7b-a2f6-9b0c4d5e6f02:
uuid: 8c1e4b22-5d3a-4e7b-a2f6-9b0c4d5e6f02
id: image_convert
weight: 2
data:
extension: webp
Use descriptive machine names that say what the style is for (meridian_card_4x3, meridian_hero_wide), not the
current size. A style named medium_300 that later becomes 480 pixels wide misleads everyone. Core installs the styles
thumbnail, medium, large and wide (the exact set depends on the install profile), and Media, the Media Library
and the user picture refer to some of them by name, so do not delete styles that you did not create.
Where the files go: derivatives and the styles/ directory
A derivative is an ordinary file stored beside the originals. For the public file system the layout is as follows.
web/sites/default/files/
2026-10/hero-gallery.jpg <- original (public://2026-10/hero-gallery.jpg)
styles/
meridian_card_4x3/
public/
2026-10/
hero-gallery.jpg.webp <- derivative
large/
public/
2026-10/
hero-gallery.jpg
The path is styles/<style>/<scheme>/<path of the original>. For the private file system the scheme directory is
private, and the files sit below the private directory, outside the web root. When the Convert effect changes the
extension, the new extension is appended to the original file name (hero-gallery.jpg.webp), so two originals that
differ only in extension never collide. The URL of the derivative contains an itok query parameter, for example
/sites/default/files/styles/meridian_card_4x3/public/2026-10/hero-gallery.jpg.webp?itok=Q7kZ3fXa.
The first request for a URL that does not exist yet does not match a real file, so the web server hands it to Drupal’s image style download route. Drupal checks the token, locks the derivative so that parallel requests do not generate it twice, applies the effects to the original, writes the file and streams it. Every later request is served by the web server straight from disk without starting PHP.
This design has consequences that explain most support questions.
-
The web server must route missing files under
styles/to Drupal. The default Apache.htaccessand the documented nginx location blocks do. A hand-written nginx configuration that answers 404 for any missing file undersites/*/filesproduces broken images for every derivative that has not been generated yet. See Requirements and hosting. -
The token protects against abuse. Without a token anyone could request thousands of arbitrary derivatives and fill the disk. The
itokvalue is derived from the style, the file and the private site key, so a visitor cannot invent new derivative URLs. Two settings inimage.settingsrelax this:allow_insecure_derivativeslets tokenless requests succeed, andsuppress_itok_outputremoves the token from generated URLs. Leave both atfalse. Section "Image style token and derivative security" below shows how to confirm them. -
Derivatives for the private scheme go through Drupal each time, because the web server cannot serve files outside the web root. They honour file access hooks and are an application-level cost. See File system and private files.
-
In a cluster, every web node needs the same files directory. A derivative written to one node’s local disk is invisible to its neighbours, which then regenerate their own. Use a shared volume or object storage. See Deployment and CI/CD.
-
Generating derivatives needs memory. GD decompresses the original into raw pixels, so a 24-megapixel photograph needs roughly 100 MB of PHP memory regardless of its file size. A "memory exhausted" error at the first request is the usual symptom, and the fix is
memory_limit, not a different style.
Flushing and warming
Changing or saving a style flushes all its derivatives, and the Flush operation on the style list does so on demand.
From the command line, Drush provides image:flush (alias if).
# flush the derivatives of two styles
ddev drush image:flush meridian_card_4x3,meridian_hero_wide
# flush every derivative; they are regenerated on demand
ddev drush image:flush --all
Source: Drush: image:flush
Flushing all styles of a large museum collection makes the next visitors pay the cost of generating thousands of derivatives at once. Flush selectively, and flush before a traffic peak rather than during it. The contrib Image Style Warmer module can create chosen derivatives when an image is uploaded or through a queue worker, so the first visitor does not wait.
Pages cache the URL of a derivative, not the file. After a style changes, the URL stays the same and the regenerated file replaces the old one, but browsers and CDNs that cached the old bytes keep serving them until their own lifetime ends. Purge the CDN as part of a deployment that changes a style.
Using a style from code
<?php
use Drupal\file\Entity\File;
use Drupal\image\Entity\ImageStyle;
// Build the URL of a derivative for a stored file (inside a service use
// the entity type manager instead of the static loaders).
$file = File::load($fid);
$style = ImageStyle::load('meridian_card_4x3');
if ($file !== NULL && $style !== NULL) {
$url = $style->buildUrl($file->getFileUri());
// The derivative exists only after the first request for $url, unless it
// is created now:
$style->createDerivative(
$file->getFileUri(),
$style->buildUri($file->getFileUri()),
);
}
Source: API: ImageStyle
The methods that matter are buildUri() (the path a derivative will have), buildUrl() (the URL with the token),
createDerivative() and flush(). When a template only has a file, prefer the Twig theme function: the image_style
theme hook renders an img with width and height computed from the style, so the layout does not shift.
$build = [
'#theme' => 'image_style',
'#style_name' => 'meridian_card_4x3',
'#uri' => 'public://2026-10/hero-gallery.jpg',
'#alt' => 'Hands-on pendulum exhibit in the Motion gallery',
'#attributes' => ['loading' => 'lazy'],
];
Image style token and derivative security
Image-derivative generation is a classic denial-of-service surface: each new URL costs CPU, memory and disk. The defaults protect you, and you should keep them. Check the two flags with Drush.
ddev drush config:get image.settings
# allow_insecure_derivatives: false
# suppress_itok_output: false
Source: Drush: config:get
If a CDN or search crawler strips query strings and tokenless requests therefore fail, the correct answer is to make the
CDN forward the query string for /styles/ paths and not to enable allow_insecure_derivatives. If you really need
tokenless URLs (for example for a static site export), keep the set of styles small, limit what the web server accepts
with rate limiting, and set the flags in settings.php for that one environment only.
// settings.php of a throwaway export environment only.
$config['image.settings']['suppress_itok_output'] = TRUE;
Also remember that an image style is not an access control mechanism: for public files the derivative is a public URL as soon as it has been requested. Files that must stay confidential belong in the private file system.
Uploads themselves are restricted by the field’s allowed extensions (png jpg jpeg webp is a good default; never
svg for untrusted editors without sanitising it, and never php or html). Image styles only process raster
formats that the toolkit supports; an SVG is served as it is.
Part 3: Format conversion, WebP and AVIF
The Convert effect
The Convert effect (plugin ID image_convert) changes the format of the derivative. Its Convert to list is built from
the formats the active image toolkit supports, which is why the same site shows different choices in different
environments. The default toolkit is GD, shipped with PHP; the contrib ImageMagick module provides an alternative
toolkit that is often faster and supports more formats.
| Format | Notes |
|---|---|
JPEG, PNG, GIF |
Always available with GD. |
WebP |
Converting to WebP with the Convert effect has been supported by core for years. Needs GD with WebP support, which current PHP builds include. Typically 25 to 35 percent smaller than JPEG at equal visual quality. |
AVIF |
Supported by the core GD toolkit since Drupal 11.2, provided PHP’s GD extension is built on libgd 2.3.2 or later with libavif. Smaller than WebP, slower to encode. |
The format list is the thing to check on every environment. Run php -r 'print_r(gd_info());' and look for the
WebP Support and AVIF Support entries, or look at the Convert to list on a style’s effect form. A development
container may lack AVIF while production has it, or the opposite.
AVIF with a fallback effect
Drupal 11.2.0 also added an effect named Convert to AVIF (with fallback). Because AVIF support depends on the server, AVIF cannot be the default for everyone. The effect creates AVIF derivatives where the toolkit supports the format, and falls back to another style, for example one that converts to WebP, where it does not.
The practical rule for Meridian is therefore:
-
Create
meridian_card_4x3_webpwith Scale and crop followed by Convert to WebP. This style works everywhere. -
Create
meridian_card_4x3with Scale and crop followed by Convert to AVIF (with fallback), pointing at the WebP style. -
Use the AVIF style in formatters.
Whenever the toolkit lacks AVIF, the fallback turns the request into a WebP derivative and nobody sees a broken
image. This answers a known pitfall of the plain approach: an image style that targets AVIF on a server without AVIF
support may fail silently and leave editors with missing pictures. Related work on adding avif to the default allowed
extensions of the standard image fields is still under discussion on drupal.org, so add it to your image field
settings yourself if editors should upload AVIF originals.
Browser support and Accept negotiation
Drupal’s Convert effect writes one format per style and emits a single img URL. It does not negotiate the format with
the Accept header. Every current mainstream browser displays WebP and AVIF, so one converted format is usually fine.
When you need a guaranteed format for each browser, use a picture element whose source elements have different
type attributes. That is done through responsive image styles, where each image style of a multiple-styles mapping
can end in a different Convert effect. See
Breakpoints and responsive images.
Older books and tutorials
Older books such as Drupal 10 Masterclass (2023) and Modernizing Drupal 10 Theme Development (2023) were written for Drupal 10.0 and 10.1, before the AVIF toolkit support of Drupal 11.2. They explain the Convert effect with JPEG, PNG and WebP only, and a tutorial written then does not offer the AVIF or fallback effects. The Drupal 10 line ends on 2026-12-09, and its last minor is 10.6, so these books are best read for the concepts (view modes, formatters, styles) and not for version-specific behaviour. Their descriptions of the administration screens for view modes and image styles remain recognisable in Drupal 11.
Part 4: Lazy loading
Browsers can postpone loading offscreen images when the img element has loading="lazy". The core Image formatter
exposes this as a setting, image_loading, with the values lazy (the default) and eager. The setting form describes
eager as the choice for images that are always displayed.
# in the formatter settings of a view display
type: image
settings:
image_style: meridian_hero_wide
image_link: ''
image_loading:
attribute: eager
Source: API: ImageFormatter
The rule is one of Core Web Vitals. Mark the single image that is the largest element in the first viewport (the hero
banner on the Meridian home page, which is the Largest Contentful Paint element) as eager, and leave every other
image on lazy. Lazy loading the hero delays the largest paint, and eager loading a gallery of 60 thumbnails
downloads them all on page load. The attribute is only a hint; it does not change the file size. Lazy images without
width and height attributes cause layout shifts. The core formatter outputs the dimensions of the derivative, so keep them on the element and use
CSS aspect-ratio or a fixed box in the theme where the markup is custom.
Other pieces rendered through other paths, such as images inside the body text, are handled differently: the CKEditor 5
image plugin stores a plain img in the text, and the core lazy-loading text filter (FilterImageLazyLoad), enabled per text format, adds loading="lazy" to
images that carry width and height attributes and do not already say loading="eager". See
Text formats and CKEditor 5.
Part 5: Responsive images
One image style produces one size. A responsive page needs several sizes of the same image, and the browser picks the
right one. The core Responsive Image module maps breakpoints defined by the active theme to image styles and outputs
either an img with srcset and sizes or a picture element. In Drupal it adds two things: a configuration entity,
the responsive image style at Configuration > Media > Responsive image styles
(/admin/config/media/responsive-image-style), and a field formatter called Responsive image, which replaces the
Image formatter in Manage display. The formatter has the same image_loading setting as the Image formatter.
The use of a responsive style in the Meridian hero view mode is therefore only a matter of selecting a different
formatter in the same screen described in Part 1; no template changes are needed.
# core.entity_view_display.node.exhibition.hero (excerpt)
content:
field_hero_image:
type: responsive_image
label: hidden
settings:
responsive_image_style: meridian_hero
image_link: ''
image_loading:
attribute: eager
weight: 0
region: content
Source: Responsive Image module
Breakpoints are defined by a THEME.breakpoints.yml file, grouped and given resolution multipliers; the mapping of
breakpoints to image styles, the choice between the srcset/sizes and picture approaches, art direction and the
common mistakes of mapping are explained in
Breakpoints and responsive images. Media items, the Media Library
and image fields in Views use the same formatters, so a responsive style set once applies everywhere the formatter is
used. See Media and the Media Library for the media view modes and the
hero template override.
Common errors and pitfalls
| Symptom | Cause and fix |
|---|---|
A new view mode changes nothing |
The mode is not enabled in Custom display settings for the bundle, so the |
The field does not appear on the teaser |
It is hidden in the |
Editing a display does not affect an exhibition |
The node uses a Layout Builder override. Revert the override or reapply the layout. |
Broken image links for new uploads, working ones for old |
The web server does not hand missing files under |
HTTP 403 on a derivative |
The |
The style form offers no AVIF option |
GD was not built with libavif, or libgd is older than 2.3.2. Check |
Large photos fail with a white page or a 500 |
PHP |
Derivatives look stale after changing a style |
The style was imported but not flushed, or a CDN keeps the old file. Run |
The hero image appears late |
It is |
Deleting an image style is refused |
A display, responsive style or Media Library configuration depends on it. Replace the references first. |
Checking the whole configuration
A short checklist for the Meridian site before a release.
# every display that uses an image style
ddev drush config:status
ddev drush php:eval 'foreach (\Drupal::entityTypeManager()->getStorage("entity_view_display")->loadMultiple() as $d) { foreach ($d->getComponents() as $n => $c) { if (!empty($c["settings"]["image_style"])) { echo $d->id(), " ", $n, " ", $c["settings"]["image_style"], PHP_EOL; } } }'
# regenerate the derivatives of the changed styles
ddev drush image:flush meridian_card_4x3
ddev drush cache:rebuild
Source: Drush: php:eval