Skip to content

Blocks System

Arky uses a unified block system to model all structured data — from CMS entries and product specifications to reservation forms and order metadata. Blocks provide type safety, multilingual support, nested structures, and AI generation capabilities.

A block is a typed, key-value pair with metadata (properties) that defines how the data should be structured, validated, and displayed.

{
"id": "block_xyz",
"key": "title",
"type": "TEXT",
"properties": {
"label": { "en": "Title", "es": "Título" },
"maxLength": 255
},
"value": [
{ "en": "Welcome to Arky", "es": "Bienvenido a Arky" }
]
}

Arky supports these core block types:

TypeDescriptionUse Cases
TEXTMultilingual text contentTitles, descriptions, HTML content
TEXT_FILTERText for filtering/searchSearch queries, filter values
NUMBERNumeric valuesPrices, dates (timestamps), quantities
NUMBER_FILTERNumeric filtersPrice ranges, date filters
BOOLEANTrue/false flagsFeature toggles, checkboxes
GEO_LOCATIONGeographic coordinates & addressesStore locations, delivery addresses
RELATIONSHIP_ENTRYReferences to CMS entriesRelated posts, categories
RELATIONSHIP_MEDIAReferences to media filesImages, videos, documents
PHONE_NUMBERPhone number valuesContact info with validation
EMAILEmail addressesContact emails
BLOCKNested block containersRepeatable sections, complex forms

Every block shares this common structure:

interface Block {
id: string; // Unique identifier
key: string; // Field name (e.g., "title", "price")
type: BlockType; // TEXT | NUMBER | BOOLEAN | etc.
properties: Props; // Type-specific metadata
value: Value[]; // Array of values (supports multi-value fields)
}

Even single-value fields use arrays (value: [...]) to support:

  • Multi-value fields: Tags, galleries, multiple addresses
  • Localization: [{ "en": "Hello", "es": "Hola" }]
  • Relationship hydration: [{ id, title, ... }] for entries or media

TEXT blocks handle all text-based content with optional multilingual support.

{
"id": "1",
"key": "description",
"type": "TEXT",
"properties": {
"label": { "en": "Description" },
"maxLength": 500
},
"value": [
{ "en": "A powerful headless CMS" }
]
}
interface TextProperties {
label?: Record<string, string>; // Localized field labels
pattern?: string; // Regex validation
minLength?: number;
maxLength?: number;
style?: Record<string, string>; // CSS styles for UI rendering
url?: string; // External link metadata
minValues?: number;
maxValues?: number; // 1 = single, >1 = multi-value
}

NUMBER blocks handle numeric values.

{
"id": "4",
"key": "price",
"type": "NUMBER",
"properties": {
"label": { "en": "Price" }
},
"value": [29.99]
}
interface NumberProperties {
label?: Record<string, string>;
minValues?: number;
maxValues?: number;
operation?: "plus" | "minus" | "equals" | "greater_than" | "less_than" | "greater_than_or_equal" | "less_than_or_equal" | "contains";
}

BOOLEAN blocks represent true/false states.

{
"id": "7",
"key": "featured",
"type": "BOOLEAN",
"properties": {
"label": { "en": "Featured Product" },
"maxValues": 1
},
"value": [true]
}
interface BooleanProperties {
label?: Record<string, string>;
maxValues?: number;
}

GEO_LOCATION blocks store geographic data for mapping and address fields.

{
"id": "8",
"key": "location",
"type": "GEO_LOCATION",
"properties": {
"label": { "en": "Store Location" }
},
"value": [
{
"country": "United States",
"countryCode": "US",
"city": "New York",
"address": "123 Broadway",
"postalCode": "10001",
"coordinates": {
"lat": 40.7128,
"lon": -74.0060
}
}
]
}
interface GeoLocationValue {
country?: string;
countryCode?: string;
city?: string;
address?: string;
postalCode?: string;
coordinates?: {
lat: number;
lon: number;
};
}
interface GeoProperties {
label?: Record<string, string>;
}

RELATIONSHIP blocks reference other entities (media files or CMS entries).

  • RELATIONSHIP_MEDIA: References to uploaded files
  • RELATIONSHIP_ENTRY: References to CMS entries

References use prefixed IDs:

  • media:<id> — Media files
  • entry:<id> — CMS entries
{
"id": "9",
"key": "gallery",
"type": "RELATIONSHIP_MEDIA",
"properties": {
"maxValues": 10
},
"value": [
"media:abc123",
"media:def456"
]
}

