1.0.0 • Published 10 months ago

@sanity-image/url-builder v1.0.0

Weekly downloads
-
License
MIT
Repository
github
Last release
10 months ago

@sanity-image/url-builder

A lightweight, zero-dependency URL builder for Sanity images. This package provides the core URL generation functionality used by sanity-image, but can be used independently for cases where you don't need the React component.

Features

  • Zero dependencies
  • Tiny bundle size
  • TypeScript support
  • Smart srcSet generation based on image size
  • Automatic quality and format optimization
  • Support for crops and hotspots
  • Never upscales images
  • Intelligent URL parameter optimization for better caching

Quick Start

Install it:

npm install @sanity-image/url-builder
# or
pnpm add @sanity-image/url-builder

Use it:

import { buildSrc, buildSrcSet } from "@sanity-image/url-builder"

// Get a single image URL with dimensions
const { src, width, height } = buildSrc({
  id: "image-79f37b3f070b144d45455d514ff4e9fc43035649-1000x1000-png",
  width: 500,
  baseUrl: `https://cdn.sanity.io/images/<project-id>/<dataset>`,
})

// Get a responsive srcSet
const srcSet = buildSrcSet({
  id: "image-79f37b3f070b144d45455d514ff4e9fc43035649-1000x1000-png",
  width: 500,
  baseUrl: `https://cdn.sanity.io/images/<project-id>/<dataset>`,
})

API

buildSrc(options)

Returns metadata and a single image URL based on the provided options.

const { src, width, height } = buildSrc({
  id: "image-abc123-1000x1000-png",
  width: 500,
  baseUrl: "/images/",
  mode: "cover", // optional, defaults to "contain"
  height: 300, // optional
  hotspot: { x: 0.5, y: 0.5 }, // optional
  crop: { top: 0, bottom: 0, left: 0, right: 0 }, // optional
  queryParams: { blur: 50, q: 90 }, // optional
})

buildSrcSet(options)

Generates an array of srcSet entries optimized for responsive images. The widths generated depend on the target size:

  • Tiny images (< 160px): 0.5x, 1x, 2x
  • Small images (< 750px): 0.5x, 1x, 1.5x, 2x
  • Medium images (< 1400px): 0.25x, 0.5x, 0.75x, 1x, 1.5x, 2x
  • Large images: 0.25x, 0.5x, 0.75x, 1x, 1.25x, 1.5x, 1.75x, 2x
const srcSet = buildSrcSet({
  id: "image-abc123-1000x1000-png",
  width: 500,
  baseUrl: "/images/",
  // ... same options as buildSrc
})

Default Behavior

  • Images are never upscaled beyond their original dimensions
  • Quality defaults to 75
  • Auto format conversion is enabled by default (e.g., WebP when supported)
  • When using mode="cover" without a hotspot, entropy-based cropping is used
  • URL parameters are sorted alphabetically for better caching
  • Tiny variants (< 50px) are skipped in srcSets to reduce HTML size

Parameters

ParameterTypeRequiredDescription
idstringYesThe Sanity Image ID (_id or _ref field value), e.g. image-abcde12345-1200x800-jpg
baseUrlstringYesThe base URL for the Sanity image CDN, e.g. https://cdn.sanity.io/images/project/dataset/
widthnumberNoTarget width in pixels. Used to determine dimensions of generated assets, not for layout. When provided, generates a reasonable srcSet based on this width.
heightnumberNoTarget height in pixels. Used to determine dimensions of generated assets, not for layout. When provided with width, establishes target aspect ratio.
mode"cover" | "contain"NoDefaults to "contain". cover: Crops image to match requested aspect ratio (based on width/height). contain: Fits image within boundaries without altering aspect ratio.
hotspot{ x: number, y: number }NoCoordinates for focal point when cropping. Values should be between 0-1 representing percentage across image.
crop{ top: number, bottom: number, left: number, right: number }NoCrop coordinates. Values should be between 0-1 representing percentage to crop from each edge.
queryParamsobjectNoAdditional Sanity Image API parameters like: q (Quality, defaults to 75), blur (Blur amount), sharpen (Sharpening amount), and other Sanity Image API options

Examples

Basic Image URL

const { src } = buildSrc({
  id: "image-abc123-1000x1000-png",
  width: 500,
  baseUrl: "/images/",
})
// => "/images/abc123-1000x1000.png?auto=format&fit=max&q=75&w=500"

Cropped Image with Hotspot

const { src } = buildSrc({
  id: "image-abc123-1000x1000-png",
  width: 500,
  height: 300,
  mode: "cover",
  hotspot: { x: 0.25, y: 0.25 },
  crop: { top: 0, bottom: 0.25, left: 0, right: 0.25 },
  baseUrl: "/images/",
})
// => "/images/abc123-1000x1000.png?auto=format&fit=crop&fp-x=0.333&fp-y=0.333&h=300&q=75&rect=0,0,750,750&w=500"

Responsive srcSet

const srcSet = buildSrcSet({
  id: "image-abc123-1000x1000-png",
  width: 500,
  baseUrl: "/images/",
})
// => [
//   "/images/abc123-1000x1000.png?auto=format&fit=max&q=75&w=250 250w",
//   "/images/abc123-1000x1000.png?auto=format&fit=max&q=75&w=500 500w",
//   "/images/abc123-1000x1000.png?auto=format&fit=max&q=75&w=750 750w",
//   "/images/abc123-1000x1000.png?auto=format&fit=max&q=75&w=1000 1000w"
// ]

License

Copyright ©2025 Corey Ward. Available under the MIT License.

1.0.0

10 months ago

1.0.0-alpha.0

10 months ago