Setting up Sanity image pipelines with Remix - do I need @sanity/client?

27 replies
Last updated: Aug 25, 2022
I'm having trouble understanding Sanity image pipelines...I am creating a project with Remix and using Sanity
I have installed @sanity/image-url in my project
Do I need to install @sanity/client? I feel like that was already installed when I set up Sanity?
And are there any better guides out there with a step by step set up for using images?
AI Update

Great questions! Let me break this down for you:

Do you need to install @sanity/client?

No, you don't need @sanity/client to use @sanity/image-url. The image URL builder can work in two ways:

  1. With a configured client (recommended): Pass a configured @sanity/client instance to createImageUrlBuilder(). This is convenient because the builder inherits your projectId and dataset from the client.

  2. Without a client: You can configure the builder directly by passing just your projectId and dataset:

import { createImageUrlBuilder } from '@sanity/image-url'

const builder = createImageUrlBuilder({
  projectId: 'your-project-id',
  dataset: 'production',
})

export function urlFor(source) {
  return builder.image(source)
}

So if you already have @sanity/client installed (which you likely do from setting up Sanity), you can use it. But if you only need image URL generation and nothing else, you can skip the client and just pass the config directly.

Step-by-step setup for using images in Remix:

  1. Install the package:
npm install @sanity/image-url
  1. Create a helper file (e.g., app/lib/sanity/image.ts):
import { createImageUrlBuilder } from '@sanity/image-url'
import type { SanityImageSource } from '@sanity/image-url'

// Option 1: Without @sanity/client
const builder = createImageUrlBuilder({
  projectId: 'your-project-id',
  dataset: 'production',
})

// Option 2: With @sanity/client (if you have it)
// import { client } from './client'
// const builder = createImageUrlBuilder(client)

export function urlFor(source: SanityImageSource) {
  return builder.image(source)
}
  1. Use it in your Remix components:
import { urlFor } from '~/lib/sanity/image'

export default function MyComponent({ person }) {
  return (
    <img 
      src={urlFor(person.image)
        .width(800)
        .height(600)
        .url()}
      alt={person.name}
    />
  )
}

Key points:

  • Always pass the full image object (not just image.asset) to urlFor() so it respects crop and hotspot settings
  • The builder automatically handles Sanity's image transformations and CDN URLs
  • You can chain methods like .width(), .height(), .format(), etc.

For more details, check out the official Presenting Images guide and the @sanity/image-url library documentation.

Show original thread
27 replies
If you've already configured your client on your frontend, you won't need to create another client. You can just pass that original client into the builder. Here's a really simple example that would allow you to have a configured client and url builder:
import sanityClient from '@sanity/client';
import imageUrlBuilder from '@sanity/image-url';

export const client = sanityClient({
  projectId: 'project-id',
  dataset: 'dataset-name',
  apiVersion: '2022-08-25', 
});

const builder = imageUrlBuilder(client);

export function urlFor(source) {
  return builder.image(source);
}
How do I check if I have @sanity/client set up?
That was a silly question
I'd first check that it's included in your package.json. If it's in the dependencies array there, there's likely a file in your repo that's called something like
sanity.js
or
client.js
those are the two most common names people use.
Hmm, it's not showing up in my dependencies so I installed it and it's still not showing up in my package.json?
I've also got picosanity installed - Would that be causing it not to show up?
user M
I'd guess you haven't installed it yet. You can run
npm i --save @sanity/client @sanity/image-url
, then create a
sanity.js
file. You can then just copy and paste that snippet I shared and place in your project id and dataset. You should be all configured then@
That worked - Where do you recommend placing the sanity.js file (Also, I'm using typescript)
I'm pretty typescript ignorant, so I can't help too much there 😅 But I'll usually create a
/src
folder to hold my client configuration.
Thaaaankkk youuuuuu!!!
You're welcome!
user M
one last question, how do I import the sanity.js file into my component / is the urlFor imported along with it?
You can do this:
import { client, urlFor } from './src/sanity'
The path to your
sanity.js
might need to be changed depending on where you're importing it, though!
user M
still getting an error
What does the error say when you hover over it?
Can you try adding
.url()
to the end of your
urlFor
function?
That fixes the error on src but now I'm getting this error:
Unable to resolve image URL from source (null)

it looks like
post.mainImage
is not defined.
If you
console.log(post)
is it there?
Wait, I figured it out - It seems I needed to have a 'mainImage' for every post I had made as test posts
This has been a very amazing learning journey and I can't thank you enough!!!
Very happy to help! I love watching folks start to 'get it'!
user M
is it ok for my projectId to be in a file that someone could possibly see? Also, if I were to ever deploy this, would I need to change the dataset from production to something else?
Yes, project IDs aren't considered secret so it's safe to expose them. You do want to take care not to expose any tokens you may eventually add in though!
You can use whatever dataset name you'd like; it won't have any effect once you go to deploy. Folks will use different datasets like
development
and
production
when they want a dataset that isn't reflected in their deployed site as they make changes.
Awesome, thank you!
The enthusiasm is infectious

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?