All Release Notes

Introduced Product Tailoring in beta

6 March 2024
Composable Commerce
HTTP API
New feature
Product catalogGraphQL

We introduced Product Tailoring in public beta, a new feature designed to enhance your product offerings across different markets. With Product Tailoring, you can customize product details like names, descriptions, slugs, and meta fields for specific brands or countries, using Stores to model these market segments.

By defining tailored product data, you can adapt product information to appeal to different markets and, in turn, increase visibility, customer loyalty, and order volumes.

Changes:

  • [API] Added Product Tailoring API.
  • [API] Added Product Tailoring Messages.
  • [GraphQL API] Added following types to the GraphQL schema: ProductTailoringDraft, ProductTailoring, ProductTailoringCreated, ProductTailoringData, ProductTailoringDeleted, ProductTailoringDescriptionSet, ProductTailoringNameSet, ProductTailoringPublished, ProductTailoringQueryResult, ProductTailoringSlugSet, ProductTailoringUnpublished, ProductTailoringUpdateAction, PublishTailoring, SetProductTailoringDescription, SetProductTailoringMetaAttributes, SetProductTailoringMetaDescription, SetProductTailoringMetaKeywords, SetProductTailoringMetaTitle, SetProductTailoringName, SetProductTailoringSlug, UnpublishTailoring.
  • [GraphQL API] Added fields productTailoring and productTailoringList to the InStore type.
  • [GraphQL API] Added fields productTailoring and productTailoringList to the Query type.
  • [GraphQL API] Added fields createProductTailoring, updateProductTailoring, and deleteProductTailoring to the Mutation type.

The following changes were introduced in terms of GraphQL SDL:

