Loading...
Loading...
Apply when designing VTEX IO configuration apps with the configuration builder or when a service app must receive structured configuration through runtime context. Covers the separation between service apps and configuration apps, schema.json and configuration.json, settingsType, and reading injected configuration through ctx.vtex.settings. Use for shared service configuration, decoupled configuration lifecycle, or reviewing whether app settings should be replaced by a configuration app.
npx skill4agent add vtexdocs/ai-skills vtex-io-service-configuration-appsconfigurationconfigurationctx.vtex.settingssettingsSchemacontentSchemas.jsonnodegraphqlconfigurationmanifest.jsonconfiguration/schema.jsonctx.vtex.settingsnodegraphqlconfigurationconfiguration<service-app>/configuration.jsonsettingsType: "workspace"node/service.json@settingsconfiguration/configurationshipping-servicevendor.shipping-serviceconfiguration.jsonctx.vtex.settingsctx.vtex.settingssettingsSchemaread-workspace-appsadditionalProperties: falsedefinitions$refsettingsType: "workspace"node/service.json@settingssettingsType@settings{
"routes": {
"status": {
"path": "/_v/status/:code",
"public": true,
"settingsType": "workspace"
}
}
}{
"routes": {
"status": {
"path": "/_v/status/:code",
"public": true
}
}
}configuration/schema.jsonconfiguration.json{
"$schema": "http://json-schema.org/draft-07/schema#",
"$ref": "#/definitions/ServiceConfiguration",
"definitions": {
"ServiceConfiguration": {
"type": "object",
"properties": {
"bank": {
"type": "object",
"properties": {
"account": { "type": "string" },
"workspace": { "type": "string", "default": "master" },
"version": { "type": "string" },
"kycVersion": { "type": "string" },
"payoutVersion": { "type": "string" },
"host": { "type": "string" }
},
"required": ["account", "version", "kycVersion", "payoutVersion", "host"],
"additionalProperties": false
}
},
"required": ["bank"],
"additionalProperties": false
}
}
}{
"anything": true
}ctx.vtex.settingssettingsType@settingsctx.vtex.settingsexport async function handleStatus(ctx: Context) {
const settings = ctx.vtex.settings
const code = ctx.vtex.route.params.code
const status = resolveStatus(code, settings)
ctx.body = { status }
}export async function handleStatus(ctx: Context) {
const settings = await ctx.clients.partnerApi.getSettings()
ctx.body = settings
}configuration/schema.jsonconfiguration.jsonctx.vtex.settingsvendor.shipping-servicemanifest.json{
"vendor": "vendor",
"name": "shipping-service",
"version": "1.0.0",
"builders": {
"node": "7.x",
"configuration": "1.x"
}
}configuration/schema.json{
"$schema": "http://json-schema.org/draft-07/schema#",
"$ref": "#/definitions/ShippingConfiguration",
"definitions": {
"ShippingConfiguration": {
"type": "object",
"properties": {
"carrierApi": {
"type": "object",
"properties": {
"baseUrl": { "type": "string" },
"apiKey": { "type": "string", "format": "password" },
"timeoutMs": { "type": "integer", "default": 3000 }
},
"required": ["baseUrl", "apiKey"],
"additionalProperties": false
}
},
"required": ["carrierApi"],
"additionalProperties": false
}
}
}vendor.shipping-configmanifest.json{
"vendor": "vendor",
"name": "shipping-config",
"version": "1.0.0",
"builders": {
"configuration": "1.x"
},
"configuration": {
"shipping-service": "1.x"
}
}configuration/shipping-service/configuration.json{
"carrierApi": {
"baseUrl": "https://api.carrier.com",
"apiKey": "secret-api-key-here",
"timeoutMs": 5000
}
}export async function createShipment(ctx: Context, next: () => Promise<void>) {
const settings = ctx.vtex.settings as {
carrierApi: {
baseUrl: string
apiKey: string
timeoutMs?: number
}
}
const timeoutMs = settings.carrierApi.timeoutMs ?? 3000
const response = await ctx.clients.carrier.createShipment({
baseUrl: settings.carrierApi.baseUrl,
apiKey: settings.carrierApi.apiKey,
timeoutMs,
payload: ctx.state.shipmentPayload,
})
ctx.body = response
await next()
}@settingstype ShippingStatus {
orderId: ID!
status: String!
}
type Query {
shippingStatus(orderId: ID!): ShippingStatus
@settings(type: "workspace")
}export const resolvers = {
Query: {
shippingStatus: async (_: unknown, args: { orderId: string }, ctx: Context) => {
const settings = ctx.vtex.settings as {
carrierApi: { baseUrl: string; apiKey: string }
}
return ctx.clients.carrier.getStatus({
baseUrl: settings.carrierApi.baseUrl,
apiKey: settings.carrierApi.apiKey,
orderId: args.orderId,
})
},
},
}configurationmanifest.jsonconfiguration/schema.json<service-app>/configuration.jsonsettingsType: "workspace"read-workspace-appssettingsType@settingsctx.vtex.settingssettingsSchemasettingsSchemasettingsType@settingssettingsType: "workspace"configuration/schema.jsonconfiguration.jsonctx.vtex.settingsread-workspace-appsconfiguration