CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-payload

Node, React and MongoDB Headless CMS and Application Framework

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

field-types.mddocs/

Field Types

Rich set of field types for modeling content including text fields, relationships, file uploads, rich text editing, and complex nested structures. Fields are the building blocks of your content model in Payload.

Capabilities

Text Fields

Basic text input fields for short text content.

interface TextField extends BaseField {
  type: 'text';
  /** Maximum character length */
  maxLength?: number;
  /** Minimum character length */
  minLength?: number;
  /** Allow multiple values (array) */
  hasMany?: boolean;
}

Usage Example:

const titleField: TextField = {
  name: "title",
  type: "text",
  label: "Post Title",
  required: true,
  maxLength: 100,
  admin: {
    placeholder: "Enter post title...",
  },
};

// Multi-value text field
const tagsField: TextField = {
  name: "tags",
  type: "text",
  hasMany: true,
  admin: {
    placeholder: "Add tags...",
  },
};

Rich Text Fields

Advanced text editor with formatting, blocks, and custom elements.

interface RichTextField extends BaseField {
  type: 'richText';
  /** Rich text editor configuration */
  editor?: RichTextEditorConfig;
}

interface RichTextEditorConfig {
  /** Custom elements (bold, italic, etc.) */
  elements?: RichTextElement[];
  /** Custom leaves (inline formatting) */
  leaves?: RichTextLeaf[];
  /** Upload collections for media */
  upload?: {
    collections: {
      [collectionSlug: string]: UploadConfig;
    };
  };
  /** Link configuration */
  link?: {
    /** Collections that can be linked to */
    collections?: string[];
    /** External URL linking */
    url?: boolean;
  };
}

Usage Example:

const contentField: RichTextField = {
  name: "content",
  type: "richText",
  label: "Post Content",
  required: true,
  editor: {
    elements: ["h2", "h3", "blockquote", "ul", "ol", "link"],
    leaves: ["bold", "italic", "underline", "code"],
    upload: {
      collections: {
        media: {
          fields: [],
        },
      },
    },
    link: {
      collections: ["posts", "pages"],
      url: true,
    },
  },
};

Number Fields

Numeric input fields with validation and formatting options.

interface NumberField extends BaseField {
  type: 'number';
  /** Minimum value */
  min?: number;
  /** Maximum value */
  max?: number;
  /** Allow multiple values (array) */
  hasMany?: boolean;
}

Usage Example:

const priceField: NumberField = {
  name: "price",
  type: "number",
  label: "Price",
  required: true,
  min: 0,
  max: 10000,
  admin: {
    step: 0.01,
    placeholder: "0.00",
  },
};

Select Fields

Dropdown selection fields with predefined options.

interface SelectField extends BaseField {
  type: 'select';
  /** Available options */
  options: Option[];
  /** Allow multiple selections */
  hasMany?: boolean;
}

interface Option {
  /** Display label */
  label: string;
  /** Stored value */
  value: string;
}

Usage Example:

const statusField: SelectField = {
  name: "status",
  type: "select",
  label: "Status",
  required: true,
  options: [
    { label: "Draft", value: "draft" },
    { label: "Published", value: "published" },
    { label: "Archived", value: "archived" },
  ],
  defaultValue: "draft",
};

// Multi-select field
const categoriesField: SelectField = {
  name: "categories",
  type: "select",
  hasMany: true,
  options: [
    { label: "Technology", value: "tech" },
    { label: "Design", value: "design" },
    { label: "Business", value: "business" },
  ],
};

Relationship Fields

Reference other documents within collections.

interface RelationshipField extends BaseField {
  type: 'relationship';
  /** Collection(s) to relate to */
  relationTo: string | string[];
  /** Allow multiple relationships */
  hasMany?: boolean;
  /** Maximum depth for population */
  maxDepth?: number;
}

Usage Example:

// Single relationship
const authorField: RelationshipField = {
  name: "author",
  type: "relationship",
  relationTo: "users",
  required: true,
  admin: {
    position: "sidebar",
  },
};

// Multiple relationships to different collections
const relatedContentField: RelationshipField = {
  name: "relatedContent",
  type: "relationship",
  relationTo: ["posts", "pages", "products"],
  hasMany: true,
  maxDepth: 1,
};

// Multiple relationships to same collection
const relatedPostsField: RelationshipField = {
  name: "relatedPosts",
  type: "relationship",
  relationTo: "posts",
  hasMany: true,
  filterOptions: ({ data }) => {
    return {
      id: {
        not_in: [data.id],
      },
    };
  },
};