By default, relationships return dehydrated references ("media:xyz"). Use query params to hydrate:

GET /v1/collections/posts/entries/123?hydrate=true
interface RelationshipProperties {
label?: Record<string, string>;
minValues?: number;
maxValues?: number;
url?: string; // External source URL
}

Dedicated phone number type with validation.

{
"id": "11",
"key": "contactPhone",
"type": "PHONE_NUMBER",
"properties": {
"label": { "en": "Contact Phone" },
"pattern": "^\\+?[0-9\\s-()]+$",
"isRequired": true,
"placeholder": "+1 (555) 123-4567"
},
"value": ["+15551234567"]
}
interface PhoneNumberProperties {
label?: Record<string, string>;
pattern?: string;
isRequired?: boolean;
placeholder?: string;
}

Email address type.

{
"id": "12",
"key": "contactEmail",
"type": "EMAIL",
"properties": {
"label": { "en": "Email" }
},
"value": ["user@example.com"]
}
interface TextProperties {
label?: Record<string, string>;
pattern?: string;
minLength?: number;
maxLength?: number;
minValues?: number;
maxValues?: number;
}

BLOCK blocks contain nested arrays of other blocks, enabling repeatable sections and complex forms.

{
"id": "11",
"key": "contacts",
"type": "BLOCK",
"properties": {
"label": { "en": "Contact Information" },
"maxValues": 5
},
"value": [
{
"id": "contact_1",
"key": "contact",
"type": "BLOCK",
"properties": {},
"value": [
{
"id": "c1_name",
"key": "name",
"type": "TEXT",
"properties": {},
"value": [{ "en": "John Doe" }]
},
{
"id": "c1_phone",
"key": "phone",
"type": "PHONE_NUMBER",
"properties": {},
"value": ["+1234567890"]
}
]
}
]
}
  • Repeatable sections: FAQ items, team members, testimonials
  • Complex forms: Multi-step checkout, reservation details
  • Structured content: Recipe ingredients, event schedules
  • Order/Reservation metadata: Custom fields for bookings
interface BlockProperties {
label?: Record<string, string>;
each?: string; // Iteration hint for rendering
style?: Record<string, string>;
url?: string;
minValues?: number;
maxValues?: number;
}

Special block types for filtering and search:

Used for text-based filtering (search queries).

{
"id": "f1",
"key": "searchQuery",
"type": "TEXT_FILTER",
"properties": {},
"value": ["smartphone"]
}

Used for numeric filtering (price ranges, date ranges).

{
"id": "f2",
"key": "priceFilter",
"type": "NUMBER_FILTER",
"properties": {
"operation": "less_than_or_equal"
},
"value": [">=100", "<=500"]
}

import { getBlockValue, getBlockTextValue, extractBlockValues } from 'arky-sdk/utils/blocks';
const entry = await sdk.cms.getCollectionEntry({ id: 'entry_123' });
// Single value
const title = getBlockValue(entry, 'title');
// Localized text
const description = getBlockTextValue(
entry.blocks.find(b => b.key === 'description'),
'en'
);
// Extract all values as object
const values = extractBlockValues(entry.blocks);
// { title: "...", price: 29.99, featured: true }
import { getImageUrl } from 'arky-sdk/utils/blocks';
const product = await sdk.eshop.getProduct({ id: 'prod_123' });
const galleryBlock = product.blocks.find(b => b.key === 'gallery');
// Extract first image URL
const imageUrl = getImageUrl(galleryBlock, true, 'https://storage.arky.io');
// "https://storage.arky.io/business_123/media/abc123.jpg"

  • Use PHONE_NUMBER instead of TEXT for phone numbers
  • Use EMAIL instead of TEXT for emails
  • Use GEO_LOCATION instead of separate text fields for addresses

Always provide multilingual labels and content:

{
"properties": {
"label": { "en": "Title", "es": "Título", "fr": "Titre" }
},
"value": [
{ "en": "Hello", "es": "Hola", "fr": "Bonjour" }
]
}

Use descriptive, consistent keys:

  • productName, price, publishedAt
  • field1, data, text

Fetch relationships dehydrated (media:xyz) unless you need full objects. This reduces payload size and improves performance.

Use BLOCK type for repeatable, structured sections rather than hardcoding multiple top-level fields.


  • CMS API — Collections and entries with block-based content
  • E-shop API — Products with block-based specifications
  • Reservations API — Services and bookings with custom block fields