1.0.0 • Published 10 months ago
@sanity-image/url-builder v1.0.0
@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-builderUse 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
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | The Sanity Image ID (_id or _ref field value), e.g. image-abcde12345-1200x800-jpg |
baseUrl | string | Yes | The base URL for the Sanity image CDN, e.g. https://cdn.sanity.io/images/project/dataset/ |
width | number | No | Target width in pixels. Used to determine dimensions of generated assets, not for layout. When provided, generates a reasonable srcSet based on this width. |
height | number | No | Target height in pixels. Used to determine dimensions of generated assets, not for layout. When provided with width, establishes target aspect ratio. |
mode | "cover" | "contain" | No | Defaults 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 } | No | Coordinates for focal point when cropping. Values should be between 0-1 representing percentage across image. |
crop | { top: number, bottom: number, left: number, right: number } | No | Crop coordinates. Values should be between 0-1 representing percentage to crop from each edge. |
queryParams | object | No | Additional 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