Build a high-performance Remix image component with Unpic and Netlify Image CDN

by Matt Kane

Unlike many other frameworks, Remix doesn’t have a built-in image component. This is in keeping with its philosophy of using the web platform, but it does make it quite a bit more work to serve responsive images. In this guide, we’ll show you how to build a Remix image component that uses Unpic and Netlify Image CDN to automatically serve responsive, high-performance images.

#TL;DR

Using Unpic and Netlify Image CDN, you can create a high-performance image component for Remix that automatically serves responsive images.

#Why serve optimized images?

Serving optimized images is crucial for web performance. Images are usually the largest assets on a web page, and serving them in the right format and size can make a big difference in how fast your site loads. By serving responsive images, you can ensure that your images look great on all devices without slowing down your site. Doing this by hand is a pain, but there are tools that make this as easy as using an <img> tag.

#How to generate responsive images on Remix

Netlify Image CDN is enabled automatically for all sites on Netlify, making it super-easy to deliver images in the right size and format. To create our responsive image component we’ll be using Unpic, a toolkit that I created to deliver high-performance images on most frontend frameworks. It automatically supports Netlify out of the box, and we’ll be using the React component in this guide.

First, install Unpic with the package mananger of choice.

Terminal window
npm install @unpic/react

Then, use it in your page:

import { Image } from "@unpic/react";
// This is a local image import
import viaduct from "../viaduct.jpg";
export default function Page() {
return (
<div>
<Image src={viaduct} alt="A viaduct" width={800} height={600} cdn="netlify" />
</div>
);
}

That’s all you need to do! We can make it even easier though, by creating a custom Remix component that wraps the Unpic component. This way, you can use the same component throughout your app without having to repeat the cdn="netlify" prop.

// src/components/RemixImage.tsx
import { Image, type ImageProps } from "@unpic/react";
export default function RemixImage(props: ImageProps) {
return <Image {...props} cdn="netlify" />;
}

If the source image is already hosted on a CDN then it will use that one, but it will use the Netlify Image CDN for local images and images that are not hosted on an image CDN.

#How it works

In this example, we’re importing a local image using asset imports. This copies the source image into the output directory with a fingerprinted filename, then returns the URL. We can use this directly in Unpic, and it will generate the correct image URLs for the Netlify Image CDN.

This is the generated tag. You will see it has everything to create a responsive image. It resizes fluidly, loads the right resolutions depending on the screen size. You’ll also find it gives great scores on Lighthouse and other performance tools.

<img
alt="Viaduct"
loading="lazy"
decoding="async"
sizes="(min-width: 800px) 800px, 100vw"
style="object-fit:cover;max-width:800px;max-height:600px;aspect-ratio:1.333;width:100%"
srcset="
/.netlify/images?w=640&amp;h=480&amp;fit=cover&amp;url=%2Fbuild%2F_assets%2Fviaduct-N2EIOTOR.jpg 640w,
/.netlify/images?w=750&amp;h=563&amp;fit=cover&amp;url=%2Fbuild%2F_assets%2Fviaduct-N2EIOTOR.jpg 750w,
/.netlify/images?w=800&amp;h=600&amp;fit=cover&amp;url=%2Fbuild%2F_assets%2Fviaduct-N2EIOTOR.jpg 800w,
/.netlify/images?w=828&amp;h=621&amp;fit=cover&amp;url=%2Fbuild%2F_assets%2Fviaduct-N2EIOTOR.jpg 828w,
/.netlify/images?w=960&amp;h=720&amp;fit=cover&amp;url=%2Fbuild%2F_assets%2Fviaduct-N2EIOTOR.jpg 960w,
/.netlify/images?w=1080&amp;h=810&amp;fit=cover&amp;url=%2Fbuild%2F_assets%2Fviaduct-N2EIOTOR.jpg 1080w,
/.netlify/images?w=1280&amp;h=960&amp;fit=cover&amp;url=%2Fbuild%2F_assets%2Fviaduct-N2EIOTOR.jpg 1280w,
/.netlify/images?w=1600&amp;h=1200&amp;fit=cover&amp;url=%2Fbuild%2F_assets%2Fviaduct-N2EIOTOR.jpg 1600w
"
src="/.netlify/images?w=800&amp;h=600&amp;fit=cover&amp;url=%2Fbuild%2F_assets%2Fviaduct-N2EIOTOR.jpg"
/>

If you are using images that are hosted on another domain that isn’t an image CDN, you will need to enable that source in your Netlify config:

[images]
remote_images = ["https://my-images.com/.*", "https://animals.more-images.com/[bcr]at/.*"]

The remote_images property accepts an array of regex patterns, letting you specify exactly which images you want to optimize.

Tip

You don’t need to add your own site domain to the remote_images list. Netlify Image CDN will automatically optimize images from your site.

#Get started

If you want to create a Remix site deploy to Netlify, you can get started with this command:

npx create-remix@latest --template netlify/remix-template

For more details and to see how to migrate an existing site, see the Remix on Netlify docs.