Keyboard shortcuts

Press or to navigate between chapters

Press ? to show this help

Press Esc to hide this help

Data & Backend Nodes

The data layer covers mutations (ActionNode), real-time subscriptions (SubscriptionNode), authentication (AuthContextNode), CMS content (ContentSlot), and structured rich text (RichTextNode). Data reads are handled by DataNode in the State chapter.

ActionNode

Declares a server mutation with optimistic update strategy, cache invalidation, and error handling. The compiler emits mutation calls with rollback support.

FieldTypeRequiredDescription
node_idstringyesUnique identifier
namestringnoHuman-readable name
sourceDataSourceyesEndpoint configuration
methodHttpMethodnoPOST (default), GET, PUT, PATCH, DELETE
input_typestringnoInput type hint for the compiler
output_typestringnoOutput type hint for the compiler
optimisticOptimisticConfignoOptimistic update behavior
invalidates[string]noDataNode IDs to refetch after success
invalidate_tags[string]noCache tags to invalidate
error_handlingErrorHandlingnoError and retry configuration
auth_requiredboolnoWhether authentication is needed (default false)
required_roles[string]noRoles required to execute this action
csrf_protectedboolnoCSRF protection enabled (default true)
idempotentboolnoWhether safe to retry (default false)

OptimisticConfig

FieldTypeRequiredDescription
strategyOptimisticStrategynoNone (default), MirrorInput, CustomTransform
target_data_node_idstringnoDataNode to optimistically update
rollbackRollbackStrategynoRevert (default) or ShowErrorKeepData

ErrorHandling

FieldTypeRequiredDescription
retryRetryConfignoRetry configuration
fallbackErrorFallbacknoShowToast (default), ShowInlineError, Redirect
redirect_pathstringnoPath for Redirect fallback
{
  "node_id": "add-to-cart",
  "name": "add-item",
  "source": {
    "provider": "Rest",
    "endpoint": "/api/cart/items"
  },
  "method": "POST",
  "optimistic": {
    "strategy": "MirrorInput",
    "target_data_node_id": "cart-data",
    "rollback": "Revert"
  },
  "invalidates": ["cart-data"],
  "csrf_protected": true
}

SubscriptionNode

Real-time data via WebSocket, Server-Sent Events, or polling. Keeps a DataNode updated with live changes.

FieldTypeRequiredDescription
node_idstringyesUnique identifier
namestringnoHuman-readable name
sourceDataSourceyesEndpoint configuration
transportSubscriptionTransportnoWebSocket (default), ServerSentEvents, Polling
channelstringnoChannel, topic, or table to subscribe to
filterstringnoFilter expression for the subscription
update_strategyUpdateStrategynoReplace (default), Merge, Append
target_data_node_idstringyesDataNode to keep updated
connectionConnectionConfignoReconnection and heartbeat settings

ConnectionConfig

FieldTypeRequiredDescription
reconnectboolnoAuto-reconnect on disconnect (default true)
reconnect_interval_msuint32noReconnect interval in ms (default 3000)
max_retriesint32noMaximum reconnect attempts (default 10)
heartbeat_interval_msuint32noHeartbeat interval in ms (default 30000)
{
  "node_id": "chat-sub",
  "name": "chat-messages",
  "source": {
    "provider": "Supabase",
    "endpoint": "wss://project.supabase.co/realtime/v1"
  },
  "transport": "WebSocket",
  "channel": "messages",
  "update_strategy": "Append",
  "target_data_node_id": "messages-data"
}

AuthContextNode

Application-level auth configuration. Provider-agnostic; the compiler adapts output to the chosen provider.

FieldTypeRequiredDescription
node_idstringyesUnique identifier
namestringnoHuman-readable name
providerAuthProvidernoAuth0, Clerk, Supabase, Firebase, NextAuth, Custom
session_strategySessionStrategynoJwtCookie (default), JwtHeader, SessionCookie
user_typestringnoType hint for the user object shape
role_fieldstringnoField path for roles in the user object
login_action_idstringnoActionNode reference for login
logout_action_idstringnoActionNode reference for logout
refresh_action_idstringnoActionNode reference for token refresh
{
  "node_id": "app-auth",
  "provider": "Supabase",
  "session_strategy": "JwtCookie",
  "role_field": "user_metadata.role",
  "login_action_id": "login-action",
  "logout_action_id": "logout-action"
}

ContentSlot

Declares a CMS content dependency. The cache strategy determines compiler behavior: static content is baked in at build time, ISR adds revalidation, and dynamic content is fetched at runtime.

FieldTypeRequiredDescription
node_idstringyesUnique identifier
content_keystringyesContent entry ID or path in the CMS
sourceContentSourcenoCMS provider and endpoint configuration
fallbackstringnoFallback content if CMS fetch fails
cache_strategyContentCacheStrategynoStatic (default), Isr, Dynamic
content_typeContentTypenoText (default), RichText, Media, Structured
localestringnoLocale for this content slot
{
  "node_id": "hero-content",
  "content_key": "homepage-hero",
  "source": {
    "provider": "sanity",
    "endpoint": "https://project.api.sanity.io/v2023-01-01"
  },
  "cache_strategy": "Isr",
  "content_type": "RichText"
}

RichTextNode

Structured rich text with paragraphs, headings, lists, images, code blocks, and more. Maps directly from Sanity Portable Text, Contentful Rich Text JSON, and Payload Lexical JSON.

FieldTypeRequiredDescription
node_idstringyesUnique identifier
blocks[RichTextBlock]yesOrdered list of content blocks
content_slotContentSlotnoCMS source for the content

RichTextBlock

FieldTypeRequiredDescription
block_typeRichTextBlockTypenoParagraph, Heading, UnorderedList, OrderedList, ListItem, Image, CodeBlock, Blockquote, Divider, Table, TableRow, TableCell
levelint8noHeading level (1-6) or list depth
children[RichTextSpan]noInline text content
media_srcstringnoImage source URL (for Image blocks)
media_altstringnoImage alt text (for Image blocks)
code_languagestringnoLanguage hint (for CodeBlock blocks)
rows[RichTextBlock]noNested rows (for Table blocks)

RichTextSpan

FieldTypeRequiredDescription
textstringyesText content
marks[RichTextMark]noBold, Italic, Underline, Strikethrough, Code, Subscript, Superscript
link_urlstringnoURL if this span is a link
{
  "node_id": "article-body",
  "blocks": [
    {
      "block_type": "Heading",
      "level": 2,
      "children": [{ "text": "Getting Started" }]
    },
    {
      "block_type": "Paragraph",
      "children": [
        { "text": "Voce IR uses " },
        { "text": "FlatBuffers", "marks": ["Bold"] },
        { "text": " for zero-copy deserialization." }
      ]
    }
  ]
}