Upload Fields

File upload fields for media and documents.

interface UploadField extends BaseField {
  type: 'upload';
  /** Upload collection to relate to */
  relationTo: string;
}

Usage Example:

const featuredImageField: UploadField = {
  name: "featuredImage",
  type: "upload",
  relationTo: "media",
  admin: {
    description: "Choose a featured image for this post",
  },
};

// Multiple file uploads
const galleryField: UploadField = {
  name: "gallery",
  type: "upload",
  relationTo: "media",
  hasMany: true,
};

Array Fields

Repeatable field groups for complex data structures.

interface ArrayField extends BaseField {
  type: 'array';
  /** Fields within each array item */
  fields: Field[];
  /** Minimum number of items */
  minRows?: number;
  /** Maximum number of items */
  maxRows?: number;
  /** Labels for admin interface */
  labels?: {
    singular?: string;
    plural?: string;
  };
}

Usage Example:

const testimonialsField: ArrayField = {
  name: "testimonials",
  type: "array",
  label: "Testimonials",
  minRows: 1,
  maxRows: 10,
  labels: {
    singular: "Testimonial",
    plural: "Testimonials",
  },
  fields: [
    {
      name: "quote",
      type: "textarea",
      required: true,
    },
    {
      name: "author",
      type: "text",
      required: true,
    },
    {
      name: "company",
      type: "text",
    },
    {
      name: "photo",
      type: "upload",
      relationTo: "media",
    },
  ],
};

Block Fields

Flexible content blocks for page builders and dynamic layouts.

interface BlockField extends BaseField {
  type: 'blocks';
  /** Available block types */
  blocks: Block[];
  /** Minimum number of blocks */
  minRows?: number;
  /** Maximum number of blocks */
  maxRows?: number;
  /** Labels for admin interface */
  labels?: {
    singular?: string;
    plural?: string;
  };
}

interface Block {
  /** Unique block identifier */
  slug: string;
  /** Display label */
  label?: string;
  /** Block fields */
  fields: Field[];
  /** Admin configuration */
  admin?: {
    condition?: (data: any, siblingData: any) => boolean;
  };
  /** GraphQL configuration */
  graphQL?: {
    singularName?: string;
  };
}

Usage Example:

const pageContentField: BlockField = {
  name: "layout",
  type: "blocks",
  label: "Page Layout",
  minRows: 1,
  blocks: [
    {
      slug: "hero",
      label: "Hero Section",
      fields: [
        {
          name: "headline",
          type: "text",
          required: true,
        },
        {
          name: "subheading",
          type: "textarea",
        },
        {
          name: "backgroundImage",
          type: "upload",
          relationTo: "media",
        },
      ],
    },
    {
      slug: "content",
      label: "Content Block",
      fields: [
        {
          name: "content",
          type: "richText",
          required: true,
        },
      ],
    },
    {
      slug: "gallery",
      label: "Image Gallery",
      fields: [
        {
          name: "images",
          type: "array",
          fields: [
            {
              name: "image",
              type: "upload",
              relationTo: "media",
              required: true,
            },
            {
              name: "caption",
              type: "text",
            },
          ],
        },
      ],
    },
  ],
};

Group Fields

Organize related fields together for better admin UX.

interface GroupField extends BaseField {
  type: 'group';
  /** Fields within the group */
  fields: Field[];
}

Usage Example:

const seoField: GroupField = {
  name: "seo",
  type: "group",
  label: "SEO Settings",
  fields: [
    {
      name: "title",
      type: "text",
      maxLength: 60,
    },
    {
      name: "description",
      type: "textarea",
      maxLength: 160,
    },
    {
      name: "keywords",
      type: "text",
      hasMany: true,
    },
    {
      name: "ogImage",
      type: "upload",
      relationTo: "media",
    },
  ],
  admin: {
    condition: (data, siblingData) => {
      return data.status === "published";
    },
  },
};

Other Field Types

Additional field types for specific use cases.

// Email field with validation
interface EmailField extends BaseField {
  type: 'email';
  hasMany?: boolean;
}

// Textarea for longer text
interface TextareaField extends BaseField {
  type: 'textarea';
  maxLength?: number;
  minLength?: number;
  rows?: number;
}

// Checkbox for boolean values
interface CheckboxField extends BaseField {
  type: 'checkbox';
}

