Skip to content

Relation Field

The Relation field type enables users to create relationships between entries in different collections within the CMS. There are two types of relations supported, depending on the target collection type:

User Interface

Editor

Radio buttons (single select) or checkboxes (multi select) for choosing related entries from another collection. If there are many entries, a dropdown with search functionality will be used instead. Use the dropdown_threshold option to customize when to switch to the dropdown UI.

Future Plans

Currently, it’s not possible to create new related entries directly from the Relation field UI. We plan to add this feature in future releases.

Preview

A string or a list of strings representing the selected related entries, formatted according to the display_fields option.

Data Type

A string or an array of strings, depending on whether the multiple option is set to true or false. Each string represents the value of the related entry as defined by the value_field option.

In some cases, it can also be a number or an array of numbers if the value_field of the related collection is of a numeric type, like an ID.

If the required option is set to false and no related entries are selected, the value will be null for single select or an empty array for multi select.

Cascading unimplemented

Cascade updates and deletions like relational databases are not yet supported. If a related entry is updated or deleted, the Relation field will not automatically reflect those changes. Users must manually update the Relation field values to maintain data integrity. We plan to add cascading support in the near future.

Data Validation

  • If the required option is set to true, at least one related entry must be selected.
  • If the multiple option is enabled, the number of selected entries must be between the min and max limits, if specified.

Options

In addition to the common field options, the Relation field supports the following options:

Required Options

widget

  • Type: string
  • Default: string

Must be set to relation.

collection

  • Type: string
  • Default: undefined

The name of the collection to relate to. This collection must exist in the CMS configuration, and can be either an entry collection or a file collection. If the target collection is a file collection, the file option must also be specified.

Optional Options

Breaking changes from Netlify/Decap CMS

Sveltia CMS does not support the deprecated camelCase valueField, displayFields and searchFields options. Use value_field, display_fields and search_fields instead.

The options_length option is also not supported in Sveltia CMS because the performance has been improved significantly.

file

  • Type: string
  • Default: undefined

The name of a file within the target file collection to relate to. Required if the target collection is a file collection.

value_field

  • Type: string
  • Default: {{slug}}

The field from the related collection to use as the value for the relation. This field’s value will be stored in the entry using the Relation field. It can be one of the following:

  • {{slug}}: Use the slug of the related entry.
  • A field name from the related collection, e.g., id or title.
  • A template string that references fields in the related collection using the syntax {{field_name}}. For example, {{fields.id}} or {{fields.title}}.

The {{locale}} template tag can be used to include the current locale in the value field, e.g. {{locale}}/{{slug}}, which is useful for i18n support.

When using template strings, keep the following in mind:

  • A field named slug must be prefixed with fields. like {{fields.slug}} to avoid ambiguity with the special {{slug}} variable.
  • Nested fields can also be referenced using dot notation, e.g., {{author.name}}.
  • To reference list items, use a wildcard * for the index, e.g., {{tags.*}} or {{gallery.*.image}}. This works for a list field with the field or fields option.

The value field must be unique across all entries in the related collection to avoid conflicts. For example, using {{title}} as the value field is not recommended unless you can guarantee that all titles are unique. That’s why the default is {{slug}}, which is unique by design.

display_fields

  • Type: array of strings
  • Default: ["title"] if value_field is {{slug}}, otherwise the value of value_field option

The fields from the related collection to display in the Relation field UI when selecting related entries. This should be an array of field names. The values of these fields will be concatenated and shown as the label for each related entry.

String templates can be used to customize the display format. For example, to show both first and last names from separate fields, you can use either of the following:

yaml
display_fields: ['{{first_name}} {{last_name}}']
toml
display_fields = ["{{first_name}} {{last_name}}"]
json
{
  "display_fields": ["{{first_name}} {{last_name}}"]
}
js
{
  display_fields: ["{{first_name}} {{last_name}}"],
}
yaml
display_fields: ['first_name', 'last_name']
toml
display_fields = ["first_name", "last_name"]
json
{
  "display_fields": ["first_name", "last_name"]
}
js
{
  display_fields: ["first_name", "last_name"],
}

search_fields

  • Type: array of strings
  • Default: value of display_fields option

