--- title: "JSON Field" aliases: [payload-json-field, json-field-payload] tags: [payloadcms, fields, json, validation, monaco] sources: [raw/fields__json.md] created: 2026-05-15 updated: 2026-05-15 --- The JSON Field stores raw JSON (object/array/primitive) directly in the database — unlike the [[wiki/payloadcms/fields-code|Code Field]] which stores a plain string. The Admin Panel shows a Monaco editor with full JSON syntax highlighting. ## Config ```ts 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 ```ts { 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 ```ts { 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|Code Field]] | |--|------------|------------| | 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`: ```tsx // Server import { JSONField } from '@payloadcms/ui' import type { JSONFieldServerComponent } from 'payload' export const CustomJSONFieldServer: JSONFieldServerComponent = ({ clientField, path, schemaPath, permissions, }) => // Client 'use client' import type { JSONFieldClientComponent } from 'payload' export const CustomJSONFieldClient: JSONFieldClientComponent = (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|Code Field]] instead when storing source code, templates, or any non-JSON string that just needs syntax highlighting ## Sources - [Payload CMS — JSON Field docs](https://payloadcms.com/docs/fields/json) - Raw file: `raw/fields__json.md`