Variables are the key to creating dynamic, data-driven interfaces with UI Builder. Instead of hardcoding static values into your components, variables allow you to bind component properties to dynamic data that can change at runtime.
This transforms static designs into powerful applications with:
UI Builder supports three typed variables:
tsx1interface Variable { 2 id: string; // Unique identifier 3 name: string; // Display name (becomes property name in generated code) 4 type: 'string' | 'number' | 'boolean'; 5 defaultValue: string | number | boolean; // Must match the type 6} 7 8// Examples: 9const stringVar: Variable = { 10 id: 'page-title', 11 name: 'pageTitle', 12 type: 'string', 13 defaultValue: 'Welcome to UI Builder' 14}; 15 16const numberVar: Variable = { 17 id: 'user-age', 18 name: 'userAge', 19 type: 'number', 20 defaultValue: 25 21}; 22 23const booleanVar: Variable = { 24 id: 'is-loading', 25 name: 'isLoading', 26 type: 'boolean', 27 defaultValue: false 28};
š” See it in action: The demo above shows all three types with real-time variable binding and runtime value overrides.
Set up variables when initializing the UIBuilder:
tsx1import UIBuilder from '@/components/ui/ui-builder'; 2import { Variable } from '@/components/ui/ui-builder/types'; 3 4const initialVariables: Variable[] = [ 5 { 6 id: 'welcome-msg', 7 name: 'welcomeMessage', 8 type: 'string', 9 defaultValue: 'Welcome to our site!' 10 }, 11 { 12 id: 'user-count', 13 name: 'userCount', 14 type: 'number', 15 defaultValue: 0 16 }, 17 { 18 id: 'show-banner', 19 name: 'showBanner', 20 type: 'boolean', 21 defaultValue: true 22 } 23]; 24 25function App() { 26 return ( 27 <UIBuilder 28 componentRegistry={myComponentRegistry} 29 initialVariables={initialVariables} 30 onVariablesChange={(variables) => { 31 // Persist variable definitions to your backend 32 console.log('Variables updated:', variables); 33 }} 34 /> 35 ); 36}
Users can create variables directly in the editor:
Variables can be bound to component properties in two ways:
Users can bind variables to component properties in the props panel by clicking the link icon next to any field.
Components can be configured to automatically bind to specific variables when added:
tsx1const componentRegistry = { 2 UserProfile: { 3 component: UserProfile, 4 schema: z.object({ 5 userId: z.string(), 6 displayName: z.string(), 7 }), 8 from: '@/components/ui/user-profile', 9 // Automatically bind user data when component is added 10 defaultVariableBindings: [ 11 { 12 propName: 'userId', 13 variableId: 'current-user-id', 14 immutable: true // Cannot be unbound in UI 15 }, 16 { 17 propName: 'displayName', 18 variableId: 'current-user-name', 19 immutable: false // Can be changed by users 20 } 21 ] 22 } 23};
Immutable bindings prevent users from unbinding critical variables for system data, branding consistency, and template integrity.
š” Learn more: See Variable Binding for detailed binding mechanics and Data Binding for connecting to external data sources.
Control whether users can edit variables in the UI:
tsx1<UIBuilder 2 allowVariableEditing={false} // Hides add/edit/delete buttons 3 initialVariables={systemVariables} 4 componentRegistry={myComponentRegistry} 5/>
When allowVariableEditing is false:
Respond to variable definition changes in the editor:
tsx1function App() { 2 const handleVariablesChange = (variables: Variable[]) => { 3 // Persist variable definitions to backend 4 fetch('/api/variables', { 5 method: 'POST', 6 body: JSON.stringify(variables) 7 }); 8 }; 9 10 return ( 11 <UIBuilder 12 componentRegistry={myComponentRegistry} 13 onVariablesChange={handleVariablesChange} 14 /> 15 ); 16}
tsx1// Variables for user-specific content 2const userVariables: Variable[] = [ 3 { id: 'user-name', name: 'userName', type: 'string', defaultValue: 'User' }, 4 { id: 'user-avatar', name: 'userAvatar', type: 'string', defaultValue: '/default-avatar.png' }, 5 { id: 'is-premium', name: 'isPremiumUser', type: 'boolean', defaultValue: false } 6];
tsx1// Variables for conditional features 2const featureFlags: Variable[] = [ 3 { id: 'show-beta-feature', name: 'showBetaFeature', type: 'boolean', defaultValue: false }, 4 { id: 'enable-dark-mode', name: 'enableDarkMode', type: 'boolean', defaultValue: true } 5];
tsx1// Variables for client-specific branding 2const brandingVariables: Variable[] = [ 3 { id: 'company-name', name: 'companyName', type: 'string', defaultValue: 'Acme Corp' }, 4 { id: 'primary-color', name: 'primaryColor', type: 'string', defaultValue: '#3b82f6' }, 5 { id: 'logo-url', name: 'logoUrl', type: 'string', defaultValue: '/default-logo.png' } 6];
userName not u)initialVariablesonChange and onVariablesChange)LayerRenderer with variableValues to inject real data at runtimeThis workflow enables the separation of content structure from actual data, making your UI Builder pages truly dynamic and reusable.
š Next Steps: Learn about Variable Binding for detailed binding mechanics, Data Binding for external data integration, and Rendering Pages for runtime usage.