Image Component and Image Optimization
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.
Image Component
To add an image to your application, import the
Image
component:
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 Home
Configuration
In addition to using properties available to the
Image
component, you can optionally configure Image Optimization for more advanced use cases via blitz.config.js
.
Domains
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"], },}
Loader
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:
- Vercel: Works automatically when you deploy on Vercel, no configuration necessary. Learn more
- Imgix:
loader: 'imgix'
- Cloudinary:
loader: 'cloudinary'
- Akamai:
loader: 'akamai'
- Default: Works automatically with
blitz start
, or a custom server
Caching
The 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.
Advanced
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.
Device Sizes
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], },}
Image Sizes
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 API
Image Optimization can be enabled via the
Image
component.
Usage
For an example, consider a project with the following files:
pages/index.js
public/me.png
We 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 Home
Required Props
The
Image
component requires the following properties.
src
The path or URL to the source image. This is required.
When using an external URL, you must add it to
domains in blitz.config.js
.
width
The width of the image, in pixels. Must be an integer without a unit.
Required unless
height
The height of the image, in pixels. Must be an integer without a unit.
Required unless
Optional Props
The
<Image />
component optionally accepts the following properties.
layout
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:
- Demo the
fixed
layout - Demo the
intrinsic
layout - Demo the
responsive
layout - Demo the
fill
layout - Demo background image
loader
A 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:
import {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} /> )}
sizes
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.
quality
The quality of the optimized image, an integer between 1 and 100 where 100 is the best quality. Defaults to 75.
priority
When true, the image will be considered high priority and
Should only be used when the image is visible above the fold. Defaults to false.
Advanced Props
In some cases, you may need more advanced usage. The
Image
component optionally accepts the following advanced properties.
objectFit
The image fit when using
layout="fill"
.
objectPosition
The image position when using
layout="fill"
.
loading
Attention: 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.
unoptimized
When true, the source image will be served as-is instead of changing quality, size, or format. Defaults to false.
Other Props
Other properties on the
Image
component will be passed to the underlying img
element with the exception of the following:
style
. UseclassName
instead.srcSet
. Use Device Sizes instead.decoding
. It is always"async"
.