Display Placeholder While Image is Loading
CldImage wraps the Unpic Image component, thus giving us access to the placeholder API which can display an SVG image while the image itself is loading.
This helps for providing a great user experience, rather than an empty space, to help let the visitor know that image is loading.
To do this, we have several options:
placeholder="blur"
coupled with ablurDataURL
placeholder="..."
with the contents being a data URL
Blurred Images
To achieve a blurred image effect, we can first convert our Cloudinary image to a Data URL then pass it in to our CldImage component.
Inside of the SvelteKit app, we can utilize server side code to generate a data URL from our image.
import { getCldImageUrl } from 'svelte-cloudinary';
export const load = () => {
const imageUrl = getCldImageUrl({
src: '<Your Public ID>',
width: 100, // Resize the original file to a smaller size
});
const response = await fetch(imageUrl);
const arrayBuffer = await response.arrayBuffer();
const buffer = Buffer.from(arrayBuffer);
const base64 = buffer.toString("base64");
const dataUrl = `data:${response.type};base64,${base64}`;
return {
dataUrl
}
}
Then when rendering CldImage, utilize the dataUrl
using placeholder
and blurDataURL
:
<script>
import { CldImage } from 'svelte-cloudinary';
export let data
</script>
<CldImage
src="<Your Public ID>"
width="600"
height="400"
alt="Decriptive text"
placeholder="blur"
blurDataURL={data.dataUrl}
/>
Shimmer
In a similar fashion, we can create a shimmer effect when our images are loading.
Inside of the SvelteKit app you can use a server side code +page.server.js
to generate a data URL from our image.
export const load = () => {
const shimmer = (w: number, h: number) => `
<svg width="${w}" height="${h}" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<linearGradient id="g">
<stop stop-color="#333" offset="20%" />
<stop stop-color="#222" offset="50%" />
<stop stop-color="#333" offset="70%" />
</linearGradient>
</defs>
<rect width="${w}" height="${h}" fill="#333" />
<rect id="r" width="${w}" height="${h}" fill="url(#g)" />
<animate xlink:href="#r" attributeName="x" from="-${w}" to="${w}" dur="1s" repeatCount="indefinite" />
</svg>`
const toBase64 = (str: string) =>
typeof window === 'undefined'
? Buffer.from(str).toString('base64')
: window.btoa(str)
const dataUrl = `data:image/svg+xml;base64,${toBase64(shimmer(600, 400))}`;
return {
dataUrl
}
}
Then when rendering CldImage, utilize the dataUrl
using placeholder
:
<script>
import { CldImage } from 'svelte-cloudinary';
export let data
</script>
<CldImage
src="<Your Public ID>"
width="600"
height="400"
alt="Decriptive text"
placeholder={data.dataUrl}
/>