How Server-Driven UI Passes Schemas to JavaScript
Server-driven UI (SDUI) architecture allows backend services to control the structure, styling, and behavior of a frontend interface by transmitting declarative layout schemas directly to client-side JavaScript. Instead of relying on hardcoded client component hierarchies, the server serializes UI definitions—typically via structured JSON or GraphQL payloads—over standard network protocols. The client JavaScript application then parses this schema, maps abstract component definitions to a local component registry, and dynamically renders the user interface in real time.
1. Schema Definition and Structure
The server constructs the UI using a standardized data format, universally represented as a nested JSON tree. This schema decouples the data model from presentation logic while specifying exactly how components should be arranged and configured.
A typical SDUI schema object contains: * type /
component: The identifier matching a corresponding
frontend component (e.g., "Carousel",
"Button", "Banner"). *
id: A unique key for UI reconciliation,
accessibility, and state tracking. * props /
attributes: Visual properties such as text,
colors, layout alignment, and margins. *
children: An array of nested schema
objects that define child elements. *
actions: Definitions for user interactions
(e.g., navigation events, analytic triggers, or API calls).
{
"type": "Card",
"id": "card-101",
"props": {
"elevation": 2,
"padding": "16px"
},
"children": [
{
"type": "Text",
"props": {
"content": "Special Promotion",
"variant": "headline"
}
},
{
"type": "Button",
"props": {
"label": "Claim Offer"
},
"action": {
"type": "NAVIGATE",
"payload": { "url": "/offers/claim" }
}
}
]
}2. Network Transport and Delivery
The backend passes the generated schema to the client runtime through standard network communication layers:
- RESTful APIs: The client issues an HTTP
GETorPOSTrequest upon navigation, receiving the layout payload tailored to the user’s context, authentication state, or feature flags. - GraphQL: The client queries specific UI fragments, allowing it to request both business data and dynamic layout schemas within a unified request.
- WebSockets / Server-Sent Events (SSE): For live interfaces, the server streams real-time schema diffs or layout replacements directly to the active client session.
3. Client Component Registry Mapping
The core of the client-side JavaScript architecture is the component
registry—a lookup table mapping incoming schema type
strings to actual frontend components (e.g., React, Vue, Svelte, or
native Web Components).
import Button from './components/Button';
import Card from './components/Card';
import Text from './components/Text';
const COMPONENT_REGISTRY = {
Button,
Card,
Text,
};4. Schema Parsing and Dynamic Rendering
Once the JSON payload arrives, the client processes the node tree recursively. A recursive rendering engine reads each node, validates it, and instantiates the target component from the registry with the provided properties.
function RenderNode({ node }) {
const Component = COMPONENT_REGISTRY[node.type];
if (!Component) {
console.warn(`Unsupported component type: ${node.type}`);
return null;
}
const renderedChildren = node.children
? node.children.map(child => <RenderNode key={child.id} node={child} />)
: null;
return (
<Component {...node.props} action={node.action}>
{renderedChildren}
</Component>
);
}5. Action and State Binding
The client-side JavaScript infrastructure intercepts declarative action definitions contained in the schema and binds them to local execution handlers.
When a user triggers an event (like a click), the client resolves the action metadata via an action dispatcher: * Navigation Actions: Handled by the client-side router without a full page reload. * API Requests: Dispatched to update server state, which can respond with a new UI schema fragment. * Local State Updates: Processed through client-side state managers (e.g., Redux, Zustand) to toggle local visibility, input forms, or animations.