// Date picker field
interface DateField extends BaseField {
  type: 'date';
  displayFormat?: string;
  pickerAppearance?: 'dayAndTime' | 'timeOnly' | 'dayOnly' | 'monthOnly';
}

// Code editor field
interface CodeField extends BaseField {
  type: 'code';
  language?: string;
}

// Geographic point field
interface PointField extends BaseField {
  type: 'point';
}

// Radio button group
interface RadioField extends BaseField {
  type: 'radio';
  options: Option[];
}

// Row field for horizontal layout
interface RowField extends BaseField {
  type: 'row';
  fields: Field[];
}

// Collapsible field container
interface CollapsibleField extends BaseField {
  type: 'collapsible';
  label: string;
  fields: Field[];
}

// Tabbed field interface
interface TabsField extends BaseField {
  type: 'tabs';
  tabs: Tab[];
}

interface Tab {
  label: string;
  description?: string;
  fields: Field[];
}

// UI field for custom components
interface UIField extends BaseField {
  type: 'ui';
  admin: {
    components?: {
      Field?: React.ComponentType;
      Cell?: React.ComponentType;
    };
  };
}

Base Field Interface

All fields extend the base field interface with common properties.

interface BaseField {
  /** Field name (becomes database field name) */
  name: string;
  /** Field type */
  type: string;
  /** Display label */
  label?: string;
  /** Whether field is required */
  required?: boolean;
  /** Default value */
  defaultValue?: any;
  /** Validation function */
  validate?: Validate;
  /** Field-level access control */
  access?: FieldAccess;
  /** Field-level hooks */
  hooks?: FieldHooks;
  /** Admin interface configuration */
  admin?: FieldAdminConfig;
  /** Localization configuration */
  localized?: boolean;
  /** Custom condition for field visibility */
  condition?: (data: any, siblingData: any) => boolean;
  /** Database index configuration */
  index?: boolean;
  /** Save field to database */
  saveToJWT?: boolean;
  /** Hide field from GraphQL schema */
  hidden?: boolean;
}

interface FieldAccess {
  read?: AccessFunction;
  create?: AccessFunction;
  update?: AccessFunction;
}

interface FieldAdminConfig {
  /** Field position in admin */
  position?: "sidebar";
  /** Field description */
  description?: string;
  /** Placeholder text */
  placeholder?: string;
  /** Field width */
  width?: string;
  /** Custom field component */
  components?: {
    Field?: React.ComponentType;
    Cell?: React.ComponentType;
  };
  /** Hide field in admin */
  hidden?: boolean;
  /** Make field read-only */
  readOnly?: boolean;
  /** Conditional field display */
  condition?: (data: any, siblingData: any) => boolean;
}

type Validate = (
  value: any,
  args: {
    data: any;
    siblingData: any;
    user: User;
    operation: "create" | "update";
  }
) => true | string | Promise<true | string>;

Upload Configuration

File Upload Configuration

Comprehensive file upload and image processing configuration for collections with upload capabilities.

/**
 * Upload configuration for collections
 */
interface UploadConfig {
  /** Image size variants to generate */
  imageSizes?: ImageSize[];
  /** URL path for serving static files */
  staticURL: string;
  /** Directory path for storing files */
  staticDir: string;
  /** Disable local file storage (for cloud storage) */
  disableLocalStorage: boolean;
  /** Thumbnail configuration for admin */
  adminThumbnail?: string | GetAdminThumbnail;
  /** Allowed MIME types */
  mimeTypes?: string[];
  /** Express static file serving options */
  staticOptions?: ServeStaticOptions;
  /** Custom upload handlers */
  handlers?: UploadHandler[];
  /** Global image resize options */
  resizeOptions?: ResizeOptions;
  /** Global image format options */
  formatOptions?: ImageUploadFormatOptions;
}

/**
 * Image size configuration for automatic variants
 */
interface ImageSize {
  /** Size variant name */
  name: string;
  /** Image width */
  width?: number;
  /** Image height */
  height?: number;
  /** Resize fit mode */
  fit?: 'cover' | 'contain' | 'fill' | 'inside' | 'outside';
  /** Resize position/gravity */
  position?: 'top' | 'right top' | 'right' | 'right bottom' | 'bottom' | 'left bottom' | 'left' | 'left top' | 'center';
  /** Format options for this size */
  formatOptions?: ImageUploadFormatOptions;
  /** @deprecated Use position instead */
  crop?: string;
}

/**
 * Image format conversion options
 */
