Improving UI with schema previews and thumbnails
Next, you will enhance the user interface (UI) with previews, thumbnails, and filters. These additions will help editors quickly find and use the blocks they need to create pages.
Previews are the snippets of information that appear in the list view of the page builder. They're the first thing your editors will see when they're adding a new block to the page builder.
Here's an example of what a good preview looks like:
And here's what a bad preview looks like:
What makes a good preview?
Previews should always have consistency. Consistency creates familiarity and familiarity improves user experience. The more consistency you have in your previews and page builders, the faster it will be for your editors to create pages.
So we're going to start with the best way to organize them.
- Title: This is the title of the block, or the most important headline. Think what section a marketer would care about the most.
- Subtitle: Call this the block name.
- Media: If the block has an image, use that, otherwise use an icon as a fallback.
Let's revisit our blocks from the last lesson and improve the readability.
Note, this lesson uses the default icons from Sanity (opens in a new tab) to minimize dependencies. However, in a real-world project,Lucide (opens in a new tab) is recommended for much larger icon selection.
Using prepare and preview
Pay attention to the preview
and prepare
functions. This is where you are defining how the block appears in the preview.
In the example below, there is a block with a title, subtitle and media.
The pink cat on the left-hand side is the media preview, this can either be an image, or an icon. However, you should never leave it blank.
The highlighted fields below are where the values are set.
import { defineField, defineType } from "sanity";
import { BlockContentIcon } from "@sanity/icons";
export default defineType({
name: "textAndImage",
type: "object",
icon: BlockContentIcon,
fields: [
defineField({
name: "orientation",
type: "string",
options: {
list: ["imageLeft", "imageRight"],
},
}),
defineField({
name: "title",
type: "string",
}),
defineField({
name: "image",
type: "image",
}),
],
preview: {
select: {
title: "title",
media: "image",
},
prepare({ title, media }) {
return {
title: title,
subtitle: "Text and Image",
media: media ?? BlockContentIcon,
};
},
},
});
This example is a simple block with a title, subtitle and media. The prepare
function is used to set the title and media for the preview. You can permeate these previews to your other two blocks, and can find out more here (opens in a new tab).
Adding thumbnails
To implement grid view previews, you need to add the options
property to your schema. This is where you are defining how the block appears in the preview. For this particular example, you are adding a grid
view to the options
property.
This creates a grid view of the block, and the preview image is taken from the static
folder.
It should look something like this:
export default defineType({
// ... previous configuration
options: {
insertMenu: {
views: [
{
name: "grid",
previewImageUrl: (schemaType) => `/static/previews/${schemaType}.png`,
},
],
},
},
});
Finally create a static
folder in your Studio root with preview images following this naming convention:
- Dimensions: 600x400px (maintain consistent sizing)
- Format: PNG with transparent background
- Naming: Match schema type names (e.g.,
hero.png
,splitImage.png
)
There is a community file built for this, it is available here (opens in a new tab).
In the next lesson, you'll transform your basic page builder into a dynamic tool that your content team will love. Create a JavaScript switch in Next.js, you'll render blocks based on your Sanity content, making your frontend more flexible and efficient.