# Custom fields
Custom fields extend Strapi’s capabilities by adding new types of fields to content-types. Once created or installed, custom fields can be used in the Content-Types Builder and Content Manager just like built-in fields.
The present documentation is intended to custom fields creators: it describes which APIs and functions developers must use to create a new custom field. The user guide describes how to install and use custom fields from Strapi's admin panel.
Custom fields are a specific type of Strapi plugins that include both a server part and an admin panel part. Both parts should be registered separately before a custom field is usable in Strapi's admin panel.
✏️ NOTE
Once registered, custom fields can be used in models's schema.json
.
# Registering a custom field on the server
Strapi's server needs to be aware of all the custom fields to ensure that an attribute using a custom field is valid.
The strapi.customFields
object exposes a register()
method on the Strapi
instance. This method is used to register custom fields on the server during the plugin's server register lifecycle.
strapi.customFields.register()
registers one or several custom field(s) on the server by passing an object (or an array of objects) with the following parameters:
Parameter | Description | Type |
---|---|---|
name | The name of the custom field | String |
plugin (optional) | The name of the plugin creating the custom fields If omitted, the custom field is registered within the global namespace. | String |
type | The data type the custom field will use | String |
✏️ NOTE
Currently custom fields can not add new data types to Strapi and should use existing, built-in Strapi data types (e.g. string, number, JSON — see models documentation for the full list).
Example: Registering an example "color" custom field on the server:
// path: ./src/plugins/my-custom-field-plugin/strapi-server.js
module.exports = {
register({ strapi }) {
strapi.customFields.register({
name: 'color',
plugin: 'color-picker', // the custom
type: 'text',
});
},
};
# Registering a custom field in the admin panel
Custom fields must be registered in Strapi's admin panel to be available in the Content-type Builder and the Content Manager.
The app.customFields
object exposes a register()
method on the StrapiApp
instance. This method is used to register custom fields in the admin panel during the plugin's admin bootstrap lifecycle.
app.customFields.register()
registers one or several custom field(s) in the admin panel by passing an object (or an array of objects) with the following parameters:
Parameter | Description | Type |
---|---|---|
name | Name of the custom field | String |
pluginId (optional) | Name of the plugin creating the custom field If omitted, the custom field is registered within the global namespace. | String |
type | Existing Strapi data type the custom field will use | String |
icon (optional) | Icon for the custom field | React.ComponentType |
intlLabel | Translation for the name | IntlObject (opens new window) |
intlDescription | Translation for the description | IntlObject (opens new window) |
components | Components needed to display the custom field in the Content Manager (see components) | |
options (optional) | Options to be used by the Content-type Builder (see options) | Object |
Example: Registering an example "color" custom field in the admin panel:
// path: ./src/plugins/color-picker/strapi-server.js
register(app) {
app.customFields.register({
name: "color",
pluginId: "color-picker", // the custom field is created by a color-picker plugin
type: "text", // the color will be stored as text
intlLabel: {
id: "color-picker.color.label",
defaultMessage: "Color",
},
intlDescription: {
id: "color-picker.color.description",
defaultMessage: "Select any color",
}
icon: ColorIcon,
components: {
Input: async () => import(/* webpackChunkName: "input-component" */ "./Input"),
View: async () => import(/* webpackChunkName: "view-component" */ "./View"),
}
options: {
base: [
/*
Declare settings to be added to the "Base settings" section
of the field in the Content-Type Builder
*/
{
sectionTitle: { // Add a "Format" settings section
id: 'color-picker.color.section.format',
defaultMessage: 'Format',
},
items: [ // Add settings items to the section
{
/*
Add a "Color format" dropdown
to choose between 2 different format options
for the color value: hexadecimal or RGBA
*/
intlLabel: {
id: 'color-picker.color.format.label',
defaultMessage: 'Color format',
},
name: 'options.format',
type: 'select',
value: 'hex', // option selected by default
options: [ // List all available "Color format" options
{
key: 'hex',
value: 'hex',
metadatas: {
intlLabel: {
id: 'color-picker.color.format.hex',
defaultMessage: 'Hexadecimal',
},
},
},
{
key: 'rgba',
value: 'rgba',
metadatas: {
intlLabel: {
id: 'color-picker.color.format.rgba',
defaultMessage: 'RGBA',
},
},
},
],
},
],
},
],
advanced: [
/*
Declare settings to be added to the "Advanced settings" section
of the field in the Content-Type Builder
*/
],
validator: (args) => ({
'color-picker': yup.object().shape({
format: yup.string().oneOf(['hex', 'rgba']),
}),
}),
},
});
}
✏️ NOTE
Relations, components or dynamic zones can't be used as a custom field's type
parameter.
# Components
app.customFields.register()
must pass a components
object with 1 or 2 of the following components:
Component | Description |
---|---|
Input | React component to use in the Content Manager's edit view |
View | Read-only React component to use in the Content Manager's list view |
Example: Registering Input and View components imported from dedicated files:
// path: ./src/plugins/my-custom-field-plugin/strapi-server.js
register(app) {
app.customFields.register({
// …
components: {
Input: async () => import(/* webpackChunkName: "input-component" */ "./Input"),
View: async () => import(/* webpackChunkName: "view-component" */ "./View"),
}
// …
});
}
# Options
app.customFields.register()
can pass an additional options
object with the following parameters:
Options parameter | Description | Type |
---|---|---|
base | Settings available in the Base settings tab of the field in the Content-type Builder | Object or Object[] |
advanced | Settings available in the Advanced settings tab of the field in the Content-type Builder | Object or Object[] |
validator | Validator function returning an object, used to sanitize input | Function |
Both base
and advanced
settings accept an object or an array of objects, each object being a settings section. Each settings section must include:
- a
sectionTitle
to declare the title of the section as aReact IntlObject
- and a list of
items
as an array of objects.
Each object in the items
array can contain the following parameters:
Items parameter | Description | Type |
---|---|---|
intlLabel | Translation for the abel of the setting item | IntlObject (opens new window) |
name | Name of the setting item Must use the options.setting-name format. | String |
type | ? | String |
value | ? | String |
options | ? | Array of Objects |
Example: Declaring settings for an example "color" custom field:
// path: ./src/plugins/my-custom-field-plugin/strapi-server.js
register(app) {
app.customFields.register({
// …
options: {
base: [
{
sectionTitle: {
id: 'color-picker.color.section.format',
defaultMessage: 'Format',
},
items: [
{
intlLabel: {
id: 'color-picker.color.format.label',
defaultMessage: 'Color format',
},
name: 'options.format',
type: 'select',
value: 'hex',
options: [
{
key: 'hex',
value: 'hex',
metadatas: {
intlLabel: {
id: 'color-picker.color.format.hex',
defaultMessage: 'Hexadecimal',
},
},
},
{
key: 'rgba',
value: 'rgba',
metadatas: {
intlLabel: {
id: 'color-picker.color.format.rgba',
defaultMessage: 'RGBA',
},
},
},
],
},
],
},
],
advanced: [],
validator: (args) => ({
'color-picker': yup.object().shape({
format: yup.string().oneOf(['hex', 'rgba']),
}),
}),
},
});
}
✏️ NOTE
When extending a custom field’s base and advanced forms in the Content-type Builder, it is not currently possible to import custom input components.