Skip to content

Transforming Sanity Images

When working with Sanity.io images, you can leverage Sanity's built-in image transformation capabilities instead of using the sharp plugin. This is particularly useful for handling Sanity's hotspot and crop features.

Fetching Images with GROQ

First, ensure your GROQ query includes all necessary image fields:

typescript
import { defineConfig } from '@bluecadet/launchpad/cli';
import { content } from '@bluecadet/launchpad/content';
import { sanitySource } from '@bluecadet/launchpad/content/sources/sanity';

export default defineConfig({
  plugins: [
    content({
      sources: [
        sanitySource({
          id: 'content',
          projectId: 'your-project-id',
          queries: [{
            id: 'pages',
            query: `*[_type == "page"]{
              image {
                ...,
                asset->
              }
            }`
          }]
        })
      ],
      transforms: [
        mediaDownloader()
      ]
    })
  ]
});

The asset-> reference is crucial for accessing the full image data, including hotspot and crop information.

Using the Image URL Transform Plugin

Add the sanityImageUrlTransform plugin to transform image references into URLs:

typescript
import { defineConfig } from '@bluecadet/launchpad/cli';
import { content } from '@bluecadet/launchpad/content';
import { sanitySource } from '@bluecadet/launchpad/content/sources/sanity';
import { sanityImageUrlTransform } from '@bluecadet/launchpad/content/transforms/sanity-image-url-transform';
import { mediaDownloader } from '@bluecadet/launchpad/content/transforms/media-downloader';

export default defineConfig({
  plugins: [
    content({
      sources: [
        sanitySource({
          id: 'content',
          projectId: 'your-project-id',
          queries: [/* ... */]
        })
      ],
      transforms: [
        sanityImageUrlTransform({
          projectId: 'your-project-id',
          dataset: 'production',
          buildUrl: (builder) => builder
            .width(800)
            .format('webp')
            .fit('crop')
            .crop('center')
        }),
        mediaDownloader()
      ]
    }),
  ]
});

TIP

It's added before the mediaDownloader (unlike the sharp plugin) because it modifies the image URLs before they are downloaded. Conversely, the sharp plugin modifies the image files after they are downloaded.

Available Transformations

Sanity's image URL builder supports many transformations:

typescript
import { defineConfig } from '@bluecadet/launchpad/cli';
import { content } from '@bluecadet/launchpad/content';
import { sanitySource } from '@bluecadet/launchpad/content/sources/sanity';
import { sanityImageUrlTransform } from '@bluecadet/launchpad/content/transforms/sanity-image-url-transform';
import { mediaDownloader } from '@bluecadet/launchpad/content/transforms/media-downloader';

export default defineConfig({
  plugins: [
    content({
      sources: [
        sanitySource({
          id: 'content',
          projectId: 'your-project-id',
          queries: [/* ... */]
        })
      ],
      transforms: [
        sanityImageUrlTransform({
          projectId: 'your-project-id',
          dataset: 'production',
          buildUrl: (builder) => builder
            .width(800)                   // Set width
            .height(600)                  // Set height
            .format('webp')               // Convert format
            .quality(80)                  // Adjust quality
            .auto('format')               // Auto-select best format
            .fit('crop')                  // Crop fitting
            .crop('center')               // Crop position
            .blur(10)                     // Apply blur
        }),
        mediaDownloader()
      ]
    })
  ]
});

Resources

Unlike the sharp plugin, Sanity's image transformations are performed on their CDN, reducing your build time and server load.

Released under the ISC License.