Unlock seamless workflows and faster delivery with our latest releases – get the details
Last updated August 17, 2024

Angular + Sanity CMS: Mastering Images with the Sanity Image Directive (Part 3)

By Alfonso Andrés López Molina

Explore the Sanity Image Directive and Loader from @limitless-angular/sanity to optimize and display images in Angular projects. Learn to update schemas, create an image component, and enhance your Portable Text setup. Unlock the power of dynamic image transformations and optimizations!

Part 3: Mastering Images with the Sanity Image Directive

Hey there, Angular enthusiasts! Welcome back to our Angular + Sanity CMS adventure. In our previous posts, we dove into rendering Portable Text and setting up a Sanity project. Now, it's time to tackle something equally exciting: handling images like a pro!

Today, we're going to explore the Sanity Image Directive and Sanity Image Loader from our trusty `@limitless-angular/sanity` library. These tools are about to become your new best friends when it comes to working with images in your Angular + Sanity projects. Ready to level up your image game? Let's dive in!

What's so important about using Sanity Images?

Before we start coding, let's talk about why Sanity's approach to images is so cool. Sanity stores image assets separately from your content, allowing you to transform and optimize images on the fly. This means you can have one source image and display it in various sizes, crops, and formats across your site. Pretty neat, right?

The Dynamic Duo: Sanity Image Directive and Loader

Our `@limitless-angular/sanity` library provides two key players for handling Sanity images:

1. Sanity Image Directive: This is an Angular directive that makes it super easy to display Sanity images in your templates.
2. Sanity Image Loader: This is the behind-the-scenes hero that handles the actual loading and transformation of images.

Together, they make working with Sanity images in Angular a breeze!

Step 1: Update Your Sanity Schema

First things first, let's make sure our Sanity schema can handle images. Open up your `schemaTypes/post.ts` file and update the `content` field like this:

defineField({
  name: 'content',
  title: 'Content',
  type: 'array',
  of: [{type: 'block'}, {type: 'image'}],
}),

This change allows you to add images directly into your content array, right alongside your text blocks.

Step 2: Create Your Image Component

Now, let's create a new component to handle our images. Create a new file called `image.component.ts` in the same directory as your `portable-text-display.component.ts` file. This is typically in your `src/app` folder or a subdirectory thereof. Paste in this code:

import { ChangeDetectionStrategy, Component } from '@angular/core';
import {
  provideSanityLoader,
  SanityImage,
} from '@limitless-angular/sanity/image-loader';
import { PortableTextTypeComponent } from '@limitless-angular/sanity/portabletext';

@Component({
  selector: 'app-image',
  standalone: true,
  imports: [SanityImage],
  template: `
    <img
      class="mx-auto"
      alt="Sanity Image"
      [width]="400"
      [height]="400"
      [sanityImage]="value()"
    />
  `,
  styles: `
    :host {
      @apply block;
    }
  `,
  changeDetection: ChangeDetectionStrategy.OnPush,
  providers: [
    provideSanityLoader({ projectId: 'your-project-id', dataset: 'production' }),
  ],
})
export class ImageComponent extends PortableTextTypeComponent {}

Let's break this down:

  • We're using the `SanityImage` directive on our `img` tag. This is the magic that connects our image to Sanity.
  • The `[sanityImage]="value()"` attribute is where we pass our Sanity image object.
  • We're setting a fixed width and height here, but you could make these dynamic based on your needs.
  • The `provideSanityLoader` in the `providers` array sets up our image loader with your Sanity project details.
  • Importantly, the `SanityImage` directive inherits from `NgOptimizedImage`. This means we're automatically getting all the optimizations that `NgOptimizedImage` provides, without needing to set the `ngSrc` property separately.

Don't forget to replace `'your-project-id'` with your actual Sanity project ID!

Step 3: Update Your Portable Text Component

Now that we have our new `ImageComponent`, let's use it in our Portable Text setup. Update your `portable-text-display.component.ts` file:

import { Component, inject } from '@angular/core';
import { PortableTextComponent, PortableTextComponents } from '@limitless-angular/sanity/portabletext';
import { ContentService } from '../content.service';
import { toSignal } from '@angular/core/rxjs-interop';
import { LinkComponent } from './link.component';
import { ImageComponent } from './image.component';

