Skip to main content
Utility functions for working with Sanity image IDs and asset references. These are re-exported from the main sanity-image package.

Import

import { parseImageId, assetId, normalizeAssetId } from 'sanity-image'

parseImageId

Parses a Sanity image ID string into its component parts: asset ID, dimensions, and format.

Signature

function parseImageId(id: string): ImageIdParts

Parameters

id
string
required
The image ID string in the format image-<hash>-<width>x<height>-<ext>.Example: "image-abc123def456-1920x1080-jpg"

Returns

ImageIdParts
object
Object containing the parsed components.
type ImageIdParts = {
  assetId: string
  dimensions: {
    height: number
    width: number
    aspectRatio: number
  }
  format: string
}

Example

const parts = parseImageId('image-abc123def456-1920x1080-jpg')

// Returns:
// {
//   assetId: 'abc123def456',
//   dimensions: {
//     width: 1920,
//     height: 1080,
//     aspectRatio: 1.7777777777777777
//   },
//   format: 'jpg'
// }

Error Handling

Throws an error if:
  • The ID doesn’t match the expected pattern
  • The dimensions are invalid or cannot be parsed
parseImageId('invalid-id')
// Error: Could not parse image ID "invalid-id"

parseImageId('image-abc123-NaNxNaN-jpg')
// Error: Invalid dimensions "NaNxNaN"

assetId

Extracts the asset ID from a Sanity image asset object, whether it has an _id or _ref field.

Signature

function assetId(asset: AssetLike): string

type AssetLike = { _id: string } | { _ref: string }

Parameters

asset
AssetLike
required
An asset object with either an _id or _ref field.
type AssetLike = { _id: string } | { _ref: string }

Returns

id
string
The asset ID value from either _id or _ref field.

Example

// With _id field
const id1 = assetId({ _id: 'image-abc123-1920x1080-jpg' })
// Returns: 'image-abc123-1920x1080-jpg'

// With _ref field
const id2 = assetId({ _ref: 'image-abc123-1920x1080-jpg' })
// Returns: 'image-abc123-1920x1080-jpg'

Use Cases

This is useful when working with Sanity data where asset references can be in either format:
// From a GROQ query with references
const image = {
  _ref: 'image-abc123-1920x1080-jpg',
  crop: { top: 0, bottom: 0, left: 0, right: 0 },
  hotspot: { x: 0.5, y: 0.5 }
}

const id = assetId(image)
// Use the ID with other functions
const parts = parseImageId(id)

normalizeAssetId

Normalizes an asset object to ensure it has an _id field. Converts _ref to _id if necessary.

Signature

function normalizeAssetId<T extends Record<string, unknown>>(
  asset: AssetLike & T
): Omit<T, '_ref'> & { _id: string }

Parameters

asset
AssetLike & T
required
An asset object with either _id or _ref, plus any additional properties.
type AssetLike = { _id: string } | { _ref: string }

Returns

normalized
Omit<T, '_ref'> & { _id: string }
The asset object with _ref removed (if present) and _id guaranteed to exist. All other properties are preserved.

Example

// With _ref field
const asset1 = {
  _ref: 'image-abc123-1920x1080-jpg',
  crop: { top: 0.1, bottom: 0.1, left: 0, right: 0 },
  hotspot: { x: 0.5, y: 0.3 }
}

const normalized1 = normalizeAssetId(asset1)
// Returns:
// {
//   _id: 'image-abc123-1920x1080-jpg',
//   crop: { top: 0.1, bottom: 0.1, left: 0, right: 0 },
//   hotspot: { x: 0.5, y: 0.3 }
// }
// Note: _ref is removed, _id is added

// With _id field (already normalized)
const asset2 = {
  _id: 'image-abc123-1920x1080-jpg',
  crop: { top: 0, bottom: 0, left: 0, right: 0 }
}

const normalized2 = normalizeAssetId(asset2)
// Returns the same object with _id preserved

Use Cases

Useful when you need consistent asset objects with _id regardless of the source:
import { normalizeAssetId, parseImageId } from 'sanity-image'

// Normalize assets from various sources
const assets = [
  { _ref: 'image-abc123-1920x1080-jpg', crop: null, hotspot: null },
  { _id: 'image-def456-800x600-png', crop: null, hotspot: null }
].map(normalizeAssetId)

// Now all assets have _id field
assets.forEach(asset => {
  const { dimensions } = parseImageId(asset._id)
  console.log(dimensions)
})

Type Definitions

Asset

Complete Sanity asset type with optional crop and hotspot data.
type Asset = {
  _id: string
  crop?: CropData | null
  hotspot?: HotspotData | null
}

type CropData = {
  bottom: number
  left: number
  right: number
  top: number
}

type HotspotData = {
  x: number
  y: number
}

Build docs developers (and LLMs) love