extend type InStore {
"BETA: This feature can be subject to change and should be used carefully in production. https://docs.commercetools.com/api/contract#public-beta"
productTailoring(
"Queries with specified ID"
id: String,
"Queries with specified key"
key: String,
"Queries with specified Product ID"
productId: String,
"Queries with specified Product key"
productKey: String): ProductTailoring
"BETA: This feature can be subject to change and should be used carefully in production. https://docs.commercetools.com/api/contract#public-beta"
productTailoringList(where: String, sort: [String!], limit: Int, offset: Int): ProductTailoringQueryResult!
}
extend type Query {
"BETA: This feature can be subject to change and should be used carefully in production. https://docs.commercetools.com/api/contract#public-beta"
productTailoring(
"Queries with specified ID"
id: String,
"Queries with specified key"
key: String,
"Queries with specified Product ID"
productId: String,
"Queries with specified Product key"
productKey: String,
"The mutation is only performed if the resource is part of the store. Can be used with store-specific OAuth permissions."
storeKey: KeyReferenceInput): ProductTailoring
"BETA: This feature can be subject to change and should be used carefully in production. https://docs.commercetools.com/api/contract#public-beta"
productTailoringList(where: String, sort: [String!], limit: Int, offset: Int): ProductTailoringQueryResult!
}
extend type Mutation {
"BETA: This feature can be subject to change and should be used carefully in production. https://docs.commercetools.com/api/contract#public-beta"
createProductTailoring(
"The mutation is only performed if the resource is part of the store. Can be used with store-specific OAuth permissions."
storeKey: KeyReferenceInput, draft: ProductTailoringDraft!): ProductTailoring
"BETA: This feature can be subject to change and should be used carefully in production. https://docs.commercetools.com/api/contract#public-beta"
deleteProductTailoring(
"The mutation is only performed if the resource is part of the store. Can be used with store-specific OAuth permissions."
storeKey: KeyReferenceInput,
"Queries with specified Product ID"
productId: String,
"Queries with specified Product key"
productKey: String,
"Queries with specified ID"
id: String,
"Queries with specified key"
key: String, version: Long!): ProductTailoring
"BETA: This feature can be subject to change and should be used carefully in production. https://docs.commercetools.com/api/contract#public-beta"
updateProductTailoring(
"The mutation is only performed if the resource is part of the store. Can be used with store-specific OAuth permissions."
storeKey: KeyReferenceInput,
"Queries with specified Product ID"
productId: String,
"Queries with specified Product key"
productKey: String,
"Queries with specified ID"
id: String,
"Queries with specified key"
key: String, actions: [ProductTailoringUpdateAction!]!, version: Long!): ProductTailoring
}
"BETA: This feature can be subject to change and should be used carefully in production. https://docs.commercetools.com/api/contract#public-beta"
input ProductTailoringDraft {
product: ResourceIdentifierInput!
name: [LocalizedStringItemInputType!]
key: String
description: [LocalizedStringItemInputType!]
slug: [LocalizedStringItemInputType!]
metaTitle: [LocalizedStringItemInputType!]
metaDescription: [LocalizedStringItemInputType!]
metaKeywords: [LocalizedStringItemInputType!]
publish: Boolean
}
"BETA: This feature can be subject to change and should be used carefully in production. https://docs.commercetools.com/api/contract#public-beta"
type ProductTailoring implements Versioned {
key: String
productRef: Reference!
product: Product
storeRef: KeyReference!
store: Store
current: ProductTailoringData
staged: ProductTailoringData
published: Boolean!
hasStagedChanges: Boolean!
id: String!
version: Long!
createdAt: DateTime!
lastModifiedAt: DateTime!
createdBy: Initiator
lastModifiedBy: Initiator
}
type ProductTailoringCreated implements MessagePayload {
publish: Boolean!
storeRef: KeyReference!
productRef: Reference!
key: String
productKey: String
name(
"String is defined for different locales. This argument specifies the desired locale."
locale: Locale,
"List of languages the client is able to understand, and which locale variant is preferred."
acceptLanguage: [Locale!]): String
description(
"String is defined for different locales. This argument specifies the desired locale."
locale: Locale,
"List of languages the client is able to understand, and which locale variant is preferred."
acceptLanguage: [Locale!]): String
slug(
"String is defined for different locales. This argument specifies the desired locale."
locale: Locale,
"List of languages the client is able to understand, and which locale variant is preferred."
acceptLanguage: [Locale!]): String
nameAllLocales: [LocalizedString!]
slugAllLocales: [LocalizedString!]
descriptionAllLocales: [LocalizedString!]
type: String!
}
"BETA: This feature can be subject to change and should be used carefully in production. https://docs.commercetools.com/api/contract#public-beta"
type ProductTailoringData {
name(
"String is defined for different locales. This argument specifies the desired locale."
locale: Locale,
"List of languages the client is able to understand, and which locale variant is preferred."
acceptLanguage: [Locale!]): String
nameAllLocales: [LocalizedString!]
description(
"String is defined for different locales. This argument specifies the desired locale."
locale: Locale,
"List of languages the client is able to understand, and which locale variant is preferred."
acceptLanguage: [Locale!]): String
descriptionAllLocales: [LocalizedString!]
slug(
"String is defined for different locales. This argument specifies the desired locale."
locale: Locale,
"List of languages the client is able to understand, and which locale variant is preferred."
acceptLanguage: [Locale!]): String
slugAllLocales: [LocalizedString!]
metaTitle(
"String is defined for different locales. This argument specifies the desired locale."
locale: Locale,
"List of languages the client is able to understand, and which locale variant is preferred."
acceptLanguage: [Locale!]): String
metaTitleAllLocales: [LocalizedString!]
metaDescription(
"String is defined for different locales. This argument specifies the desired locale."
locale: Locale,
"List of languages the client is able to understand, and which locale variant is preferred."
acceptLanguage: [Locale!]): String
metaDescriptionAllLocales: [LocalizedString!]
metaKeywords(
"String is defined for different locales. This argument specifies the desired locale."
locale: Locale,
"List of languages the client is able to understand, and which locale variant is preferred."
acceptLanguage: [Locale!]): String
metaKeywordsAllLocales: [LocalizedString!]
}
type ProductTailoringDeleted implements MessagePayload {
storeRef: KeyReference!
productRef: Reference!
productKey: String
type: String!
}
type ProductTailoringDescriptionSet implements MessagePayload {
storeRef: KeyReference!
productRef: Reference!
productKey: String
description(
"String is defined for different locales. This argument specifies the desired locale."
locale: Locale,
"List of languages the client is able to understand, and which locale variant is preferred."
acceptLanguage: [Locale!]): String
oldDescription(
"String is defined for different locales. This argument specifies the desired locale."
locale: Locale,
"List of languages the client is able to understand, and which locale variant is preferred."
acceptLanguage: [Locale!]): String
descriptionAllLocales: [LocalizedString!]
oldDescriptionAllLocales: [LocalizedString!]
type: String!
}
type ProductTailoringNameSet implements MessagePayload {
storeRef: KeyReference!
productRef: Reference!
productKey: String
name(
"String is defined for different locales. This argument specifies the desired locale."
locale: Locale,
"List of languages the client is able to understand, and which locale variant is preferred."
acceptLanguage: [Locale!]): String
oldName(
"String is defined for different locales. This argument specifies the desired locale."
locale: Locale,
"List of languages the client is able to understand, and which locale variant is preferred."
acceptLanguage: [Locale!]): String
nameAllLocales: [LocalizedString!]
oldNameAllLocales: [LocalizedString!]
type: String!
}
type ProductTailoringPublished implements MessagePayload {
storeRef: KeyReference!
productRef: Reference!
productKey: String
type: String!
}
type ProductTailoringQueryResult {
offset: Int!
count: Int!
total: Long!
exists: Boolean!
results: [ProductTailoring!]!
}
type ProductTailoringSlugSet implements MessagePayload {
storeRef: KeyReference!
productRef: Reference!
productKey: String
slug(
"String is defined for different locales. This argument specifies the desired locale."
locale: Locale,
"List of languages the client is able to understand, and which locale variant is preferred."
acceptLanguage: [Locale!]): String
oldSlug(
"String is defined for different locales. This argument specifies the desired locale."
locale: Locale,
"List of languages the client is able to understand, and which locale variant is preferred."
acceptLanguage: [Locale!]): String
slugAllLocales: [LocalizedString!]
oldSlugAllLocales: [LocalizedString!]
type: String!
}
type ProductTailoringUnpublished implements MessagePayload {
storeRef: KeyReference!
productRef: Reference!
productKey: String
type: String!
}
"BETA: This feature can be subject to change and should be used carefully in production. https://docs.commercetools.com/api/contract#public-beta"
input ProductTailoringUpdateAction {
publish: PublishTailoring
unpublish: UnpublishTailoring
setDescription: SetProductTailoringDescription
setMetaAttributes: SetProductTailoringMetaAttributes
setMetaDescription: SetProductTailoringMetaDescription
setMetaKeywords: SetProductTailoringMetaKeywords
setMetaTitle: SetProductTailoringMetaTitle
setName: SetProductTailoringName
setSlug: SetProductTailoringSlug
}
input PublishTailoring {
dummy: String
}
input SetProductTailoringDescription {
description: [LocalizedStringItemInputType!]
staged: Boolean = true
}
input SetProductTailoringMetaAttributes {
metaDescription: [LocalizedStringItemInputType!]
metaKeywords: [LocalizedStringItemInputType!]
metaTitle: [LocalizedStringItemInputType!]
staged: Boolean = true
}
input SetProductTailoringMetaDescription {
metaDescription: [LocalizedStringItemInputType!]
staged: Boolean = true
}
input SetProductTailoringMetaKeywords {
metaKeywords: [LocalizedStringItemInputType!]
staged: Boolean = true
}
input SetProductTailoringMetaTitle {
metaTitle: [LocalizedStringItemInputType!]
staged: Boolean = true
}
input SetProductTailoringName {
name: [LocalizedStringItemInputType!]
staged: Boolean = true
}
input SetProductTailoringSlug {
slug: [LocalizedStringItemInputType!]
staged: Boolean = true
}
input UnpublishTailoring {
dummy: String
}