# Rendering assets

> Consume the asset parameter from your frontend.

Source: https://docs.uniform.app/docs/guides/composition/manage-assets/rendering-assets

This page describes the shape of the asset parameter value returned by the Uniform APIs and the SDK utilities you can use to render assets in your frontend. For the editor-facing flow, see the [asset parameter](https://docs.uniform.app/docs/guides/composition/manage-assets/asset-parameter). For configuration options when defining the parameter on a component, see [parameters for components](https://docs.uniform.app/docs/guides/models/components/parameters#asset).

## Asset properties

The asset parameter provides a composition with a set of properties about an asset, reducing or eliminating the need to model them as separate component parameters. The data within the asset parameter is returned as an array, even if the array only contains one item.

API responses include these fields:

| Parameter | Description | Allowed values | Required |
| --- | --- | --- | --- |
| type | Broad category of the asset | `image`, `video`, `audio`, `other` | Yes |
| _source | Internal field indicating the source of the image. It could be an integration ID, a data resource name, or a custom string | `uniform-assets`, `<string>` | No |
| _id | Random, persisted UUID assigned to the asset parameter array item to assist with frontend rendering (for example, as a value for the React key property). This is not the ID of the asset, which is instead found in the `fields.id` property. | <UUID string> | Yes |
| fields.id | ID of the asset | `type: 'text'`, `value: '<UUID string>'` | No |
| fields.url | URL pointing to the binary file | `type: 'text'`, `value: '<URL>'` | Yes |
| fields.title | Title of the asset | `type: 'text'`, `value: '<STRING>'` | No |
| fields.description | Description of the asset | `type: 'text'`, `value: '<STRING>'` | No |
| fields.mediaType | Media (mime) type of the asset | `type: 'text'`, `value: '<STRING>'` | No |
| fields.width | Width of the asset (in case of an image) | `type: 'number'`, `value: <NUMBER>` | No |
| fields.height | Height of the asset (in case of an image) | `type: 'number'`, `value: <NUMBER>` | No |
| fields.focalPoint | Focal point of the asset (in case of an image) | `type: 'focalPoint'`, `value.x: <NUMBER>`, `value.y: <NUMBER>` | No |

In the context of a composition, the response from the API would be structured like this:

_For the US region:_

```json
"asset": {
  "type": "asset",
  "value": [
    {
      "type": "image",
      "_id": "69197033-6dcb-49f2-91bf-a3c8246ff8ee",
      "_source": "uniform-assets",
      "fields": {
        "id": {
          "type": "text",
          "value": "69197033-6dcb-49f2-91bf-a3c8246ff8ee"
        },
        "url": {
          "type": "text",
          "value": "https://img.uniform.global/p/j52GAt4USny1AmTCdiwADQ/jvbDipiiQT6v94H0dD1NeA-some-image.png",
        },
        "title": {
          "type": "text",
          "value": "Asset Title",
        },
        "description": {
          "type": "text",
          "value": "This is an image showing something interesting",
        },
        "mediaType": {
          "type": "text",
          "value": "image/png",
        },
        "width": {
          "type": "number",
          "value": 1000,
        },
        "height": {
          "type": "number",
          "value": 563,
        },
        "focalPoint": {
          "type": "focalPoint",
          "value": {
            "x": 0.5,
            "y": 0.5,
          },
        },
      },
    },
  ]
},
```

_For the EU region:_

```json
"asset": {
  "type": "asset",
  "value": [
    {
      "type": "image",
      "_id": "69197033-6dcb-49f2-91bf-a3c8246ff8ee",
      "_source": "uniform-assets",
      "fields": {
        "id": {
          "type": "text",
          "value": "69197033-6dcb-49f2-91bf-a3c8246ff8ee"
        },
        "url": {
          "type": "text",
          "value": "https://img.eu.uniform.global/p/j52GAt4USny1AmTCdiwADQ/jvbDipiiQT6v94H0dD1NeA-some-image.png",
        },
        "title": {
          "type": "text",
          "value": "Asset Title",
        },
        "description": {
          "type": "text",
          "value": "This is an image showing something interesting",
        },
        "mediaType": {
          "type": "text",
          "value": "image/png",
        },
        "width": {
          "type": "number",
          "value": 1000,
        },
        "height": {
          "type": "number",
          "value": 563,
        },
        "focalPoint": {
          "type": "focalPoint",
          "value": {
            "x": 0.5,
            "y": 0.5,
          },
        },
      },
    },
  ]
},
```

## Frontend rendering

### JavaScript

[Asset utilities](https://docs.uniform.app/docs/guides/composition/rendering/blocks-assets) are provided by the Uniform SDK to streamline the process of rendering assets in your application.

For interacting with the [Image Delivery API](https://docs.uniform.app/docs/guides/composition/manage-assets/image-delivery-api), an `imageFrom` utility is available, exported from the `@uniformdev/assets` package. The utility assists with the following:

1. Extracting a URL from an asset parameter
2. Constructing a URL compatible with the Image Delivery API transformations, for assets sourced from the Uniform Asset Library

_For the US region:_

```ts
import { imageFrom } from '@uniformdev/assets'

const assetParameter = { ... };

for (const asset of assetParameter.value) {
  // Log the URL of the asset from the asset parameter
  console.log(imageFrom(asset).url());
}

for (const asset of assetParameter.value) {
  // Resize the image to 100x100, with the focal point set to the top left corner
  console.log(imageFrom(asset).transform({ width: 100, height: 100, focal: { x: 0, y: 0 } }).url());
}

for (const asset of assetParameter.value) {
  // Fit the image to a 100x100 box, but don't crop
  console.log(imageFrom(asset).transform({ width: 100, height: 100, fit: 'scale-down' }).url());
}

// You can also pass in a URL directly
imageFrom('https://img.uniform.global/p/...').transform({ width: 1200 }).url();
```

_For the EU region:_

```ts
import { imageFrom } from '@uniformdev/assets'

const assetParameter = { ... };

for (const asset of assetParameter.value) {
  // Log the URL of the asset from the asset parameter
  console.log(imageFrom(asset).url());
}

for (const asset of assetParameter.value) {
  // Resize the image to 100x100, with the focal point set to the top left corner
  console.log(imageFrom(asset).transform({ width: 100, height: 100, focal: { x: 0, y: 0 } }).url());
}

for (const asset of assetParameter.value) {
  // Fit the image to a 100x100 box, but don't crop
  console.log(imageFrom(asset).transform({ width: 100, height: 100, fit: 'scale-down' }).url());
}

// You can also pass in a URL directly
imageFrom('https://img.eu.uniform.global/p/...').transform({ width: 1200 }).url();
```

> **Tip:**
>
> The `imageFrom` utility will automatically respect the focal point of the asset passed to it if present, you do not need to manually pass it in.

> **Info:**
>
> Calls to `.transform()` will be ignored for non-image assets, and any assets not sourced from the Uniform Asset Library. In those cases, the original URL will always be returned.

### TypeScript types

The assets SDK (available under `@uniformdev/assets`) exports types that can be useful when rendering assets in your application.

```ts
import type {
  /** A type for a whole array representing the value of an asset parameter **/
  AssetParamValue,
  /** A type of a single array item representing the asset parameter item payload **/
  AssetParamValueItem,
  /** Image delivery parameters type **/
  ImageDeliveryParams,
} from '@uniformdev/assets'
```

### Next.js

When rendering images coming from the Uniform Asset Library, you will need to follow a few steps:

1. Enable images coming from the Uniform CDN

In your `next.config.ts` file, add _For the US region:_

_For the EU region:_

 as an allowed remote pattern:

_For the US region:_

```ts
const nextConfig = {
  ...
  images: {
    remotePatterns: [
      {
        protocol: 'https',
        hostname: 'img.uniform.global',
      },
    ],
  },
}
```

_For the EU region:_

```ts
const nextConfig = {
  ...
  images: {
    remotePatterns: [
      {
        protocol: 'https',
        hostname: 'img.eu.uniform.global',
      },
    ],
  },
}
```

2. Use the `imageFrom` utility documented above in combination with the `Image` component:

```tsx
import { imageFrom } from '@uniformdev/assets'

const [firstAsset] = assetsParameter

return (
  <Image
    src={imageFrom(firstAsset).transform({ width: 1200 }).url()}
    // We need a ?? fallback because the width and height are required by the Next.js Image component,
    // but are not guaranteed to be present on every asset parameter, specifically for assets
    // not sourced from the Uniform Asset Library
    width={firstAsset.fields.width?.value ?? 1200}
    height={firstAsset.fields.height?.value ?? 800}
    alt={firstAsset.fields.description?.value ?? ''}
  />
)
```

3. For background images you can use the `Image` component together with the `fill` property, like so:

```tsx
return (
  <div
    style={{
      width: '400px',
      height: '400px',
      position: 'relative',
    }}
  >
    <Image
      // The focal point property of an asset is automatically respected by `transform` and does not need to be passed in
      src={imageFrom(firstAsset).transform({ width: 400, height: 400 }).url()}
      alt={firstAsset.fields.description?.value ?? ''}
      fill
    />
  </div>
)
```

> **Use an AI coding assistant:**
>
> The [`uniform-assets`](https://github.com/uniformdev/agent-skills/tree/main/skills/uniform-assets) agent skill teaches coding assistants such as Claude Code, Codex, Cursor, and Copilot how to define asset parameters, render images with `imageFrom`, read asset fields, and seed or migrate asset values. To install it, see [Uniform agent skills](https://docs.uniform.app/docs/guides/ai/agent-skills).