The fields from the related collection to search against when filtering related entries in the Relation field UI. This should be an array of field names. By default, it uses the same fields as specified in the display_fields option.

default

  • Type: string, number, array of strings, or array of numbers
  • Default: null or []

The default value for the field. Should be a string or number for single select, or an array of strings or numbers for multi select, depending on the multiple option.

  • Type: integer
  • Default: 5

The number of related entries at which to switch from radio buttons/checkboxes to a dropdown with search functionality. If the number of entries in the target collection is greater than this threshold, a dropdown will be used.

multiple

  • Type: boolean
  • Default: false

Whether to allow selecting multiple related entries.

min

  • Type: integer
  • Default: 0

The minimum number of related entries required. This enables validation to ensure that users select at least this many entries. Ignored if multiple is set to false.

max

  • Type: integer
  • Default: Infinity

The maximum number of related entries allowed. This enables validation to prevent users from selecting more than this many entries. Ignored if multiple is set to false.

filters

  • Type: array of filter objects
  • Default: []

An array of filter objects to limit the related entries shown in the Relation field UI. Each filter object should have the following properties:

  • field: The field name in the related collection to filter on.
  • values: An array of strings or numbers representing the values to match for the specified field

Example:

yaml
filters:
  - field: draft
    values: [false]
  - field: category
    values: ['news', 'updates']
toml
[[filters]]
field = "draft"
values = [false]

[[filters]]
field = "category"
values = ["news", "updates"]
json
{
  "filters": [
    {
      "field": "draft",
      "values": [false]
    },
    {
      "field": "category",
      "values": ["news", "updates"]
    }
  ]
}
js
{
  filters: [
    {
      field: 'draft',
      values: [false],
    },
    {
      field: 'category',
      values: ['news', 'updates'],
    },
  ],
}

Examples

Selecting Entries from an Entry Collection

Assuming you have the following entry collection named categories:

yaml
collections:
  - name: categories
    label: Categories
    folder: content/categories
    fields:
      - name: title
        label: Title
        widget: string
      - name: slug
        label: Slug
        widget: string
      - name: description
        label: Description
        widget: text
toml
[[collections]]
name = "categories"
label = "Categories"
folder = "content/categories"
[[collections.fields]]
name = "title"
label = "Title"
widget = "string"
[[collections.fields]]
name = "slug"
label = "Slug"
widget = "string"
[[collections.fields]]
name = "description"
label = "Description"
widget = "text"
json
{
  "collections": [
    {
      "name": "categories",
      "label": "Categories",
      "folder": "content/categories",
      "fields": [
        {
          "name": "title",
          "label": "Title",
          "widget": "string"
        },
        {
          "name": "slug",
          "label": "Slug",
          "widget": "string"
        },
        {
          "name": "description",
          "label": "Description",
          "widget": "text"
        }
      ]
    }
  ]
}
js
{
  collections: [
    {
      name: 'categories',
      label: 'Categories',
      folder: 'content/categories',
      fields: [
        {
          name: 'title',
          label: 'Title',
          widget: 'string',
        },
        {
          name: 'slug',
          label: 'Slug',
          widget: 'string',
        },
        {
          name: 'description',
          label: 'Description',
          widget: 'text',
        },
      ],
    },
  ],
}

You can create a Relation field in another collection to select a single category:

yaml
fields:
  - name: category
    label: Category
    widget: relation
    collection: categories
    value_field: slug
    display_fields: [title]
    search_fields: [title, description]
toml
[[fields]]
name = "category"
label = "Category"
widget = "relation"
collection = "categories"
value_field = "slug"
display_fields = ["title"]
search_fields = ["title", "description"]
json
{
  "fields": [
    {
      "name": "category",
      "label": "Category",
      "widget": "relation",
      "collection": "categories",
      "value_field": "slug",
      "display_fields": ["title"],
      "search_fields": ["title", "description"]
    }
  ]
}
js
{
  fields: [
    {
      name: 'category',
      label: 'Category',
      widget: 'relation',
      collection: 'categories',
      value_field: 'slug',
      display_fields: ['title'],
      search_fields: ['title', 'description'],
    },
  ],
}

