Files Guide

Working with Files

Files in Val

Val supports generic file uploads for any file type, including videos, PDFs, audio files, and more. Files work similarly to images but with more flexibility in file types.

Defining File Schema

Use `s.file()` to define a file field in your schema. You can optionally specify accepted file types:

const mediaSchema = s.object({
  video: s.file({ accept: "video/*" }),
  document: s.file({ accept: ".pdf,.doc,.docx" }),
  audio: s.file({ accept: "audio/*" }),
  anyFile: s.file(), // Accepts any file type
});

Using Local Files

Local files are stored in the `/public/val` folder. Use `c.file()` to reference them:

export default c.define("/content/media.val.ts", mediaSchema, {
  video: c.file("/public/val/video.mp4"),
  document: c.file("/public/val/guide.pdf"),
  audio: c.file("/public/val/podcast.mp3"),
  anyFile: c.file("/public/val/data.json"),
});

Using Remote Files

Enable remote files by adding `.remote()` to your schema. Then use `c.remote()` to reference external URLs:

const mediaSchema = s.object({
  externalVideo: s.file({ accept: "video/*" }).remote(),
  externalDocument: s.file({ accept: ".pdf" }).remote(),
});

export default c.define("/content/media.val.ts", mediaSchema, {
  externalVideo: c.remote(
    "https://example.com/video.mp4",
    { mimeType: "video/mp4" }
  ),
  externalDocument: c.remote(
    "https://example.com/guide.pdf",
    { mimeType: "application/pdf" }
  ),
});

Rendering Files

Files are returned as URL strings that you can use directly in your components:

import { fetchVal } from "@/val/val.rsc";
import mediaVal from "./media.val";

export default async function MediaPage() {
  const { video, document, audio } = await fetchVal(mediaVal);
  
  return (
    <div>
      <video src={video} controls className="w-full" />
      
      <a 
        href={document} 
        download 
        className="btn"
      >
        Download PDF
      </a>
      
      <audio src={audio} controls />
    </div>
  );
}

Video Files in Val Studio

When you use `s.file({ accept: 'video/*' })`, Val Studio will recognize it as a video file and provide a video preview in the editor. This makes it easier to manage video content.

File Storage

Like images, local files must be stored in the `/public/val` directory. When editors upload files through Val Studio, they are automatically saved to this location.