How to get file URL from Sanity asset reference in Next.js?
When working with file assets in Sanity, there are a couple of approaches to get the download URL in your Next.js frontend:
Option 1: Properly Resolve the Asset Reference in GROQ
The issue with file.asset->url returning undefined is that you need to fully resolve the asset reference. Try this GROQ query pattern:
*[_type == "yourDocType"] {
...,
"fileUrl": file.asset->url
}However, if that's still returning undefined, you might need to resolve it more explicitly:
*[_type == "yourDocType"] {
...,
file {
asset-> {
url
}
}
}Or spread the asset fields:
*[_type == "yourDocType"] {
...,
file {
...,
asset-> {
_id,
url,
originalFilename,
size
}
}
}Option 2: Use @sanity/asset-utils (Recommended)
Instead of resolving the URL in GROQ, you can use the @sanity/asset-utils package to build URLs from the asset reference. This is often more efficient since you avoid extra resolving in your query:
Install the package:
npm install @sanity/asset-utilsUse a simpler GROQ query:
*[_type == "yourDocType"] {
...,
file
}Build the URL in your frontend:
import {buildFileUrl} from '@sanity/asset-utils'
// In your component
const fileUrl = buildFileUrl(file, {
projectId: 'your-project-id',
dataset: 'your-dataset'
})You can also get additional file information like size and original filename:
*[_type == "yourDocType"] {
...,
file {
asset-> {
_id,
originalFilename,
size
}
}
}Then in your frontend:
import {buildFileUrl} from '@sanity/asset-utils'
const fileUrl = buildFileUrl(file.asset, {
projectId: 'your-project-id',
dataset: 'your-dataset'
})
const fileName = file.asset.originalFilename
const fileSize = file.asset.sizeEnabling Downloads
To trigger a download (rather than opening in browser), append ?dl= to the URL:
<a href={`${fileUrl}?dl=`} download>
Download File
</a>The ?dl parameter is a Sanity CDN feature that forces the browser to download the file instead of displaying it.
Summary
The @sanity/asset-utils approach is generally preferred because:
- It avoids unnecessary API calls to resolve references
- It works with just the asset
_refor_id - It's more performant for your GROQ queries
- You have full control over URL building in your frontend code
Show original thread11 replies
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.