Unify Applications
Logo
Loading States & Triggers

Loading States & Triggers

Logo

9 mins READ

Loading Layout (Skeleton Screens)

A loading layout is a skeleton version of your page shown while data is loading. Instead of a blank canvas or a lone spinner, visitors see a shimmer that mirrors the shape of the finished page — giving an immediate sense of structure and reducing perceived wait time.

Note: The loading layout is shown only when the page is used as a template component inside another page, and the host page signals a loading state. It does not appear during ordinary page navigation or while individual data sources are fetching. For data-source loading within a normal page, bind block visibility to the data source's isLoading flag instead.

How the Skeleton Is Generated

The loading layout lives as a separate subtree beside the page's normal body, shown as a Loader section in the Hierarchy panel. You create and rebuild it from the ⋮ menu at the top of the Hierarchy panel (Set loader / Regenerate loader), which appears for template components. You do not build it block by block — the platform generates it from the current page body.

Action

When to use

What it does

Set loader

First time you want to create the loading layout

Reads the current page body and generates the skeleton subtree. Containers, stacks, and cards keep their structural role. Text and links become dashed-line placeholders. Other content becomes solid shimmer blocks.

Regenerate loader

After making structural changes to the page

Discards the existing skeleton and rebuilds it from the updated page body. Use after adding, removing, or significantly rearranging blocks. Once a loader exists, the menu item reads Regenerate loader instead of Set loader.

unify-applications-loading-states-and-triggers-01-set-loader-in-hierarchy.png
unify-applications-loading-states-and-triggers-01-set-loader-in-hierarchy.png

Placeholder Generation Rules

The generator follows consistent rules when converting page content into skeleton placeholders:

Original block type

Skeleton treatment

Layout blocks: Container, Stack, Scrollable, Card, Tabs, Repeatable, Stepper

Preserved as structural wrappers. Their children are converted.

Typography, Link

Replaced with a dashed-line placeholder sized to match the text area as currently rendered.

Every other block, including Table, Image, Button and Chart

Replaced with one solid shimmer block matching the block's rendered dimensions.

Modal, Drawer, Bottom Sheet, Contextual Dialog

Excluded from the skeleton. These are not part of the initial page view.

Warning: Placeholder dimensions are measured from the real layout at generation time. If you later change block sizes, add new blocks, or adjust spacing, the skeleton goes out of sync. Use Regenerate loader after structural page changes to keep the skeleton accurate.

Editing the Generated Skeleton

The generated loading layout is an ordinary block subtree — you can open it in the builder, select individual placeholders, and adjust them like any other block. Styling, spacing, and placeholder shape can all be refined by hand after generation.

While a block inside the loader subtree is selected, the canvas automatically switches to the loading layout view so you can see your edits in context. The main page body is hidden while you are editing the loader. Deselect or select a block outside the loader to return to the normal canvas.

Example — Binding block visibility to data source loading state

For normal in-page loading states (not template component skeleton), bind the visibility of a spinner or placeholder component directly to the data source's isLoading flag:

// Show spinner only while data source is loading its first result Visible when: {{ orders_query.isLoading }} // Show the data table only once results are available Visible when: {{ !orders_query.isLoading }} // Show an error message when loading fails Visible when: {{ !!orders_query.error }}

This is the correct approach for standard page data fetching. The skeleton loading layout is reserved for the template component use case.

Page Triggers

A page can run a sequence of actions automatically — without the visitor clicking anything. These are called page triggers and are configured in Page Settings → Interactions → Events.

Page triggers are particularly useful for:

  • Fetching data as soon as a page opens

  • Setting initial variable values

  • Running analytics or logging events

  • Coordinating multiple data sources that share a common starting point

On Page Load

The most commonly used trigger. Fires once when the page finishes mounting — the moment someone opens the page or navigates to it.

Note: When a user navigates away from a page and then back to it, the page is torn down and mounted fresh. This means On Page Load fires again each time the user returns to the page via navigation — it is not a one-time event for the lifetime of the session. In native mobile apps it works differently: a page you leave stays in the navigation stack, so going back to it does not fire On Page Load again. On Page Focus fires instead.

Example — Using On Page Load to fetch initial data

A common On Page Load action sequence:

On Page Load: 1. Trigger Data Source: customer_list_query 2. Trigger Data Source: notifications_query 3. Set variable: selectedTab = "overview"

This ensures data is available immediately after the page renders, and that the UI starts in a predictable state regardless of where the user navigated from. Set the run behavior of customer_list_query and notifications_query to Manual, with run on page load off, so they run only from this sequence and not twice. See Run Behavior & Triggering.

On Page Focus

Fires when the browser tab or window regains focus while the page is already mounted. Unlike On Page Load, this trigger does not fire when the page first opens — only on subsequent focus events.

Typical uses:

  • Refreshing a data source after the user returns from another browser tab

  • Checking for new notifications when the user comes back to the app

  • Resuming a timer or interval that was paused while the tab was hidden

