Fetching MP4 or WEBM Assets with Next.js - Error: Failed to Resolve Asset ID from Source

2 replies
Last updated: Mar 27, 2022
Question for the channel… someone has experience fetching mp4/webm or any other type of data besides images? I’m trying to work with
@sanity/asset-utils
but I’m stuck here Failed to resolve asset ID from source, if someone can share me a hint, tutorial, snippet code from where to keep figuring out I’ll really appreciate.
Thanks!
AI Update

I feel your pain! The @sanity/asset-utils library can be tricky when working with files. The "Failed to resolve asset ID from source" error usually happens when the data structure you're passing to getFileAsset() isn't what the library expects.

The Data Structure Issue

The getFileAsset() function from @sanity/asset-utils expects your file field to have a specific shape. When you query a file field in Sanity, make sure you're getting the full asset object, not just a reference.

In your GROQ query, you need to dereference the asset:

*[_type == "yourDocumentType"] {
  videoFile {
    asset-> {
      _id,
      url,
      originalFilename,
      mimeType,
      extension
    }
  }
}

Notice the asset-> with the arrow - that's dereferencing the asset reference.

Using getFileAsset()

Once you have the proper data structure, getFileAsset() works the same for videos (mp4, webm) as it does for other files:

import { getFileAsset } from '@sanity/asset-utils';

// Your Sanity config
const sanityConfig = {
  projectId: 'your-project-id',
  dataset: 'your-dataset'
};

// The file object from your query
const fileSource = {
  asset: {
    _ref: 'file-abc123...',  // or the full dereferenced object
  }
};

// Get the file asset details
const fileAsset = getFileAsset(fileSource, sanityConfig);

// Now you can access:
// fileAsset.url - the CDN URL
// fileAsset.extension - like 'mp4' or 'webm'
// fileAsset.mimeType - like 'video/mp4'

Common Gotchas

  1. Missing asset reference: If your file field is null or the asset hasn't been uploaded yet, you'll get that error
  2. Wrong data shape: Make sure you're passing the whole file object (with asset property), not just the _ref string
  3. Project config: The second parameter needs your projectId and dataset

Alternative Approach

If you're still stuck, you can also just work directly with the file URL from your query without using @sanity/asset-utils:

*[_type == "yourDocumentType"] {
  "videoUrl": videoFile.asset->url,
  "videoType": videoFile.asset->mimeType
}

Then use the URL directly in your video player. For more details on working with files, check out the file type documentation.

Hope this helps! If you're still getting the error, share what your file field schema looks like and how you're querying it - that'll help narrow down the issue.

Is working!!! I was missing to add a simple
value.
at the beginning
I took the example from here:
https://www.harrytheo.com/blog/2021/07/replace-gif-with-video-in-sanity-gatsby/
To make it works in Next JS:


function videoAssetFor(source) {
  return getFileAsset(source, client.config());
}

const ptComponents = {
  types: {
    videoAnimation: ({ value }) => {
      if (!value.webm || !value.fallback) {
        return null;
      }
      const webmAsset = videoAssetFor(value.webm);
      const fallbackAsset = videoAssetFor(value.fallback);

      return (
        <video title={webmAsset.alt} loop muted autoPlay playsInline>
          <source src={webmAsset.url} type={`video/${webmAsset.extension}`} />
          <source src={fallbackAsset.url} type={`video/${fallbackAsset.extension}`}
          />
        </video>
      );
    },
....more code

Sanity – Build the way you think, not the way your CMS thinks

Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.

Was this answer helpful?