Skip to content

New: Setting up FastStore images doc #44

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
149 changes: 149 additions & 0 deletions docs/how-to-guides/performance/setting-up-faststore-images.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
---
tags:
- performance
---

# Setting up FastStore images

In this guide, learn how to improve your store's image rendering performance by using a CDN to deliver optimized images in `WebP` and `AVIF` formats.
This improvement speeds up loading times without compromising image quality, resulting in a better customer experience while navigating your store.

According to the [Lighthouse official documentation](https://developer.chrome.com/docs/lighthouse/performance/uses-webp-images/), `WebP` and `AVIF` formats load faster and have better quality than other formats. Using a CDN to deliver images takes the load off the server, ensuring stability and efficient loading even during high-traffic periods, avoiding performance issues or downtime.

> ⚠️ Apply the steps in this guide to make changes to the `Next.js` starter and `Gatsby` starter.

## Before you start
FastStore projects can benefit from [Thumbor](http://thumbor.org/), an image CDN that optimizes images on demand and caches the result on CDN, resulting in improved storefront performance.

To use Thumbor, replace all instances of `assets.vtex.app` with `{accountName}.vtexassets.com` in your FastStore project.
For example, change `https://assets.vtex.app` to `https://examplestore.vtexassets.com`.

For more information, refer to [this release note](https://www.faststore.dev/releases/2023/03/10/faststore#what-needs-to-be-done)

## Step-by-step

### Step 1: Setting up the new images domain.
To enable the use of Thumbor in your store, you need to set up a new domain for your store's images in the `.faststore/next.config.js` file and point the Thumbor service to the new images domain in the `src/components/ui/Image/thumborUrlBuilder.ts` file.

1. In the store’s repository, access `.faststore/next.config.js` file and add the images’ domain.

```js
const storeConfig = require('./faststore.config')

const nextConfig = {
/* config options here */
images: {
domains: [`${storeConfig.api.storeId}.vtexassets.com`],
},

```
2. Access `src/components/ui/Image/thumborUrlBuilder.ts` and point the Thumbor service to the new images domain.

```js
import storeConfig from '../../../../faststore.config'

[...]

const THUMBOR_SERVER = `https://${storeConfig.api.storeId}.vtexassets.com`

[...]
```

### Step 2: Use FastStore Image component

We highly recommend optimizing your store's images using the FastStore Image component, which now leverages the Next.js [`next/future/image`](https://nextjs.org/docs/api-reference/next/image) component.

The `useImage()` hook is used to generate image URLs with Thumbor and handle all necessary settings to optimize and serve images from the CDN.

To ensure that the Next.js component uses Thumbor as the image loader, follow these steps:

1. Navigate to `/src/components/ui/Image/Image.tsx`.

2. Pass the `unoptimized` property to the `NextImage` component.

3. Set the value of `src` to `thumborSrc`, which is the URL generated by `useImage()` hook.

> ⚠️ If you are using Gatsby, you should use the `thumborSrc` provided by `useImage()` and disable the default loaders if applicable. Alternatively, consider using the `<img />` tag with the given `thumborSrc`.

Here's the implementation of the `Image` component:

```js
import { memo } from 'react'

import NextImage, { ImageProps } from 'next/future/image'
import { ThumborOptions } from './thumborUrlBuilder'
import { useImage } from './useImage'

function Image({ src, width, height, quality, ...otherProps }: ImageProps) {
const { src: thumborSrc, alt } = useImage({
src: String(src),
width: Number(width),
height: Number(height),
options: quality ? ({ filters: { quality } } as ThumborOptions) : undefined,
...otherProps,
})

return (
<NextImage
data-fs-image
unoptimized
src={thumborSrc}
width={width}
height={height}
alt={alt}
{...otherProps}
/>
)
}

Image.displayName = 'Image'
export default memo(Image)
```

> ℹ️ Using the `useImage()` hook, the component generates the `thumborSrc` URL and passes it to the `src` prop of the `NextImage` component. The `unoptimized` property is set to ensure that the `NextImage` component uses Thumbor as the image loader.


The `Image` component takes the following props:

| Prop | Description |
| ------ | --------------- |
| `src` | The image source URL. |
| `width` | The width of the image. |
| `height` | The height of the image. |
| `quality` | The quality of the image. |
| `otherProps` | Additional props to pass to the NextImage component. |

### Step 3: Install `sharp` for Image Conversion in Production Environment

To ensure that your store's images are converted to modern formats such as `WebP`and `AVIF` in both development and production environments, you need to install [`sharp`](https://www.npmjs.com/package/sharp), as [recommended by Next.js](https://nextjs.org/docs/messages/sharp-missing-in-production).

To install `sharp`, run the following command in the terminal:

```bash
yarn add sharp
```

This will add `sharp` as a dependency to your FastStore project and enable image conversion in production mode. Make sure to restart your development server after installing it.

With `sharp` installed, the `next/future/image` component will automatically convert images to `WebP` and `AVIF` formats in both development and production environments.

## Validating FastStore Images


To ensure that your images are being served correctly and optimized for performance, you can use the DevTools Network tab. This tool allows you to filter images, check their format, size, and loading time, and determine whether an image originates from the CDN cache.

![validating-faststore-image-one](https://vtexhelp.vtexassets.com/assets/docs/src/faststore-image-one___11277d64c4ea14f105fbc43498fdb8f7.png)

In this example, you can see:
- The recommended domain `<Account>.vtexassets.com` is being used.

- The images are in the `WebP` format, which offers better compression and faster loading times than `JPEG` or `PNG`. Despite being smaller in size, the images maintain their quality. Clicking on any of the images reveals more details.

![validating-faststore-image-two](https://vtexhelp.vtexassets.com/assets/docs/src/faststore-image-two___1b07a8a0b2cfc160790aef9ccf5f0f19.png)

Although the image has the Request URL informed as `JPG`, which is the format used when uploading it to the VTEX admin in the CMS or Catalog section, the image is being transformed into `WebP`. You can verify this transformation through the `content-type`.

It is possible to validate that a CDN cache HIT has occurred through the x-cache header, reducing the time it takes to load the content.


For more details on image conversion on the VTEX platform, see [this announcement](https://help.vtex.com/en/announcements/na-vtex-conversao-de-png-para-webp-agora-e-lossless--4J4ZtrCZIksY8qikWgeomY).