Tip: Use On Page Load for the initial data fetch, and On Page Focus for a lighter "refresh" that checks for updates without fully reloading. This pattern gives users fresh data when they return to a tab without triggering a full re-fetch on every navigation.

On Receive MQTT Event

Available when the page is wired to an MQTT integration. Fires each time a message arrives on the configured MQTT topic. Use this to update page state in real time in response to server-pushed events — for example, updating a machine status indicator as telemetry arrives.

Walkthrough Triggers

Two triggers support pages that participate in walkthroughs:

TriggerWhen it firesCommon use
On Walkthrough Pre StartImmediately before a walkthrough begins on this pagePrepare page state before the walkthrough starts — set variables, navigate to the correct tab
On Walkthrough Pre EndImmediately before a walkthrough ends on this pageClean up or log completion when the walkthrough finishes

Keyboard Shortcuts

A page can also run actions when the visitor presses a key combination. Add a shortcut in Page Settings → Interactions → Keyboard Shortcuts, record the combination by pressing it (for example Control and S together), and attach the actions to run. The shortcut fires anywhere on the page, including while a field has focus, and only when the pressed modifiers match the recorded ones exactly. Combinations the browser or operating system reserves may never reach the page.

Trigger vs Data Source Auto-Run

Both page triggers and data source auto-run settings can cause a data source to execute when a page opens. Understanding the difference prevents unexpected double-fetches and ensures your intended sequencing.

MechanismHow it worksBest for
Data source auto-runThe data source is configured to run automatically on its own timing — on page load or when its inputs change. This is a setting on the data source itself, independent of any page trigger.Simple cases where one data source should fetch independently on load. The default for most data sources.
On Page Load triggerAn explicit action sequence that runs when the page mounts. You add "Trigger Data Source" actions to this sequence manually.Coordinating multiple data sources that should run in a specific order. Running other actions (set variables, logging) alongside the fetch. Centralizing all page initialization in one visible place.

Warning: If a data source is set to auto-run on page load and you also add it to the On Page Load action sequence, it will run twice — once from its own setting and once from the trigger. Configure one or the other, not both, for each data source.

No Page Leave Trigger

UnifyApps does not currently provide an "on page leave" or "before navigate away" trigger. If you need to perform cleanup or save draft state when a user leaves a page, use one of these alternatives:

  • Auto-save at regular intervals using a polling or interval mechanism

  • Save state to a page variable and persist it to a data source on explicit user action (Save button)

  • Use the On Page Load trigger on the destination page to handle any initialization that depends on what the user was doing before

All Page Triggers at a Glance

Trigger

When it fires

Fires on first load?

Notes

On Page Load

Page finishes mounting

Yes

On web, also fires when the user navigates back to the page — the page tears down and remounts fresh each time. In native mobile apps, going back fires On Page Focus instead.

On Page Focus

Browser tab/window regains focus while page is mounted

No

Does not fire on first load. Only fires on subsequent focus events after the page is already open. In native mobile apps, it also fires when the user goes back to the page.

On Receive MQTT Event

MQTT message arrives on configured topic

No

Fires only when the app receives a message on a configured MQTT topic.

On Walkthrough Pre Start

Just before a walkthrough begins on this page

No

Fires only when this page runs inside a walkthrough.

On Walkthrough Pre End

Just before a walkthrough ends on this page

No

Fires only when this page runs inside a walkthrough.

On Keyboard Shortcut

The visitor presses a recorded key combination

No

Set up under Interactions → Keyboard Shortcuts. Fires only when the pressed modifiers match exactly.

Configuring Page Triggers

  1. Open Page Settings: In the Navigator panel, click the page to open its Page Settings, then scroll to the Interactions section.

  2. Select the trigger: Under Events, add an event and choose the trigger you want to configure — for example, On Page Load. For key combinations, use Keyboard Shortcuts instead. An empty action list for that trigger appears.

  3. Add actions: Click Add Action to add items to the action sequence. Actions run in order from top to bottom. You can add as many actions as needed — trigger data sources, set variables, navigate, show toasts, or call custom logic.

  4. Test in preview: Use the builder's preview mode to verify that the trigger fires at the correct moment and produces the expected results. Check that data sources load in the right order and that variables are set correctly before any blocks attempt to read them.

Best Practices

Tip: Put all page startup logic — data fetches, variable initialization, and setup actions — in a single On Page Load action sequence. This makes the page's startup behavior easy to read and debug in one place. Set any data source you trigger from it to Manual, with run on page load off, so it doesn't run twice. See Run Behavior & Triggering.

Tip: Do not use the loading layout for normal page data fetching. Instead, bind a spinner or placeholder block's visibility to {{ your_datasource.isLoading }}. Reserve the loading layout for when the page is used as a template component.

Tip: If you use a loading layout and later rearrange or add blocks to the page, choose Regenerate loader from the ⋮ menu at the top of the Hierarchy panel to keep the skeleton in sync with the current page body. A stale skeleton that no longer matches the real layout degrades the loading experience.