Blitz has a built-in Image Component and Automatic Image Optimization.
The Blitz Image Component, Image, is an extension of the HTML <img>
element, evolved for the modern web.
The Automatic Image Optimization allows for resizing, optimizing, and serving images in modern formats like WebP when the browser supports it. This avoids shipping large images to devices with a smaller viewport. It also allows Blitz to automatically adopt future image formats and serve them to browsers that support those formats.
Automatic Image Optimization works with any image source. Even if the image is hosted by an external data source, like a CMS, it can still be optimized.
Instead of optimizing images at build time, Blitz optimizes images on-demand, as users request them. Unlike static site generators and static-only solutions, your build times aren't increased, whether shipping 10 images or 10 million images.
Images are lazy loaded by default. That means your page speed isn't penalized for images outside the viewport. Images load as they are scrolled into viewport.
Images are always rendered in such a way as to avoid Cumulative Layout Shift, a Core Web Vital that Google is going to use in search ranking.
To add an image to your application, import the Image component:
import { Image } from "blitz"
import profilePic from "../me.png"
function Home() {
return (
<>
<h1>My Homepage</h1>
<Image src={profilePic} alt="Picture of the author" />
<p>Welcome to my homepage!</p>
</>
)
}
export default HomeIn addition to using properties available to the Image component, you
can optionally configure Image Optimization for more advanced use cases
via blitz.config.js.
To enable Image Optimization for images hosted on an external website, use
an absolute url for the Image src and specify which domains are
allowed to be optimized. This is needed to ensure that external urls can't
be abused.
module.exports = {
images: {
domains: ["example.com"],
},
}If you want to use a cloud provider to optimize images instead of using
the Blitz' built-in Image Optimization, you can configure the loader and
path prefix. This allows you to use relative urls for the Image src and
automatically generate the correct absolute url for your provider.
module.exports = {
images: {
loader: "imgix",
path: "https://example.com/myaccount/",
},
}The following Image Optimization cloud providers are supported:
loader: 'imgix'loader: 'cloudinary'loader: 'akamai'blitz dev, or a custom serverThe following describes the caching algorithm for the default loader. For all other loaders, please refer to your cloud provider's documentation.
Images are optimized dynamically upon request and stored in the
<distDir>/cache/images directory. The optimized image file will be
served for subsequent requests until the expiration is reached. When a
request is made that matches a cached but expired file, the cached file is
deleted before generating a new optimized image and caching the new file.
The expiration (or rather Max Age) is defined by the upstream server's
Cache-Control header.
If s-maxage is found in Cache-Control, it is used. If no s-maxage is
found, then max-age is used. If no max-age is found, then 60 seconds
is used.
You can configure deviceSizes and
imageSizes to reduce the total number of possible
generated images.
The following configuration is for advanced use cases and is usually not necessary. If you choose to configure the properties below, you will override any changes to the Blitz defaults in future updates.
In some cases, where you know the expected device widths from the users of
your website, you can specify a list of device width breakpoints using the
deviceSizes property. These widths are used when the Image component
uses layout="responsive" or layout="fill" so that the correct image is
served for the device visiting your website.
If no configuration is provided, the default below is used.
module.exports = {
images: {
deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
},
}You can specify a list of image widths using the imageSizes property.
These widths should be different (usually smaller) than the widths defined
in deviceSizes because the arrays will be concatenated. These widths are
used when the Image component uses layout="fixed" or
layout="intrinsic".
If no configuration is provided, the default below is used.
module.exports = {
images: {
imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
},
}Image Optimization can be enabled via the Image component.
For an example, consider a project with the following files:
pages/index.jspublic/me.pngWe can serve an optimized image like so:
import { Image } from "blitz"
function Home() {
return (
<>
<h1>My Homepage</h1>
<Image
src="/me.png"
alt="Picture of the author"
width={500}
height={500}
/>
<p>Welcome to my homepage!</p>
</>
)
}
export default HomeThe Image component requires the following properties.
Required and must be one of the following:
When using an external URL, you must add it to domains in
blitz.config.js.
The width of the image, in pixels. Must be an integer without a unit.
Required, except for statically imported images, or those with
layout="fill".
The height of the image, in pixels. Must be an integer without a unit.
Required, except for statically imported images, or those with
layout="fill".
The <Image /> component optionally accepts the following properties.
The layout behavior of the image as the viewport changes size. Defaults to
intrinsic.
When fixed, the image dimensions will not change as the viewport changes
(no responsiveness) similar to the native img element.
When intrinsic, the image will scale the dimensions down for smaller
viewports but maintain the original dimensions for larger viewports.
When responsive, the image will scale the dimensions down for smaller
viewports and scale up for larger viewports.
When fill, the image will stretch both width and height to the
dimensions of the parent element, usually paired with
object-fit.
Try it out:
fixed layoutintrinsic layoutresponsive layoutfill layoutA custom function used to resolve URLs. Defaults to
images object in blitz.config.js.
loader is a function returning a string, given the following parameters:
srcwidthqualityimport { Image } from "blitz"
const myLoader = ({ src, width, quality }) => {
return `https://example.com/${src}?w=${width}&q=${quality || 75}`
}
const MyImage = (props) => {
return (
<Image
loader={myLoader}
src="me.png"
alt="Picture of the author"
width={500}
height={500}
/>
)
}A string mapping media queries to device sizes. Defaults to 100vw.
We recommend setting sizes when layout="responsive" and your image
will not be the same width as the viewport.
The quality of the optimized image, an integer between 1 and 100 where 100 is the best quality. Defaults to 75.
When true, the image will be considered high priority and
preload.
Should only be used when the image is visible above the fold. Defaults to false.
A placeholder to use while the image is loading, possible values are
blur or empty. Defaults to empty. When placeholder="blur", the
blurDataURL will be used as the placeholder. If the src is an object
from a static import, then blurDataURL will automatically be populated.
If the src is a string, then you must provide the
blurDataURL property.
In some cases, you may need more advanced usage. The Image component
optionally accepts the following advanced properties.
The image fit when using layout="fill".
The image position when using layout="fill".
This property is only meant for advanced usage. Switching an image to load
with eager will normally hurt performance.
We recommend using the priority property instead, which properly loads
the image eagerly for nearly all use cases.
The loading behavior of the image. Defaults to lazy.
When lazy, defer loading the image until it reaches a calculated
distance from the viewport.
When eager, load the image immediately.
A
Data URL
to be used as a placeholder image before the src image successfully
loads. Only takes effect when combined with
placeholder="blur".
Must be a base64-encoded image. It will be enlarged and blurred, so a very small image (10px or less) is recommended. Including larger images as placeholders may harm your application performance.
When true, the source image will be served as-is instead of changing
quality, size, or format. Defaults to false.
Other properties on the Image component will be passed to the underlying
img element with the exception of the following:
style. Use className instead.srcSet. Use Device Sizes instead.decoding. It is always "async".