@Component({
  selector: 'app-portable-text-display',
  standalone: true,
  imports: [PortableTextComponent],
  template: `
    @if (portableTextContent(); as content) {
      <div portable-text [value]="content" [components]="customComponents"></div>
    } @else {
      <p>Hold on, content's loading...</p>
    }
  `,
})
export class PortableTextDisplayComponent {
  private contentService = inject(ContentService);
  
  portableTextContent = toSignal(
    this.contentService.getPortableTextContent('my-first-blog-post')
  );

  customComponents: PortableTextComponents = {
    types: {
      image: ImageComponent,
    },
    marks: {
      link: LinkComponent,
    },
  };
}

The key change here is adding `ImageComponent` to our `customComponents` object under the `types` key. This tells our Portable Text renderer to use our custom `ImageComponent` whenever it encounters an image in the content.

Step 4: Marvel at Your Handiwork

That's it! Now, when you run your Angular app and load some content from Sanity that includes images, they should render beautifully using your new `ImageComponent`.

Here's what's happening behind the scenes:

  1. The Portable Text renderer encounters an image in your content.
  2. It uses your `ImageComponent` to render that image.
  3. The `SanityImage` directive in your `ImageComponent` works with the Sanity Image Loader to fetch and optimize the image.
  4. Because `SanityImage` inherits from `NgOptimizedImage`, you're automatically getting all the built-in Angular image optimizations.
  5. The result? A beautifully rendered, fully optimized image in your Angular app!

Bonus Tips and Tricks

Want to take your Sanity image game to the next level? Here are a few extra tips:

  1. Responsive Images: The `SanityImage` directive already provides responsive image handling through its inheritance from `NgOptimizedImage`. You can further customize this by adjusting the `sizes` attribute if needed.
  2. Image Transformations: Sanity's image API allows for on-the-fly transformations. You can adjust things like width, height, crop, and even apply filters directly in your image URL.
  3. Lazy Loading: Good news! The `SanityImage` directive automatically includes lazy loading functionality from `NgOptimizedImage`, so your images will lazy load by default.

Wrapping Up

And there you have it! You've just leveled up your Angular + Sanity CMS skills by mastering image handling. With the Sanity Image Directive and Loader, you now have the power to effortlessly display and optimize images in your Angular applications.

Remember, great images can make a big difference in a user's experience, so use these tools wisely. Keep experimenting, keep learning, and most importantly, keep enjoying your work with Angular and Sanity!

If you want to dive deeper, check out these resources:

Happy coding, and may your images always be crisp, your load times swift, and your users delighted!

Sanity – build remarkable experiences at scale

Sanity Composable Content Cloud is the headless CMS that gives you (and your team) a content backend to drive websites and applications with modern tooling. It offers a real-time editing environment for content creators that’s easy to configure but designed to be customized with JavaScript and React when needed. With the hosted document store, you query content freely and easily integrate with any framework or data source to distribute and enrich content.

Sanity scales from weekend projects to enterprise needs and is used by companies like Puma, AT&T, Burger King, Tata, and Figma.

Other guides by author

Angular + Sanity CMS: Setting Up Your Sanity CMS Project with TypeScript (Part 2)

Learn to set up a Sanity CMS project with TypeScript for seamless Angular integration. This guide covers creating a Sanity project, defining schemas, configuring Studio, and connecting to Angular. It builds on the previous @limitless-angular/sanity tutorial, completing your full-stack solution.

This is an external link at:dev.to
Alfonso Andrés López Molina
Go to Angular + Sanity CMS: Setting Up Your Sanity CMS Project with TypeScript (Part 2)

Angular + Sanity CMS: Rendering Portable Text with @limitless-angular/sanity

Learn to render Sanity CMS Portable Text in Angular using @limitless-angular/sanity. This guide covers setup, content fetching, and component creation, showcasing modern Angular features. Build dynamic, content-rich apps with ease.

This is an external link at:dev.to
Alfonso Andrés López Molina
Go to Angular + Sanity CMS: Rendering Portable Text with @limitless-angular/sanity