Output example when the selected category has a slug of news:

yaml
category: news
toml
category = "news"
json
{
  "category": "news"
}

Referencing a File in a File Collection, Multiple Select

Assuming you have the following cities file in a data file collection:

yaml
collections:
  - name: data
    label: Data
    files:
      - name: locations
        label: Locations
        file: data/locations.yaml
        fields:
          - name: cities
            label: Cities
            widget: list
            fields:
              - name: name
                label: Name
                widget: string
              - name: country
                label: Country
                widget: string
toml
[[collections]]
name = "data"
label = "Data"
[[collections.files]]
name = "locations"
label = "Locations"
file = "data/locations.yaml"
[[collections.files.fields]]
name = "cities"
label = "Cities"
widget = "list"
[[collections.files.fields.fields]]
name = "name"
label = "Name"
widget = "string"
[[collections.files.fields.fields]]
name = "country"
label = "Country"
widget = "string"
json
{
  "collections": [
    {
      "name": "data",
      "label": "Data",
      "files": [
        {
          "name": "locations",
          "label": "Locations",
          "file": "data/locations.yaml",
          "fields": [
            {
              "name": "cities",
              "label": "Cities",
              "widget": "list",
              "fields": [
                {
                  "name": "name",
                  "label": "Name",
                  "widget": "string"
                },
                {
                  "name": "country",
                  "label": "Country",
                  "widget": "string"
                }
              ]
            }
          ]
        }
      ]
    }
  ]
}
js
{
  collections: [
    {
      name: 'data',
      label: 'Data',
      files: [
        {
          name: 'locations',
          label: 'Locations',
          file: 'data/locations.yaml',
          fields: [
            {
              name: 'cities',
              label: 'Cities',
              widget: 'list',
              fields: [
                {
                  name: 'name',
                  label: 'Name',
                  widget: 'string',
                },
                {
                  name: 'country',
                  label: 'Country',
                  widget: 'string',
                },
              ],
            },
          ],
        },
      ],
    },
  ],
}

You can create a Relation field in another collection to select multiple cities from the locations file:

yaml
fields:
  - name: favorite_cities
    label: Favorite Cities
    widget: relation
    collection: data
    file: locations
    multiple: true
    min: 1
    max: 3
    value_field: '{{cities.*.name}}'
    display_fields: ['{{cities.*.name}}, {{cities.*.country}}']
    search_fields: ['{{cities.*.name}}']
toml
[[fields]]
name = "favorite_cities"
label = "Favorite Cities"
widget = "relation"
collection = "data"
file = "locations"
multiple = true
min = 1
max = 3
value_field = "{{cities.*.name}}"
display_fields = ["{{cities.*.name}}, {{cities.*.country}}"]
search_fields = ["{{cities.*.name}}"]
json
{
  "fields": [
    {
      "name": "favorite_cities",
      "label": "Favorite Cities",
      "widget": "relation",
      "collection": "data",
      "file": "locations",
      "multiple": true,
      "min": 1,
      "max": 3,
      "value_field": "{{cities.*.name}}",
      "display_fields": ["{{cities.*.name}}, {{cities.*.country}}"],
      "search_fields": ["{{cities.*.name}}"]
    }
  ]
}
js
{
  fields: [
    {
      name: 'favorite_cities',
      label: 'Favorite Cities',
      widget: 'relation',
      collection: 'data',
      file: 'locations',
      multiple: true,
      min: 1,
      max: 3,
      value_field: '{{cities.*.name}}',
      display_fields: ['{{cities.*.name}}, {{cities.*.country}}'],
      search_fields: ['{{cities.*.name}}'],
    },
  ],
}

Note that a wildcard (*) is used in the value_field, display_fields, and search_fields options to reference list items within the cities field.

Output example when the selected favorite cities are “San Francisco”, “Tokyo”, and “Paris”:

yaml
favorite_cities:
  - San Francisco
  - Tokyo
  - Paris
toml
favorite_cities = ["San Francisco", "Tokyo", "Paris"]
json
{
  "favorite_cities": ["San Francisco", "Tokyo", "Paris"]
}

Released under the MIT License.