
Grab your gear: The official Sanity swag store
Read Grab your gear: The official Sanity swag storeThe best approach for auto-incrementing an orderNumber field is to use a dedicated counter document with atomic transactions. Here's the pattern that works reliably:
Create a separate counter document to track your order numbers, then use transactions with patch, setIfMissing, and inc operations to atomically increment and retrieve the next number:
async function createOrder() {
const COUNTER_ID = 'order-counter'; // A fixed document ID for your counter
// Atomic transaction to get next order number
const result = await client
.transaction()
.patch(COUNTER_ID, patch =>
patch
.setIfMissing({ _type: 'counter', current: 2300000000 }) // Initialize if missing
.inc({ current: 1 }) // Increment atomically
)
.commit({ returnDocuments: true });
const nextOrderNumber = result[0].current;
// Now create your order with the guaranteed unique number
const doc = {
_type: 'order',
note: 'První poznámka objednávky',
orderNumber: nextOrderNumber,
};
const orderResult = await client.create(doc);
console.log(`Objednávka byla vytvořena, document ID is ${orderResult._id}`);
console.log(`Order number: ${nextOrderNumber}`);
}setIfMissing ensures the counter document exists and is initialized on first useinc atomically increments the counter - this is thread-safe even with concurrent requestsreturnDocuments: true gives you the updated counter value immediatelyYou can also create both the counter update and order document in a single transaction:
async function createOrder() {
const COUNTER_ID = 'order-counter';
const orderId = `order-${Date.now()}`; // Generate unique ID
// First get the next number
const counterResult = await client
.transaction()
.patch(COUNTER_ID, patch =>
patch
.setIfMissing({ _type: 'counter', current: 2300000000 })
.inc({ current: 1 })
)
.commit({ returnDocuments: true });
const nextOrderNumber = counterResult[0].current;
// Then create the order with that number
const orderResult = await client.create({
_type: 'order',
note: 'První poznámka objednávky',
orderNumber: nextOrderNumber,
});
console.log(`Objednávka byla vytvořena, document ID is ${orderResult._id}`);
return orderResult;
}Add a counter document type to your schema:
export default {
name: 'counter',
type: 'document',
title: 'Counter',
fields: [
{
name: 'current',
type: 'number',
title: 'Current Value',
},
],
}While GROQ's math::sum can calculate totals, it's not suitable for generating unique sequential numbers because:
The counter document with inc is the proper solution because it's atomic and handles concurrency correctly. The ifRevisionId parameter you might find in older examples is not necessary with this approach since inc is inherently atomic within a transaction.
Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.
Content backend


The only platform powering content operations


Tecovas strengthens their customer connections
Build and Share

Grab your gear: The official Sanity swag store
Read Grab your gear: The official Sanity swag store