Recipe — Custom types & fields
commercetools custom fields are defined by a Type. This recipe creates a type
and attaches custom fields to a customer — all through the API.
import { expect, test } from 'vitest'import { apiRoot } from '../test/ct-client'
test('customer carries custom fields', async () => { // 1. Define a Type targeting customers await apiRoot .types() .post({ body: { key: 'customer-extra', name: { en: 'Customer extra fields' }, resourceTypeIds: ['customer'], fieldDefinitions: [ { name: 'loyaltyId', label: { en: 'Loyalty ID' }, required: false, type: { name: 'String' }, inputHint: 'SingleLine', }, ], }, }) .execute()
// 2. Create a customer that uses the type const { body: created } = await apiRoot .customers() .post({ body: { email: 'jane@example.com', password: 's3cret', custom: { type: { typeId: 'type', key: 'customer-extra' }, fields: { loyaltyId: 'LOYAL-42' }, }, }, }) .execute()
// 3. Read it back, expanding the type reference const { body: customer } = await apiRoot .customers() .withId({ ID: created.customer.id }) .get({ queryArgs: { expand: ['custom.type'] } }) .execute()
expect(customer.custom?.fields.loyaltyId).toBe('LOYAL-42') expect(customer.custom?.type.obj?.key).toBe('customer-extra')})Step 3 uses commercetools
reference expansion
to inline the type reference.