 Good afternoon, everyone. Since you're here, you probably agree with this statement. Images are an important part of the web as a medium. Being able to display photographs, diagrams, charts, and other images on the page with text and other elements is one of the most powerful features of the web. It's right up there with other basic functionality like hyperlinks, the way we connect pages together, the magical way you can go from one page to another. So it's fundamental to our experience on the web. Images help to provide visual interest, they increase engagement, and they convey information. But because images are so fundamental to our experience on the web, it's possible we take them for granted. We don't think carefully enough about how they'll be integrated into a website when we're first starting or as we're developing and maintaining on an ongoing basis. Any sort of image plan that gets developed is often done in ad hoc manner rather than as part of a well-thought-out strategy. So for example, when building a site in Drupal, we spend quite a bit of time thinking about what content types we're going to need and what fields are going to go on them. We think about taxonomy, vocabularies, and how we're going to categorize our data. We think about users of the site and the permissions they'll need. But images are not often given the same amount of attention. And that results in a lack of a defined strategy for how images are going to be managed and displayed on the site. And not having a strategy can result in inconsistencies, inefficiencies, and reduced site performance. So in this session, I'll be talking about how to create an image plan for a Drupal website. The end goal is simplification for how images are managed, standardization for how images are rendered, and improved site performance. My name is Rick Hawkins. I lead the Drupal capability at Slalom, which is a tech consulting company. We have almost 40 offices in North America and eight offices in Australia, Germany, Japan, the UK, and Ireland. I've been the primary organizer of the Seattle Drupal users group for many years. And I maintain a couple dozen modules on Drupal.org. Many of those modules are related to security, and many of them are related to images. And I'll be talking about the image-related ones in the session today. So when thinking about creating an image plan for a Drupal website, here are five top level categories of considerations to take into account. Besides general strategic considerations, it's a good idea to think about how image files are going to be named and organized. And it's important to think about how images are gonna be processed and rendered. And finally, it's smart to think about how to make the experience of uploading, finding, and managing images on the site as good as possible for the users who are doing that. The benefits of taking these considerations into account and creating a well-defined image plan are achieving a level of standardization that provides consistency to how images are displayed and managed on the site. Simplifying your approach makes site development and management much easier, and it allows you to spend less time thinking about images once your plan has been defined and implemented. Standardization and simplification often then result in improved site performance. So the first category of consideration is general strategy, which means thinking broadly about site-wide requirements related to images. What image file, what file format should you use for images? The three formats you see on the left there are well-supported by web browsers and have been for many years. WebP and AVIF are newer formats that offer improved compression, which means smaller file sizes. WebP has very good browser support. AVIF's browser support is decent, but it may not be wise to use it quite yet. Unless you have the ability to provide a fallback image for with a better supported format. There are newer file formats on the horizon that don't yet have good browser support, but it's a good idea to keep an eye on the landscape in case new file format formats come along that have broad browser support. SVG is well-supported by browsers, but it needs to be handled differently because it's a different type of format. It's a vector format versus raster, which is what all the others are. Drupal added native support for WebP in version 9.2, and that means that users can upload WebP images and they can convert images to WebP as part of an image-style definition. There are contributed modules that provide additional support for WebP and here are two of them. WebP automatically makes a copy of an image and saves it in WebP format. It essentially provides a turnkey solution for providing WebP versions of all the uploaded images on your site. The image API optimized WebP, besides being a mouthful, does something similar, but it does it as part of an image optimized pipeline and I'll be talking about those pipelines a bit later. WebP files will generally be smaller than JPEGs, GIFs, or PINGS, so I recommend you render WebP images whenever possible. Consider whether your site needs to support SVG images. Do your users need to be able to upload logos or other scalable vector graphics? Drupal core out of the box does not support uploading SVG images, but there are contributed modules that do, and they take different approaches so it's important to understand the difference and determine which one will suit your needs best. The SVG image field module adds a new field type, so when you create a new field, SVG image will be there as an option. It also provides a new widget and formatter to support that field type. The SVG image module, the second one, takes a different approach and it alters the default image field widget provided by Drupal core and the formatter that provided by Drupal core, so in a single image field, you could allow users to upload JPEGs, PINGS, and SVGs, but since SVGs are fundamentally different, it's generally best to use a different field and not try to combine them. Whichever approach you choose, be sure that if you're going to render the SVGs inline, that you sanitize the output because you couldn't introduce a cross-site scripting vulnerability. The good news is both of these modules provide sanitization of inline rendered SVGs. Consider whether all images on your site should be publicly accessible or do you need to keep some of them private or maybe all of them private. The default download method in Drupal is set in a site-wide setting that you see on the left where you can choose public, private, or even a third option if you've installed a module that adds another option like AWS S3 bucket, for instance, if you wanna store your files there. And then on the right-hand side, we have an image field definition and you can set the upload destination for that specific field in the settings for the field. So if you need to keep certain content on your site accessible only to certain users, it's critical to think about restricting access to images that are related to that content. A decision to make is whether you're gonna use image fields directly or if you're gonna take advantage of the media handling capabilities within Drupal. And use media entities and entity references. And I highly recommend using media entities unless there's a compelling reason not to. Adding an extra entity reference, using media entities as an extra entity reference between the base entity and the file entity but there are huge advantages. So you can add fields and common fields that you might add to a image media entity are a caption or a source information about the image. And then once the image is added, it's available within the media library to be used throughout the site. Media entities can be embedded in a WYSIWYG editor and metadata can automatically be extracted from them and stored in fields on the media entity extracted from the files themselves. And then last, a page can be exposed for that media entity if desired. If you do choose to use media entities, you'll need to determine which media types you'll need. So this is similar to deciding what content types you need, what nodes you'll need on your site. You might base your decision on what fields are required for a particular image type, how the image will be used on the site and characteristics of images. So when you first enable the media module, you get five media types created. And one of them is image. But keep in mind, you don't have to only use that one media type for images. You can create as many media types as you need to support your image requirements. So for example, if you have the need for a very large, wide image for a hero, say, at the top of a page, consider making a banner image media type. And then you can do things like set a minimum resolution that's higher than other image media types. And if you decide to allow SVGs to be uploaded, you should probably create a vector image media type just to handle the specific requirements of SVG. It's a good idea to think about how images on your site will be made available if a page is shared on social media. And this is usually done by defining meta tags. The meta tag contributed module is a good option for providing that functionality. Meta tag, the meta tag module has a number of sub modules that provide different fields for different purposes. And the two of them are open graph and Twitter cards. So when you enable those, it will create meta tag fields for use by Facebook, Pinterest, LinkedIn and Twitter. Specifying the image in meta tags ensures that the preferred image is used and that is the right size and dimensions for social media platforms. You may decide to opt out of managing images in Drupal altogether and use an external image hosting solution. Here are three popular ones, Cloudinary, Serve and ImageX. All of them essentially take the place of Drupal's native image style and responsive image style functionality. There are contributed modules that provide integration with each of these three platforms. And I'm most familiar with Serve because I wrote the module that provides Drupal integration with it. External image hosting services provide image optimization and additional features that aren't available in Drupal. For example, serve supports being able to zoom in on an image or view an item in a photo from all angles which are useful features for e-commerce. Drupal by default requires that a token be included in requests for image derivatives. You've probably seen the italk query parameter which is added to image URLs. If that token is missing and the derivative hasn't been generated yet, the derivative will not be created and therefore the image will be missing on the page. Occasionally you may have the need to allow image derivatives to be generated without this token. You have a couple of options. There's a site-wide setting provided by Drupal Core. It's called allow insecure derivatives and it can be set to true. Now insecure sounds kind of scary but really all this setting does is allow a derivative to be generated without a token. It's a site-wide setting so it's all or nothing. It applies to all image styles. I wanted to have more control over which image styles would allow creation of derivatives without a token so I wrote the image derivative token module and it allows setting, it creates a setting to allow insecure derivatives for only certain image styles. So when editing an image style, there's a new setting which you can see here for allowing derivatives to be created for that image style without a token. And there's also a setting to suppress output of that image token in the first place. The second category of considerations to take into account is file organization. So that means customizing the paths to images and organizing them in a particular way within the server's file system. And thinking about if and how names of files will be altered and these considerations apply to all files, not just images. It's generally recommended to avoid saving all uploaded images or any other file into a single directory. So it's important to think about how to separate files into different directories unless you have a very, very small website and you know you're only gonna have a handful of files. Drupal Core by default uses the current year and month which means that if I upload a file today it would be saved in a directory named 2023-06. Some people aren't crazy about that approach, they want an alternative. Luckily the file field paths module provides more options. So you can use with file field paths you can use values from the uploaded file or from the entity that it's being added to. So in my example that's the screen capture on the left. In the example that I gave the path that I entered includes the media type name and the value of a custom field added to the media entity called category. So the path will be the media type slash and then the category whatever was entered for that media. You can also clean up file names and this provides really powerful options for how you can standardize how uploaded files are named. And a lot of it is done by passing the file name through path auto. So you can force, for example, only lowercase characters in your file names, replacing spaces with dashes, removing punctuation and converting, transliteration which is converting characters with diacritical marks to ones that don't have them. One of my colleagues, Andrew Morton here, recommended setting the file name to be the alt text the user enters to describe the image which I thought was pretty clever. So that way the file will have a descriptive name and it could be good for SEO if indexed images are important to your site. There are two contributed modules that you can use to customize file paths and file names further. File name, they are similar but they're slightly different. File name hash token is a module that I wrote that generates a hash which is a unique string of hexadecimal characters based on the name of the file. So you can use a portion of that hash to customize which subdirectory the file is placed in. So if you use one character from the hash, for instance, your files will evenly be distributed into 16 different directories. The file hash module does something similar but its hash is generated from the contents of the file itself, not the file name. And you could also use a substring from that in order to evenly distribute files into subdirectories. You can use that module to completely rename the file to the generated hash and it will be a unique value because it's based on the contents of the file. You could also use that unique hash to prevent uploading a duplicate file because even if somebody changes the name of the file the hash will be the same and you'll be able to say that file is a duplicate, so it could be useful. So the third category of considerations is image processing, which involves thinking about how image data will be altered. In Drupal you can specify which toolkit you wanna use to process images. And the default image toolkit is GD2, but there are alternatives and the most popular one is, the most popular alternative is image magic which provides additional features and functionality. To make it available you just add the image magic contributed module, but to use image magic your web host must support it but the good news is all three major Drupal hosting platforms, Acquia, Pantheon and PlatformSH support image magic. Some modules that process or generate images don't work with GD2 so you would have to use image magic. An example of that is there's a module called media thumbnails PDF which generates thumbnail images from PDFs and that requires image magic. The most common effects applied to images are scaling and cropping because applying these two effects is the easiest way to generate the right sized image derivatives from an original. But there are modules that provide additional image effects and one such module is called image effects. And here's some examples of some of the effects the module provides. You can shift the color, add a mask, change the opacity, pixelate, add a watermark. Sharpen is especially useful for images that have been scaled since scaling can introduce blurriness and sharpening then helps make the image more crisp. So after you scale, it's helpful to add the sharpen effect to just make it a little more crisp. All image effects provided by this module work with both GD2 and image magic. The image module provided by Drupal Core creates four image styles when it's first installed and all of them only scale an image to a maximum with their height. They do not crop. So unless your site has very simple image needs, you'll wanna create additional image styles. And I recommend choosing a small number of aspect ratios, maybe four or five that you're gonna use across your entire site. Images on the web tend to be more wide than tall so you may need several landscaped aspect ratios. You can see I have three here, one portrait and a square aspect ratio. It can be helpful to base your aspect ratios on classic proportions from photography and video. So I've got like a 16 by nine, three by two, those tend to work well. Limiting the number of aspect ratios used across your site is part of both standardizing and simplifying within an image plan. I don't like creating image styles, I find it tedious. So I wanted to be able to generate them automatically. So I wrote a module that does that. It's called image style generate. And it allows you to define patterns that are used by Drupal's Migrate API to generate image styles in bulk. So you begin by defining style groups which usually map to those aspect ratios that I was talking about. So if you had four or five aspect ratios, you were supporting you to have four or five style groups. And then you define the base sizes that you want to apply. That's usually the image width. And then you can define size scales which are multipliers of the base sizes for supporting devices with high resolutions. And then you define which image effects to apply and then how they should be labeled. So after running image style generate, your list of image styles might look something like this. So you can see I've got three aspect ratios. I'm using a square one landscape portrait. And we've got a selection of base sizes and size scales. Note the consistency of the labeling and the wide range of sizes I now have available in the three aspect ratios. Cropping is a very common effect to be applied to images of course. It's useful to help maintain the consistency of rendering images with a selected set of proportions, those aspect ratios I was talking about. Vocal point is a very popular module for that enhances cropping. It allows users to set a crosshair on an image to indicate where crops should be centered. It's often a good idea to set up focal point even if you don't know you're gonna need it yet because it doesn't cause any harm if it's not used and it'll be immediately available if and when you need it. The image widget crop module offers much more precise control for how cropping occurs. And the image effect module I mentioned earlier provides an effect that performs smart cropping where it attempts to determine based on the contents of the image what is the most important part and it focuses the cropping there. Optimizing images generally means reducing the size without noticeably sacrificing image quality. Some methods to optimize images include manually optimizing images before uploading, using image opt-in on the Mac or some other application. You could reduce the quality setting in whatever toolkit you're using. So GD2 or image magic. In GD2 the default quality is 75% for JPEGs. You could bump that down to 60 and you'd instantly get smaller file sizes on your image derivatives. You can employ the convert image effect provided by Drupal Core to convert an image into a format that has better compression such as WebP. And the WebP module I mentioned earlier will automatically generate a WebP version of all your images. So you can just enable that and get better optimized images. You can take advantage of the capabilities provided by the image optimized module which provides a framework for creating pipelines that contain processors. And pipelines exist separately from image styles. So within pipelines you can do things like generate files in other formats or run tools on your server to perform optimization or you could run an external optimization service. And here's what an image optimized pipeline looks like. On the left is the definition for a pipeline called derive WebP. And it generates a WebP version of the image and then it uses GD2 to perform compression on it. And you can add as many processors as you want to the pipeline. And then on the right you can see in the wide image style settings. At the very bottom I've selected the derive WebP pipeline to be run after the image effects are applied. So if you do use a pipeline for compression it's generally a good idea to set the default compression to 100% and let the pipeline handle the compression. I mentioned that there are image optimization services. Here are three popular ones but there are others. Resmushet, Kraken.io and Image Optim. Each of these services has a contributed module that provides integration with the image optimized module for use in pipelines. Resmushet is the only free option. The other two are paid options and Resmushet limits file uploads to five megabytes. Uploaded images can contain metadata. I took this selfie a few hours ago and when I opened it in the max preview application you can see what metadata was saved and it includes things like the kind of camera that was used and the shutter speed, white balance, kind of boring stuff. But images also contain GPS data about where the photo was taken, the latitude, the longitude and helpfully and that I was traveling zero kilometers per hour when I took the photo. Note that the preview application on my Mac even plotted on a map precisely where the photo was taken. So that raises privacy concerns. If you have users uploading photos they may have taken at their house. So it's important to know, so there are legitimate reasons for wanting to retain metadata but it's important to know when metadata is preserved and when it's stripped in Drupal. So if you use the default GD2 toolkit metadata is preserved on the original image but it's stripped from any images derived from the original. So you may have seen this before where you upload a photo that you took with your phone and all the derivatives are upside down. And that's because the metadata got stripped and the orientation is part of the metadata. There is a, the image effects module has an effect that will fix the orientation. When, if you're using the image magic toolkit metadata is preserved on the original image and also on the derivatives. So the only time image metadata is stripped in Drupal by default is in image derivatives generated with GD2. So what should you do if you want to ensure that potentially sensitive data doesn't exist in your uploaded files? You can alert users about the situation and tell them that metadata that may not be stripped and suggest methods to manually remove the metadata from files they upload. You could automatically remove metadata from images when they were uploaded. I don't know of a contributed module that does this. I've started work on one but it's still in progress. I'd like to see this option in Drupal Core at some point. There is an issue that I've linked to to add that functionality. If site visitors don't ever need to see the original uploaded images, you can prevent access to the directories that contain the original images. And then for the image magic toolkit, the image effects module has an effect called strip metadata which can be used in an image style to strip metadata when image derivatives are generated. So, this chart would say no. If you use that, then in that lower right, the lower right area would say no. It would be similar to GD2. Okay, the fourth category of considerations is image rendering which means developing a strategy for how to render images in a way that will maximize performance. Drupal supports the native lazy loading functionality provided by modern browsers and it is enabled by default for the image field formatter as seen on the right. It's generally best to not change that setting except perhaps for images that are gonna be displayed at the top of the page and you don't want them to lazy load. This feature did not originally support lazy loading for responsive images but that support has been added to Drupal 10.1. Dries today at his keynote was talking about new features in Drupal 10.1. Lazy loading for responsive images is one of them. He didn't mention it. But patches are available. If you want that functionality now, there are patches available for Drupal 10.0 and Drupal 9. There are several contributed modules that provided additional lazy loading support. Two of them are blazy and lazy load and they use JavaScript libraries. So if you have more complicated needs than native browser support provides, have a look at those modules. I strongly recommend rendering responsive images if you can and that means delivering different files depending on browser conditions such as viewport width or the resolution of the device. Drupal core includes the responsive image module which allows creation of responsive image styles. So when creating a responsive image style you select the responsive method you wanna use and then you select specific image styles and you associate them with viewport widths or device resolutions. And this is where if you generated image styles in bulk using the image style generate module, you'll be really glad you did because now you'll have a nice selection of image styles to choose from for your responsive image style. And then when you wanna use that responsive image style within the field formatter for the image field, you'll select responsive image and then choose the desired responsive image style. The last category of considerations is user experience which means thinking about making the best possible experience for users who will be uploading and managing images on the site. It can be very helpful to implement methods to make it easier for people to find images especially as the number of images in your media library grows. So you could add a tax, sorry, a tag taxonomy that's only used for media and that will allow users to enter keywords that they can later use to find an image. By default, the widget used to select an entity in an entity reference field is autocomplete which is not that useful for media because the user has to try to find a media entity by its title. You see that on the left and there's no thumbnail of the image. So the media library module provided by Drupal core offers a media library widget which allows filtering by title or any other field on the media type such as a media tag like I mentioned on the previous slide and that you see here on the right. And it displays thumbnails of the images. Just overall it provides a much better user experience. The title of a media entity is by default set to be the name of the file which again is not that useful but similar to how you could rename the image file to be the alt text, you could force the title of the media entity to be the alt text. So that way the user only has to enter a description of the image in one place and it'll be used for the alt text, the file name and the media title. Site users who are tasked with maintaining images often have the need to replace an image. And when I say replace, I mean upload a new version of an image and have it replace the existing one and Drupal doesn't support replacing images out of the box. If you upload a new image and a file with that same name already exists a new image will be renamed with an underscore and a number. So there are contributed modules that offer the ability to replace images and they take different approaches that one of them is the media entity file replace module and it operates on media entities. The file replace module operates on the file entity level but and both contributed modules work to replace that can replace any kind of file, not just images. Along with replacing images, sometimes site editors want to be able to delete an image and that's not supported out of the box by Drupal either but there are several contributed modules that do. Media file delete operates on the media entity so you can have a file deleted when it's associated media is deleted and then the other two file delete and fancy file delete operate on the file entities. Of course be very careful which users you give this permission to. A common request from users is to be able to upload more than one image at a time so there are a handful of solutions. The Dropsalone.js JavaScript library is probably the most popular choice for bulk uploading and there are a handful of contributed modules that integrate with it. It's a good idea to allow users to embed media when editing content in a text editor. That top toolbar has a button that allows inserting an image. That's the one that is provided if you're in Drupal by default so you could either enter a URL or you can allow uploads but the original image will be rendered rather than a derivative. Enabling the media library module makes the option, the second option you see there insert media available. And insert media, inserting media instead of an image allows more control over the output. You're actually outputting a media entity in a particular view mode so you can include the fields that are on the media entity. You can use responsive images and any images that are uploaded this way are also go into the media library and can be reused across the site. The insert media functionality offers embedding any media type, not just images. And you could support both but I think that would just confuse users so probably just sticking with media library or sorry, insert media is the best way to go. So these again are the categories of considerations to take into account when developing an image plan. And I went through a lot and I think they're all important but here are my top 10 recommendations. Take advantage of the media handling capabilities provided by Drupal Core. Use the image magic tool kit. Limit the proportions of images on the site to a small number of aspect ratios, ideally four or five at the most. Consider using the image style generate module to automate the process of creating image styles. Make use of a high compression image format such as WebP. Optimize your images to reduce the size of files. Allow images to be replaced instead of being renamed and allow users to embed media in a text editor. Finally, take advantage of Drupal's responsive image functionality and allow lazy loading of images. Thinking about all the considerations I've proposed and following these recommendations will help to create a comprehensive and coherent image plan that will help you to standardize and simplify how images are displayed and managed on your Drupal website. If you wanna contact me with any questions or thoughts about the topic of creating an image plan, the best way to do it is send a message through my contact form on Drupal.org or if you see me around the conference. I'll also be in the contribution room quite a bit until Thursday. So I mentioned a lot of contributed modules and I started making a list of all of them just because I wanted to provide links in one place. So I will update this to actually have the links to all of these modules. But this seems like it would be helpful. We have time for questions. Yes. The question is, is there a method for pulling metadata into the media library search? You can, I think you'd probably have to write a custom module to do it. I've done that to get certain metadata out of an image, but you could do that and add it to a field that is attached to the media entity and then that should be available in the media library. Yeah. Yes. Yeah, hard direction. So yeah, that's one way of doing responsive images. It's very pr- That's the whole problem. It's not. I see. So it's not even using responsive images, but they want different images to be served. Yes, so we'll use them. I can't say I've ever heard of such a request, but it does sound like something some people from marketing would ask for it. What's that? Yeah, using the picture element in art direction and having different images, and that's really the best way to probably do it. Art direction? No, art direction is just an approach to responsive images. Yes. The question, if I understand it was, is there a good way to find images that are much larger than they need to be for, given how they're being rendered on a page? Is that right? There's probably, I don't know of anything in particular, but I assume that you could use a JavaScript library tool that would do something like that. I'm not familiar with one, though. So the question is, was about preventing uploading duplicate images. And if you're using media entities, you can take advantage of that module I mentioned, file hash to prevent uploading a duplicate. That's the only way I know of. I see there are similar images, but they're not exactly the same. Right, so this doesn't go by file name. It goes by the contents of the file itself, so that should get the same hash and therefore you could prevent it. Sure, exactly. Yes. The question was about if you have a service like CloudPlayer or something that's doing, yeah, that's generating your WebP versions for you. Do you need to still do it in Drupal? And I think the answer is no. I was on a project recently where we were using WebP and then we started using CloudPlayer and we just turned it off in Drupal and we're letting CloudPlayer handle it. Any final questions? Well, thank you very much, everybody.