Index
Edit

Presenting images

The Sanity Image Pipeline

When you use Sanity you have a globally distributed asset CDN at your fingertips. At any time you can request your image in a new size, with a new crop or whatever you need and the asset is created for you and automatically cached close to your users. One thing to keep in the back of your mind as you implement your front-end is that to achieve maximum performance, you should take care to reuse crops and sizes across your front-end to make sure your cached assets are re-used.

How images are represented

Before we go into the practical details, let's recap how images are handled in Sanity: The image type represents an image used as a field in a document, or embedded in a block text. It may contains any additional fields, like caption, crediting etc, and may contain the specific crop and hotspot for this image. The image references an asset which represents the actual image data to be displayed for this image. (One asset may actually be shared by several images allowing editors to reuse an asset with different crops, captions etc.)

The basic way to show images

The absolutely most basic way to present images from Sanity is to get the base url of the image from the asset. Let's say we have a document type person that has a field image, we can get the base url with this simple query:

*[_type == 'person']{
  name,
"imageUrl": image.asset->url
}

Here we follow the reference asset from the image and extract only the url.

{
  name: "Sean Gunn",
imageUrl: "https://cdn.sanity.io/images/zp7mbokg/production/G3i4emG6B8JnTmGoN0UjgAp8-300x450.jpg"
}

We can now append url-options to this base-url in order to constrain size, crop the image, blur it or perform other operations on it. Some examples:

// The base image
https://cdn.sanity.io/images/zp7mbokg/production/G3i4emG6B8JnTmGoN0UjgAp8-300x450.jpg

// Resized to have the height 200
https://cdn.sanity.io/images/zp7mbokg/production/G3i4emG6B8JnTmGoN0UjgAp8-300x450.jpg?h=200

// Extract a rectangle from the image (x, y, width, height)
https://cdn.sanity.io/images/zp7mbokg/production/G3i4emG6B8JnTmGoN0UjgAp8-300x450.jpg?rect=70,20,120,150

// Extract a rectangle from the image (x, y, width, height) and constrain height to 64
https://cdn.sanity.io/images/zp7mbokg/production/G3i4emG6B8JnTmGoN0UjgAp8-300x450.jpg?rect=70,20,120,150&h=64

// Blur the image
https://cdn.sanity.io/images/zp7mbokg/production/G3i4emG6B8JnTmGoN0UjgAp8-300x450.jpg?blur=50

See the image url reference documentation for the full list of parameters.

The crop and hot-spot

Some images may have a crop and a hot-spot. This may be enabled in the schema. If there is a crop/hotspot, that means the editor has used an interface like this:

The crop describes which part of the image the editor wants to allow to be used, while the hot-spot specifies what she wants preserved when the image needs to be cropped additionally in a front-end.

An image record with a crop and hot-spot might look like this from the api:

{
  _type: "image",
  asset: {
    _ref: "image-G3i4emG6B8JnTmGoN0UjgAp8-300x450-jpg",
    _type: "reference"
  },
  // The crop is specified in fractions of the image dimensions
  // and measured from the edge of the image. This image is cropped
  // from the bottom at 44% of the image height. The other dimensions
  // are left un-touched.
  crop: {
    bottom: 0.44,
    left: 0,
    right: 0,
    top: 0
  },
  // The hot-spot position x, y is in fractions of the image dimensions.
  // This hot-spot is centered at 43% of the image width from the left,
  // 26% of the image height from the top. The width and height is 
  // in the same unit system. This hot spot is 44% of the image width wide,
  // 65% of the image height tall, this rectangle is centered on the x,y
  // coordinate given.
  hotspot: {
    height: 0.44,
    width: 0.65,
    x: 0.43,
    y: 0.26
  }
}

It is the responsibility of the front-end to respect the crop/hot-spot according to the wishes of the editor, but conveniently we provide a JavaScript library that takes care of this for you.

Let the url-builder do it all

For JavaScript projects, we provide the @sanity/image-url npm package that will generate image-urls for you given an image record like the one above. You may specify additional constraints like width and height and trust that the crop/hot-spot is respected where applicable.

Let's see how this package might be used with React to render images. (There is nothing React-specific about it, you can use it with any framework you desire)

You install it to your project in the usual manner:

npm install --save @sanity/image-url

Then you need to configure it with your projectId and dataset. The simples way to do this, is to initialize it with your configured Sanity client like this:

import React from 'react'
import myConfiguredSanityClient from './sanityClient'
import imageUrlBuilder from '@sanity/image-url'

// Get a pre-configured url-builder from your sanity client
const builder = imageUrlBuilder(myConfiguredSanityClient)

// Then we like to make a simple function like this that gives the
// builder an image and returns the builder for you to specify additional
// parameters:
function urlFor(source) {
  return builder.image(source)
}

Now you can use this handy builder-syntax to create your urls:

<img src={urlFor(person.image).width(200).url()} />

You can add more options like this:

<img src={urlFor(person.image).width(200).invert().flipHorizontal().url()} />

See the full list of builder options in the reference documentation.

Previous: What about GraphQL?Next: Presenting Block Text