@plaiceholder/css v1.0.0
Sponsors 🖤
Become a project sponsor to access premium features, including:
- Studio
Upload your images and transform to beautifully lightweight placeholders (like magic, but real) ✨ - API
(TBC, depending on sponsor interest)
Individuals
Support Plaiceholder and get access to premium features via plaiceholder.co. Your support will be greatly appreciated!
Organizations
Support Plaiceholder via your organization. Your logo will show up here and on plaiceholder.co with a link to your website.
Table of Contents
Examples
Jump to the examples
directory to see working demos for Next.js, 11ty and more...
Introduction
"Plaiceholder" is a collection of Node.js helpers for creating low quality image placeholders, with 4 approaches to choose from:
Disclaimer: It's worth taking pros/cons of each approach with a grain of salt. Although initial tests locally and on WebPageTest have proved successful, extra research needs to be completed to determine the fastest solution.
Setup
CSS
Converts a specified image Buffer
into a low-res placeholder, outputted as a set of linear-gradient
s (in the form of a JavaScript style object).
Pros: Fast DOMContentLoaded
and LCP
Cons: ? (Still figuring out)
For a "blurred" effect, extend the returned styles with filter: blur(<value>)
and transform: scale(<value>)
.
Installation
npm i @plaiceholder/css
Example
import fs from "fs";
import path from "path";
import { promisify } from "util";
import { getPixelsCSS } from "@plaiceholder/css";
const image = await promisify(fs.readFile)(
path.join("path", "to", "your", "image.jpg")
);
const css = await getPixelsCSS(image);
console.log(css);
// Outputs
// {
// backgroundImage: "…"
// backgroundPosition: "…"
// backgroundSize: "…"
// backgroundRepeat: "…"
// }
SVG
Converts a specified image Buffer
into a low-res placeholder, outputted as an SVG.
Pros: Fast DOMContentLoaded
and LCP
Cons: ? (Still figuring out)
For a "blurred" effect, extend the returned SVG's styles with filter: blur(<value>)
and transform: scale(<value>)
.
Although it returns the SVG in the format of
React.createElement()
arguments, you are not constrained to using React.js.e.g. See the 11ty example.
Installation
npm i @plaiceholder/svg
Example
import fs from "fs";
import path from "path";
import { promisify } from "util";
import { getPixelsSVG } from "@plaiceholder/svg";
const image = await promisify(fs.readFile)(
path.join("path", "to", "your", "image.jpg")
);
const svg = await getPixelsSVG(image);
console.log(svg);
// Outputs
// [
// "svg",
// { ...props }
// [
// [
// "rect",
// { ...childProps }
// ],
// ...etc
// ]
// ]
Base64
Converts a specified image Buffer
into a low-res image, encoded as Base64 string.
Pros: Fast DOMContentLoaded
and LCP
Cons: ? (Still figuring out)
For a "blurred" effect, add filter: blur(<value>)
and transform: scale(<value>)
styles to the image.
Installation
npm i @plaiceholder/base64
Example
import fs from "fs";
import path from "path";
import { promisify } from "util";
import { getBase64 } from "@plaiceholder/base64";
const image = await promisify(fs.readFile)(
path.join("path", "to", "your", "image.jpg")
);
const base64 = await getBase64(image);
console.log(base64);
// Outputs
// data:image/jpeg;base64,/9j/2wBDAAYEBQY…
Blurhash
Converts a specified image Buffer
into a low-res image, encoded as Blurhash string accompanied by its width and height
Pros: Lightweight, fast DOMContentLoaded
and LCP
Cons: As it uses canvas
, it's not ideal to use Blurhash for above-the-fold content.
This can be passed into a library such as react-blurhash.
Installation
npm i @plaiceholder/blurhash
Example
import fs from "fs";
import path from "path";
import { promisify } from "util";
import { getBlurhash } from "@plaiceholder/blurhash";
const image = await promisify(fs.readFile)(
path.join("path", "to", "your", "image.jpg")
);
const blurhash = await getBlurhash(image);
console.log(blurhash);
// Outputs
// {
// hash: "U.QSL{%1bdxtR...",
// height: 32,
// width: 32
// }
Plugins
Next.js
A tiny helper function to access public
files in server-side functions or getStaticProps()
Installation
npm i @plaiceholder/next
Example
In this example, we're going to use the @plaiceholder/base64
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.
Add your chosen image to the
public
directory.In this case, our image is
public/keila-joa.jpg
In it's current state,
@plaiceholder/next
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 { getImage } from "@plaiceholder/next"; import { getBase64 } from "@plaiceholder/base64"; export const getStaticProps: GetStaticProps = async () => { const imgSrc = "/keila-joa.jpg"; const img = await getImage(imgSrc); const imgBase64 = await getBase64(img); 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
Why have you misspelled "placeholder"?
A Plaice is a flat fish that lays stationary on the sea-bed, much like an image placehol… actually this is bullshit, all the other good names were taken.
What about remote images in Next.js?
In it's current state, @plaiceholder/next
only supports local images (added to public
). PRs to add support for remote images are welcomed ❤️.
3 years ago
3 years ago
3 years ago
3 years ago
4 years ago