Working with Images

Working with Images

Images in Val

Val provides a type-safe way to handle images with built-in support for local and remote images. Images are optimized and integrated with Next.js Image component.

Defining Image Schema

Use s.image() to define an image field in your schema:

const pageSchema = s.object({
  hero: s.image(),
  thumbnail: s.image().nullable(),
  logo: s.image(),
});

Using Local Images

Local images are stored in the /public/val folder. Use c.image() to reference them:

export default c.define("/content/page.val.ts", pageSchema, {
  hero: c.image("/public/val/hero.jpg"),
  thumbnail: c.image("/public/val/thumb.png"),
  logo: c.image("/public/val/logo.svg", {
    alt: "Logo"
  }),
});

Adding Image Metadata

Images must have a valid metadata object with width, height and mimeType. Use the CLI to automatically generate and / validate this metadata for you.

NOTE: You can also add alt text.

Using the VS Code Extension

You can also use the Val Intellisense VS Code extension to automatically generate and validate metadata for your images.

Using Remote Images

Enable remote images by adding .remote() to your schema. Just as with the metadata, you can use the CLI or the VS Code extension to upload the images to the remote server. Make sure you follow the remote files guide before trying this.

Uploading Remote Images

Use the CLI to upload remote images to the remote server. We recommend using the CLI when working with multiple files.

Uploading Remote Images with the VS Code Extension

You can also use the Val Intellisense VS Code extension to upload remote images to the remote server. This also works in reverse: if you remove the .remote(), it will download the image automatically for you.

Rendering Images

Use the ValImage component to render images in your React components:

import { ValImage } from "@valbuild/next/client";
import { fetchVal } from "@/val/val.rsc";
import pageVal from "./page.val";

export default async function Page() {
  const { hero, thumbnail } = await fetchVal(pageVal);
  
  return (
    <div>
      <ValImage 
        src={hero} 
        priority 
        className="w-full h-auto"
      />
      {thumbnail && (
        <ValImage 
          src={thumbnail}
          className="w-32 h-32 object-cover"
        />
      )}
    </div>
  );
}

Image Properties

When defining images, you must provide:

  • width: The intrinsic width of the image

  • height: The intrinsic height of the image

  • alt: Alt text for accessibility

  • mimeType: (Remote images only) The MIME type

Important

Local images must be stored in the /public/val directory. Val Studio will automatically upload images to this location when you add them through the editor.