db:migrate.
Where this sits in the stack. Custom Fields is a Mercur module (
@mercurjs/core/modules/custom-fields) layered on top of Medusa’s standard module-link system — it generates the side table, the link, and the schema for you. It’s the lightest way to add data to an entity.When to use Custom Fields
How it works
The Custom Fields module creates a separate table for each entity you extend (e.g.product_custom_fields). Each table is linked back to the original entity via a foreign key with a unique constraint, ensuring a one-to-one relationship. The module automatically registers these links so you can query custom fields through Medusa’s standard remote query.
Set up custom fields
Define your fields in medusa-config.ts
Register the Custom Fields module and describe your fields in the
customFields option:medusa-config.ts
Supported field types
| Type | Description |
|---|---|
string | Short text |
text | Long text |
integer | Whole number |
float | Decimal number |
boolean | True/false |
date | Date only |
time | Time only |
datetime | Date and time |
json | JSON object |
array | Array of values |
enum | One of a predefined set of values (requires enum array) |
Field options
| Option | Type | Default | Description |
|---|---|---|---|
nullable | boolean | true | Whether the field can be null |
defaultValue | any | null | Default value for the field |
enum | string[] | — | Required for enum type. List of allowed values |
Using the service directly
The Custom Fields module exposes a service withupsert, delete, and list methods. You can use these in your own workflows and API routes:
upsert method accepts either a single object or an array. If a record already exists for the given entity ID, it updates it; otherwise, it creates a new one.
Workflow steps
The module ships with two workflow steps you can compose into your own workflows:upsertCustomFieldsStep— Takes{ alias, data }wherealiasis the entity name (e.g."product") anddatacontains the entity ID and field values.deleteCustomFieldsStep— Takes{ alias, ids }to soft-delete custom field records by their IDs.
FAQ
Can I add or change fields after the first migration?
Can I add or change fields after the first migration?
Yes — edit the
customFields config and run db:migrate again; the module updates the side table’s schema. Removing a field from config stops exposing it; treat destructive column changes with the same care as any schema migration.How do vendors or admins edit these values from the panels?
How do vendors or admins edit these values from the panels?
Through your own UI: add a page or re-compose an existing one (extending panels) and call an API route that uses the service’s
upsert — or compose upsertCustomFieldsStep into a workflow behind a custom route.Can one entity have multiple custom-field records?
Can one entity have multiple custom-field records?
No — the side table has a unique constraint on the parent ID, enforcing one-to-one. If you need many records per parent, that’s a custom module, not custom fields.
Next steps
Add a custom API route
Expose your custom fields through a typed endpoint.
Extend a workflow
Write custom fields from inside existing business flows.