obsidian/wiki/payloadcms/fields-json.md
2026-05-15 15:29:41 +01:00

4.2 KiB

title aliases tags sources created updated
JSON Field
payload-json-field
json-field-payload
payloadcms
fields
json
validation
monaco
raw/fields__json.md
2026-05-15 2026-05-15

The JSON Field stores raw JSON (object/array/primitive) directly in the database — unlike the wiki/payloadcms/fields-code which stores a plain string. The Admin Panel shows a Monaco editor with full JSON syntax highlighting.

Config

import type { Field } from 'payload'

export const MyJSONField: Field = {
  name: 'customerJSON',
  type: 'json',
  required: true,
}

Config Options

Option Description
name * DB property name
jsonSchema JSON Schema for validation + editor typeahead
label Admin Panel label (string or i18n object)
unique DB-level unique index
index DB index for faster queries
validate Custom validation function (client + server)
saveToJWT Include in JWT if field is top-level in auth collection
hooks Field lifecycle hooks
access Field-level access control
hidden Hide from all APIs + Admin (still saved to DB)
defaultValue Default value
localized Enable per-locale content
required Make field mandatory
virtual Disable DB column (true) or link to a relationship (string path)
typescriptSchema Override generated TS type with JSON schema
admin.editorOptions Pass options to Monaco editor

JSON Schema Validation

Attach a jsonSchema to enable:

  • Editor typeahead — Monaco auto-completes properties and enums in the Admin Panel
  • Save-time validation — invalid documents cannot be saved

Local Schema

{
  name: 'customerJSON',
  type: 'json',
  jsonSchema: {
    uri: 'a://b/foo.json',          // required (any unique URI)
    fileMatch: ['a://b/foo.json'],   // required (must match uri)
    schema: {
      type: 'object',
      properties: {
        foo: { enum: ['bar', 'foobar'] },
      },
    },
  },
}
// {"foo": "bar"} ✓   {"foo": "other"} ✗

Remote Schema

{
  name: 'customerJSON',
  type: 'json',
  jsonSchema: {
    uri: 'https://example.com/customer.schema.json',
    fileMatch: ['https://example.com/customer.schema.json'],
    // schema omitted — Payload fetches it from the URL
  },
}

Gotcha: If the remote URL is not publicly accessible, Payload will fail to fetch the schema. Embed the schema inline or import it from a local file.

JSON vs Code Field

| | JSON Field | wiki/payloadcms/fields-code | |--|------------|------------| | DB storage | Native JSON / JSONB | Plain string | | Editor | Monaco (JSON mode) | Monaco (any language) | | Validation | JSON Schema supported | Custom validate only | | Use case | Structured data, API configs, metadata | Source code snippets, templates |

Custom Components

Both Server and Client component patterns are supported. Import JSONField from @payloadcms/ui:

// Server
import { JSONField } from '@payloadcms/ui'
import type { JSONFieldServerComponent } from 'payload'

export const CustomJSONFieldServer: JSONFieldServerComponent = ({
  clientField, path, schemaPath, permissions,
}) => <JSONField field={clientField} path={path} schemaPath={schemaPath} permissions={permissions} />

// Client
'use client'
import type { JSONFieldClientComponent } from 'payload'
export const CustomJSONFieldClient: JSONFieldClientComponent = (props) => <JSONField {...props} />

Key Takeaways

  • type: 'json' stores actual JSON in the DB (not a stringified value) — use this when you need to query or index the JSON contents later
  • jsonSchema unlocks both Monaco typeahead in the Admin Panel and automatic save-time validation — add it for any structured config or metadata field
  • For remote schemas: if the URL is not public, embed the schema inline to avoid fetch failures
  • admin.editorOptions accepts the full Monaco EditorOptions object for advanced editor configuration
  • Use wiki/payloadcms/fields-code instead when storing source code, templates, or any non-JSON string that just needs syntax highlighting

Sources