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-blurhash
Add your chosen image to the
public
directory.In this case, our image is
public/keila-joa.jpg
(to match the demo)In it's current state,
next-blurhash
only 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 thepublic
prefix.This will return the BlurHash string as a static prop (which will be decoded to dimensions of 32×32).
Import
BlurhashCanvas
fromreact-blurhash
and supply it with your newly generated static BlurHash string.Add custom styles to place the
BlurhashCanvas
underneath Next.js'Image
whilst 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-placeholder
Add your chosen image to the
public
directory.In this case, our image is
public/keila-joa.jpg
(to match the demo)In it's current state,
next-placeholder
only 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 thepublic
prefix. This will return the Base64 string as a static prop.Add custom styles to position (and blur) the placeholder
img
underneath Next.js'Image
whilst it loads.
An
aria-hidden
ensures 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