next-blurhash v0.2.0
Choose-your-own approach:
Base64 or BlurHash
Table of Contents
Setup
Choose your own adventure: BlurHash or Base64…
BlurHash
In this example, we're going to use the additional next-blurhash package to create a BlurHash string for a single image inside a Next.js Page.
We'll then use react-blurhash to render the string to a canvas, to sit underneath our Image whilst it's loading.
See the demo for a live example.
Add the package to your existing Next.js project:
npm i next-blurhash react-blurhashAdd your chosen image to the
publicdirectory.In this case, our image is
public/keila-joa.jpg(to match the demo)In it's current state,
next-blurhashonly supports local images.Create a new page (or add to an existing page), and add the following:
Call
getBlurhash()insidegetStaticProps()with your image's path without thepublicprefix.This will return the BlurHash string as a static prop (which will be decoded to dimensions of 32×32).
Import
BlurhashCanvasfromreact-blurhashand supply it with your newly generated static BlurHash string.Add custom styles to place the
BlurhashCanvasunderneath Next.js'Imagewhilst it loads.
// pages/index.jsx import * as React from "react"; import Image from "next/image"; import { getBlurhash } from "next-blurhash"; import { BlurhashCanvas } from "react-blurhash"; export const getStaticProps: GetStaticProps = async () => { const imgSrc = "/keila-joa.jpg"; const imgHash = await getBlurhash(imgSrc); return { props: { imgHash, imgSrc, }, }; }; function Index({ imgHash, imgSrc }) { return ( <main> <div style={{ position: "relative" }}> {/* Canvas sits underneath the `Image` and fills available space */} <BlurhashCanvas // Your generated Blurhash string hash={imgHash} // getBlurhash **always** returns 32×32 dimensions width={32} height={32} punch={1} style={{ position: "absolute", top: 0, left: 0, right: 0, bottom: 0, width: "100%", height: "100%", }} /> {/* Your image, optimized by next/image */} <Image src={imgSrc} width={4032} height={3024} /> </div> </main> ); } export default Index;Run your Next.js app to see the results in action!
You should expect to see the BlurHash canvas first, then the image optimized by Next.js
Base64
In this example, we're going to use the base next-placeholder package to create a Base64 string for a single image inside a Next.js Page.
We'll then apply the string to an <img> element (hidden from screen-readers) and position underneath our Image whilst it's loading.
See the demo for a live example.
Add the package to your existing Next.js project:
npm i next-placeholderAdd your chosen image to the
publicdirectory.In this case, our image is
public/keila-joa.jpg(to match the demo)In it's current state,
next-placeholderonly supports local images.Create a new page (or add to an existing page), and add the following:
Call
getBase64()insidegetStaticProps()with your image's path without thepublicprefix. This will return the Base64 string as a static prop.Add custom styles to position (and blur) the placeholder
imgunderneath Next.js'Imagewhilst it loads.
An
aria-hiddenensures the content is hidden from screen-readers.// pages/index.jsx import * as React from "react"; import Image from "next/image"; import { getBase64 } from "next-placeholder"; export const getStaticProps: GetStaticProps = async () => { const imgSrc = "/keila-joa.jpg"; const imgBase64 = await getBase64(imgSrc); return { props: { imgBase64, imgSrc, }, }; }; function Index({ imgBase64, imgSrc }) { return ( <main> <div style={{ position: "relative", overflow: "hidden" }}> {/* Our placeholder image */} <img aria-hidden="true" alt="" src={imgBase64} style={{ position: "absolute", top: 0, left: 0, right: 0, bottom: 0, width: "100%", height: "100%", /* Adjust the content to fit */ objectFit: "cover", objectPosition: "center", /* Blur the image and scale to avoid transparent corners */ filter: "blur(2rem)", transform: "scale(1.2)", }} /> {/* Your image, optimized by next/image */} <Image src={imgSrc} width={4032} height={3024} /> </div> </main> ); } export default Index;Run your Next.js app to see the results in action!
You should expect to see the placeholder first, then the image optimized by Next.js
FAQs
What about remote images?
In it's current state, next-placeholder only supports local images (added to public). PRs to add support for remote images are welcomed ❤️.
Acknowledgements
- BlurHash by Wolt