Blur como placeholder em imagens no NextJS 14
Este post é um passo a passo de como adicionar blur como placeholder enquanto a aplicação carrega imagens remotas utilizando NextJS 14 e a biblioteca plaiceholder.
Passo a passo
Caso você queira adicionar blur em uma imagem que esteja salva localmente no seu projeto, basta utilizar a propriedade blur conforme recomendado na documentação oficial do NextJS.
Porém, caso você queira adicionar blur em uma imagem que seja dinâmica, alguns passos extras precisam ser seguidos, que é o que veremos neste passo a passo.
Source code
O código fonte deste tutorial pode ser encontrado aqui.
Criar um novo projeto NextJS
Para criar um novo projeto em NextJS, basta rodar o seguinte comando no terminal:
npx create-next-app@latest <nome-do-projeto>
Instalar a biblioteca plaiceholder
Após finalizar a criação do projeto, é preciso acessar o diretório raíz do projeto e rodar o seguinte comando:
npm install plaiceholder
Habilitar imagens remotas nas configurações do NextJS
Para que o NextJS permita imagens remotas na aplicação, é preciso adicionar algumas configurações extras, dizendo ao NextJS qual o domínio que contém as imagens que serão utilizadas, o protocolo (HTTP ou HTTPS) e algumas outras configurações.
Portanto, abra o arquivo next.config.mjs localizado na raíz do projeto e altere seu conteúdo todo com as seguintes informações:
/** @type {import('next').NextConfig} */
const nextConfig = {
images: {
remotePatterns: [
{
protocol: "https",
// Estou utilizando imagens que estão armazenadas em um repositório do github,
// substitua o hostname abaixo de acordo com sua necessidade.
hostname: "raw.githubusercontent.com",
port: "",
},
],
},
};
export default nextConfig;
Plaiceholder
Agora a biblioteca que instalamos entra em ação, ela irá fornecer a imagem no formato base64-encoded, que é utilizada no campo blurDataURL do componente Image do NextJS.
Para imagens estáticas, a propriedade blurDataURL é "automaticamente preenchido" pelo próprio NextJS, mas para imagens dinâmicas é uma propriedade obrigatória.
Dito isso, é preciso criar uma função que irá retornar a imagem no formato base64-encoded. No exemplo criado para este passo a passo, a função foi criada em um arquivo chamado image.ts , que foi criado a parte dentro de um diretório que também foi criado manualmente, chamado lib. A função foi criada baseada na documentação da própria biblioteca plaiceholder, que pode ser acessada clicando aqui.
// lib/image.ts
import { getPlaiceholder } from "plaiceholder";
export async function getBase64(imageUrl: string) {
try {
const buffer = await fetch(imageUrl).then(async (res) =>
Buffer.from(await res.arrayBuffer())
);
const { base64 } = await getPlaiceholder(buffer);
return base64;
} catch (err) {
err;
}
}
Adicionando blurDataURL do componente Image
Agora que é possível obter a imagem no formato base64-encoded, basta atualizar o arquivo page.tsx da seguinte forma:
import { getBase64 } from "@/lib/image";
import Image from "next/image";
// É preciso que o componente Home seja assíncrono para utilizar o await
export default async function Home() {
// Chamar a função criada, passando como parâmetro a URL da imagem
const blur = await getBase64(
"https://raw.githubusercontent.com/gmcardoso-dev/blog-images/main/2024/05/hoisting.jpg"
);
return (
// As classes CSS do exemplo são do Tailwind, caso não esteja utilizando Tailwind no seu projeto, basta ignorá-las
<main className="flex min-h-screen flex-col items-center justify-start p-8">
<h1>Using blur while the image is not ready</h1>
<div className="flex place-items-center mt-16">
<Image
className="max-w-screen"
src="https://raw.githubusercontent.com/gmcardoso-dev/blog-images/main/2024/05/hoisting.jpg"
alt="A random image"
width={500}
height={500}
priority
// Adicionar as duas propriedades abaixo
placeholder="blur"
blurDataURL={blur}
/>
</div>
</main>
);
}
Rodando o projeto
Para visualizar o que foi feito, basta rodar o projeto utilizando o seguinte comando no terminal:
npm run dev
E abrir o navegador na URL que o comando acima retornar, normalmente a URL é: http://localhost:3000/.
Imagem sendo baixada:
Imagem baixada:
Dependendo da sua conexão de internet fica difícil de visualizar o blur, porque a imagem acaba sendo baixada muito rapidamente. Para isso, existe uma opção dentro do navegador Google Chrome (provavelmente existe isso nos outros também, só não saberei dar detalhes de como utilizar) que simula uma conexão de internet ruim.
Bônus: Network throttling no Google Chrome
Vá em View > Developer > Developer Tools. Isso irá exibir uma nova janela na aba do navegador. Clique na aba Network dentro desta nova janela e, no topo desta aba, troque o valor "No throttling" por "Fast 3G" ou "Slow 3G" e tente recarregar a página. Essa opção irá simular uma conexão de internet pior, demorando mais para baixar a imagem e, assim, mais fácil de visualizar o placeholder que foi adicionado enquanto a imagem é baixada.