Skip to main content

Photo data and dimensions

Use one stable photo shape for layout, navigation, and image delivery.

Nuxt Photo accepts one public photo shape: PhotoItem.

Test the PhotoItem contract

Invalid data fails before layout calculation.

Desert landscape at golden hour

Valid collectionThe album can calculate geometry before loading images.

const photos: PhotoItem[] = [
  {
    "id": "desert-light",
    "src": "/photos/desert-light.jpg",
    "width": 1280,
    "height": 800,
    "alt": "Desert landscape at golden hour",
    "caption": "Desert Light",
    "description": "Golden hour over sand dunes with long shadows stretching across the landscape."
  }
]
ts
import type { PhotoItem } from '@lupinum/nuxt-photo/app'

Required fields

ts
const photo: PhotoItem = {
  id: 'alpine-lake',
  src: '/photos/alpine-lake.jpg',
  width: 1600,
  height: 1067,
}
FieldRequirement
idA non-empty string that is unique in the current collection.
srcThe full image URL used by the lightbox.
widthThe intrinsic pixel width. It must be positive and finite.
heightThe intrinsic pixel height. It must be positive and finite.

Intrinsic dimensions describe the source file, not its displayed CSS size. They let Nuxt Photo calculate the layout and reserve space before the image loads. Do not use array positions as IDs or approximate dimensions.

If a CMS omits dimensions, calculate them during upload or server-side ingestion. The CMS guide shows one approach.

Optional fields

FieldPurpose
altAlternative text for the thumbnail and lightbox image.
captionShort visible text for the photo.
descriptionLonger visible text in the included lightbox.
thumbSrcA smaller image URL for thumbnails.
placeholderSrcA low-quality preview shown until the requested image loads.
srcsetNative responsive image candidates.
metaTyped application data passed through to slots and adapters.

The placeholder resets when the resolved image request changes. It remains visible when that image fails to load.

Map external data once

Convert CMS or API records at your application boundary. Rendering components should receive PhotoItem[] instead of knowing each source format.

ts
const photos = records.map((record) => ({
  id: String(record.id),
  src: record.image.url,
  width: record.image.width,
  height: record.image.height,
  alt: record.image.alt ?? undefined,
  meta: { credit: record.image.credit },
})) satisfies PhotoItem<{ credit: string }>[]

This mapping gives layout, navigation, and image delivery one source of truth.