interface ImageUploadFormatOptions {
  /** Target image format */
  format: 'jpeg' | 'png' | 'webp' | 'avif' | 'tiff';
  /** Format-specific options */
  options?: {
    /** JPEG quality (1-100) */
    quality?: number;
    /** PNG compression level (0-9) */
    compressionLevel?: number;
    /** WebP quality (1-100) */
    quality?: number;
    /** Enable progressive encoding */
    progressive?: boolean;
  };
}

/**
 * Function to generate admin thumbnail URL
 */
type GetAdminThumbnail = (args: { doc: Record<string, unknown> }) => string;

/**
 * File data structure
 */
interface FileData {
  /** Original filename */
  filename: string;
  /** File size in bytes */
  filesize: number;
  /** MIME type */
  mimeType: string;
  /** Image width (for images) */
  width: number;
  /** Image height (for images) */
  height: number;
  /** Generated size variants */
  sizes: FileSizes;
}

/**
 * Generated image sizes
 */
interface FileSizes {
  [sizeName: string]: FileSize;
}

/**
 * Individual file size variant
 */
interface FileSize {
  /** Generated filename */
  filename: string;
  /** File size in bytes */
  filesize: number;
  /** MIME type */
  mimeType: string;
  /** Size variant name */
  name: string;
  /** Image width */
  width: number;
  /** Image height */
  height: number;
  /** Crop setting used */
  crop: string;
}

/**
 * Incoming file during upload
 */
interface File {
  /** File buffer data */
  data: Buffer;
  /** MIME type */
  mimetype: string;
  /** Original filename */
  name: string;
  /** File size in bytes */
  size: number;
}

Upload Configuration Examples:

// Basic image upload collection
const MediaCollection: CollectionConfig = {
  slug: "media",
  upload: {
    staticURL: "/media",
    staticDir: "media",
    disableLocalStorage: false,
    mimeTypes: ["image/jpeg", "image/png", "image/webp"],
    imageSizes: [
      {
        name: "thumbnail",
        width: 150,
        height: 150,
        fit: "cover",
        position: "center",
      },
      {
        name: "small",
        width: 400,
        height: 300,
        fit: "cover",
      },
      {
        name: "medium", 
        width: 800,
        height: 600,
        fit: "inside",
      },
      {
        name: "large",
        width: 1600,
        height: 1200,
        fit: "inside",
      },
    ],
    adminThumbnail: "thumbnail",
  },
  fields: [
    {
      name: "alt",
      type: "text",
      label: "Alt Text",
    },
  ],
};

// Advanced upload with format conversion
const AdvancedMediaCollection: CollectionConfig = {
  slug: "media",
  upload: {
    staticURL: "/media",
    staticDir: "media", 
    disableLocalStorage: false,
    mimeTypes: ["image/jpeg", "image/png", "image/webp", "image/avif"],
    formatOptions: {
      format: "webp",
      options: {
        quality: 80,
      },
    },
    imageSizes: [
      {
        name: "thumbnail",
        width: 150,
        height: 150,
        fit: "cover",
        formatOptions: {
          format: "webp",
          options: { quality: 70 },
        },
      },
      {
        name: "optimized",
        width: 1200,
        height: 800,
        fit: "inside",
        formatOptions: {
          format: "avif",
          options: { quality: 85 },
        },
      },
    ],
    adminThumbnail: ({ doc }) => {
      return doc.sizes?.thumbnail?.filename || doc.filename;
    },
  },
  fields: [
    {
      name: "alt",
      type: "text",
      required: true,
    },
    {
      name: "caption", 
      type: "textarea",
    },
  ],
};

// Cloud storage configuration (S3, etc.)
const CloudMediaCollection: CollectionConfig = {
  slug: "media",
  upload: {
    staticURL: "https://cdn.example.com/media",
    staticDir: "/tmp/uploads", // Temporary local directory
    disableLocalStorage: true, // Files stored in cloud
    handlers: [
      // Custom handlers for cloud upload
      s3UploadHandler,
      cloudinaryHandler,
    ],
    imageSizes: [
      {
        name: "thumbnail", 
        width: 200,
        height: 200,
      },
    ],
  },
  fields: [
    {
      name: "cloudinaryId",
      type: "text",
      hidden: true,
    },
  ],
};

Install with Tessl CLI

npx tessl i tessl/npm-payload

docs

authentication.md

configuration.md

core-operations.md

field-types.md

global-operations.md

index.md

preferences.md

version-control.md

tile.json