KINDERAS.COM

Sat May 21 2022

Validating child fields in Sanity - Image object with alt text

Sanity is a content platform (or a headless CMS) for both individuals and companies. One of the things that separate Sanity from other Headless CMS products is its flexibility. Sanity enables you to describe the CMS interface (called Studio) using simple JSON objects, or rolling your own fully custom React components.

This flexibility means that you can achieve a lot with regards to data structures and the CMS UI (Studio). However, it also means that you don't get as much out of the box, compared to for instance WordPress or Contentful CMS.

PS: This post assumes some knowledge of how Sanity works. If you're new to Sanity, take a look at their getting started article.

The problem

This post demonstrates how to do validation on child fields of an image object with additional fields. This is very useful when you want to create one image object, and reuse it acroll multiple documents.

The main challenge is to be able to have one image object, which then can be used in multiple documents. In some documents we might want the image object to be required, in others optional.

The solution

Imagine that you have created the following object in Sanity allowing editors to add an image to a document.

  • You have the image file itself, this will be using the build in Sanity image type.
  • Then you want to have an alternative text input to use as the image alt property. This is the alt field.
  • Then perhaps you'll want a caption field, to display a text below the image. This is the caption field in the code below.

This object might look like something like this:

export default {
    type: "image",
    title: "Image with caption",
    name: "accessibleImage",
    options: { hotspot: true },
    fields: [
        {
            name: "alt",
            title: "Alternative text",
            type: "string",
            options: {
                isHighlighted: true,
            },
        },
        {
            name: "caption",
            title: "Caption",
            type: "string",
            description: "(optional) A description which will be shown under the image",
            options: {
                isHighlighted: true,
            },
        },
    ]
};

As described in the the problem section, we want to be able to use this image object in multiple documents, where sometimes the image should be required, sometimes optional.

This means that we can't add the required/optional validation into the image object itself. Instead we have to add the validation to the document where the image object is being used as a field.

The validation

Tip: If you are unfamiliar with validation in Sanity, you can take a look at their excellent documentation first.

The validation itself depends on what you want to be required. Let's assume that in our document we want to enforce that the editor has to upload an image file and add an alt text, the caption remains optional.

Let's say we a have a simple article document, like this:

export default {
    name: "myArticle",
    title: "Article",
    type: "document",
    fields: [
        {
            name: "title",
            title: "Page title",
            type: "string",
            validation: (Rule: { required: () => any }) => Rule.required(),
        },
        // other fields probably ....
        {
            type: "accessibleImage",
            name: "articlePreviewImage",
            description: "This is the image used to generate previews for this article",
            title: "Preview Image",
            validation: (Rule) =>
                Rule.custom((fields) => {
                    if (fields && fields.asset && typeof fields.alt === "string") {
                        return true;
                    }
                    return "Preview image: The image and an alt text is required";
                }),
        },
    ]
};

This "Article" document has a title which is required and an "AccessibleImage" field with a custom validation rule (line 19) which does the following:

  • Test if the asset field exists. If it does then the editor has uploaded an image
  • Test if the alt field is a string. If it is a string, then the editor has added an alternative text. (Note: You could enforce a minimum lengh here as well)

If both of the test cases above are true, then the validation will pass, if not it will return an error message.

That's it..

Sources