The Visibility System allows you to dynamically show or hide components based on the state of your application. Instead of static forms, you can create reactive interfaces that adapt to user input, user roles, or database records.
Every component in the App Builder has a Visibility Logic setting.
true, the component is shown.false, the component is hidden.The logic engine uses standard JavaScript comparisons combined with a special Double Curly Brace syntax to access your data.
{{ ... }}To read a value from your application, wrap the path in curly braces. The system replaces these tags with the actual values before running the logic.
| Namespace | Description | Example |
|---|---|---|
| pageData | Data currently entered in the form inputs on the screen. | {{pageData.firstName}} |
| record | Data from the database record currently loaded (if editing). | {{record.status}} |
| system | Global app data (User info, Theme, Dates). | {{system.user.email}} |
| params | Values from the URL (e.g., ID or query strings). | {{params.id}} |
You can use standard logical operators to compare values:
== (Equals)!= (Does not equal)> (Greater than)&& (AND - both must be true)|| (OR - at least one must be true)utils)Data can be messy (null values, empty lists, etc.). We provide a built-in utils library to make your logic robust and crash-proof.
utils.isEmpty(value)Checks if a value is effectively "blank". It returns true for: null, undefined, empty strings "", empty arrays [], or empty objects {}.
Use Case: Show a "Submit" button only when an email is typed.
!utils.isEmpty({{pageData.email}})
utils.includes(list, item)Checks if a list contains a specific item, or if a string contains a substring.
Use Case: Show a generic Admin panel only to users with the 'admin' role.
utils.includes({{system.user.roles}}, 'admin')
Use Case: Show a field if the 'Ticket Type' dropdown contains the word "Urgent".
utils.includes({{pageData.ticketType}}, 'Urgent')
utils.isAfter(dateA, dateB)Compares two dates. Returns true if dateA is after dateB.
Use Case: Show an overdue warning if the due date is past today.
utils.isAfter({{system.date.today}}, {{record.dueDate}})
Goal: Only show the "Github Username" input if the user selects "Developer" as their Job Title.
{{pageData.jobTitle}} == 'Developer'
Goal: Show a "Delete" button only if we are editing an existing record (not creating a new one), and the record has an ID.
!utils.isEmpty({{record.id}})
Goal: Show a generic "Manager Approval" section if the Total Cost is over $1,000 AND the department is Sales.
{{pageData.totalCost}} > 1000 && {{pageData.department}} == 'Sales'
Goal: Show a special specific configuration panel only if the URL contains ?mode=advanced.
{{params.mode}} == 'advanced'
pageData or utils). Use these suggestions to avoid typos.undefined. It is safer to use utils.isEmpty({{pageData.field}}) than to check {{pageData.field}} == ''.