Back to blog

Published on Thursday, January 9, 2025

How to Use Sanity.io CMS Images in Your Next.js App with @sanity/image-url

How to Use Sanity.io CMS Images in Your Next.js App with @sanity/image-url

Video Tutorial

Prerequisites

Before starting, ensure you have:

  • A Sanity.io account (sign up if you don’t have one).
  • A Sanity project set up with a dataset containing images.
  • A working Next.js app (create one with npx create-next-app@latest).
  • Basic knowledge of Sanity schemas for managing image content.

Step 1: Installation

First, add the Sanity client and @sanity/image-url to your project:

npm install @sanity/client @sanity/image-url

Step 2: Configure the Sanity Client

Create a lib/sanity/index.ts file to set up the Sanity client and image URL builder:

import { createClient } from '@sanity/client'
import imageUrlBuilder from '@sanity/image-url'

// Note: Ensure these env vars is inlcuded in .env
export const sanityClient = createClient({
  projectId: process.env.SANITY_PROJECT_ID,
  dataset: process.env.SANITY_DATASET,
  useCdn: true,
});

const builder = imageUrlBuilder(sanityClient);

export const urlFor = (source) => builder.image(source);

Step 3: Configure Next.js for Sanity.io Images

To enable image optimization for Sanity.io images in your Next.js app, update your next.config.js file with the following configuration:

import type { NextConfig } from "next";

const nextConfig: NextConfig = {
  images: {
    dangerouslyAllowSVG: true,
      remotePatterns: [
        {
          protocol: "https",
          hostname: "cdn.sanity.io",
          port: "",
          pathname: `/images/${process.env.SANITY_PROJECT_ID}/${process.env.SANITY_DATASET}/**`,
      },
    ],
  },
}

export default nextConfig

Step 4: Fetch and Display Posts with Thumbnails

Fetch posts from your Sanity project using a GROQ query and display their titles with thumbnail images:

import Image from "next/image"
import type { SanityImageSource } from '@sanity/image-url/lib/types/types'
import { sanityClient, urlFor } from '@/lib/sanity'

type Post = {
  slug: string;
  title: string;
  thumbnail: SanityImageSource; // Update based on your schema
};

export default async function Home() {
  const query = `*[_type == "post"]{ title, slug, thumbnail }`;
  const posts = await sanityClient.fetch<Post[]>(query);

  return (
    <main>
      <h1>Posts</h1>
      <ul>
        {posts.map((post) => (
          <li key={post.slug}>
            <h2>{post.title}</h2>
            {post.thumbnail && (
              <Image
                src={urlFor(post.thumbnail).width(150).height(100).url()}
                alt={post.title}
                width={150}
                height={100}
              />
            )}
          </li>
        ))}
      </ul>
    </main>
  );
}

Step 5: Test Your Application

Start the development server:

npm run dev

Conclusion

Integrating Sanity.io with Next.js makes building dynamic, content-driven apps simple and efficient. It enables seamless image optimization and enhances your app's visual appeal. This powerful combination ensures a smooth development experience and a better user interface.