URL Structure
Every page in your app has a slug — a short path segment that determines the page's URL. The page's full URL is the app's base URL followed by the slug:
Example — Page URL from slug
App base URL: https://mycompany.unifyapps.com/app/ Page slug: order-details Full page URL: https://mycompany.unifyapps.com/app/order-details
The slug is set when the page is created and can be changed in Page Settings at any time — but changing it breaks any external links or bookmarks pointing at the old address.
The Navigator Panel
The Navigator panel (left rail in the builder) lists all pages and modules as a tree. Pages can be organized into folders. Each page entry has an overflow menu with actions:
| Action | What it does |
| Page Settings | Opens the full page settings panel for slug, privacy, document title, events, permissions, custom code, and transition behavior. |
| Rename Page | Changes the display name of the page. Does not change the slug. |
| Clone Page | Creates a duplicate of the page with all its blocks, variables, and settings. The clone gets a new slug. |
| Delete Page | Permanently removes the page. Navigation items pointing at it become broken. If it was the default page, the default is left unset. |
| Home Page | Sets this page as the app's default (home) page for logged-in users. |
| Export as Template | Opens the Publish as Template flow to save this page's design to the template library. |
Creating a New Page
Click Create New Page from the Navigator panel or page list. The Page Setup dialog presents the following options:
| Field | Required | Notes |
| Page Name | Yes | Display name. Shown in the Navigator and used as the browser tab title by default. |
| Parent Folder | No | Organizes the page within a folder in the Navigator. No effect on the URL unless the folder is a URL segment (see Dynamic URLs). |
| Page Slug (Page URL) | Yes | Auto-generated from the page name. Must be unique across all pages. Cannot match another page's URL. Shown as "Page URL:" in the dialog for clarity. |
| Privacy | Yes | Private = requires sign-in. Public = accessible to anyone with the link, no sign-in required. Default is Private. |
| Add page to navigation | No | If checked, adds the page to the app's navigation menu immediately. Expands to let you set a Navigation Icon and Nest location (which group to place it under). |
| Starting point | No | Blank Page or choose a template from the Custom or System template library. |
Page Settings
After a page is created, open Page Settings from the Navigator menu to configure it further. Settings are organized into sections:
General Settings
| Setting | Description |
| Page Slug | The URL path segment for this page. Must be unique. Changing it breaks existing links and bookmarks to the old URL. |
| Parent Folder | Move the page to a different folder in the Navigator tree. |
| Privacy | Private (authenticated) or Public (unauthenticated access). Private pages redirect unauthenticated visitors to the login page. |
| Document Title | The text shown in the browser tab for this page. Defaults to the page name. Can be a fixed string or a dynamic expression — when bound to a value (e.g., a record name from a data source), the tab title updates as the bound value changes. |
| Query Parameters | Declares named page inputs that arrive via the URL query string (e.g., ?orderId=123). Only declared parameters are read — undeclared params are ignored. The name pageInputs is reserved and cannot be used. |
| Transition Behavior | Mobile-only animation style for this page when navigating to it. |
Events
The Events section in Page Settings is where page triggers (On Page Load, On Page Focus, etc.) are configured. See Loading States & Triggers for full details.
Permissions
Layer role-based access on top of the Privacy setting. Private pages are already limited to authenticated users; Permissions add finer control over which authenticated users or roles can access the page. Pages with insufficient permissions are silently hidden from the navigation in the published app.
Custom Code
Add page-level JavaScript or CSS that executes only when this page is open. Useful for third-party analytics snippets, page-specific CSS overrides, or legacy integrations.
Dynamic URLs
Dynamic URLs let a single page represent many different records by capturing a variable value from the URL path. This is how you build detail pages — one page design, many records.
Folder Types for Dynamic Segments
Dynamic URL segments are created by setting a folder's type in the Navigator:
| Folder type | URL segment | Example URL | Use |
| Static segment | Literal text | /orders/details | Grouping pages under a named path prefix without capturing a value |
| Dynamic segment | Captures a value as a named parameter (:paramName) | /orders/:orderId/details | Record detail pages — the segment value becomes available in the page as a dynamic param |
Dynamic folders have a Mock value setting — a placeholder value used in the builder so the page can preview correctly without a real record ID.
Folder Redirects
A folder can be configured to Redirect to another page. When a URL matching the folder's path is visited without a child page match, the visitor is redirected to the target page. Path parameters captured from the URL can be passed to the redirect target.
Example — Dynamic URL structure for an order detail page
Folder: orders/ (static segment) Folder: :orderId/ (dynamic segment — captures order ID) Page: details (slug: "details") Resulting URL pattern: /orders/:orderId/details Example URL: /orders/ORD-2847/details In-page access: {{ page.params.orderId }} → "ORD-2847"
Navigating Between Pages
In-app navigation is controlled by the Go to Page action (and related navigation actions), configured in any interaction or event handler.
Go to Page Action
| Option | Description |
| Page | The destination page. Select from all pages in the app. |
| Open in new tab | If enabled, opens the destination in a new browser tab instead of the current one. |
| History — Push | Adds the destination to the browser's navigation history. The user can press Back to return. This is the default behavior. |
| History — Replace | Replaces the current entry in the browser's history instead of adding a new one. Back does not return to the current page. |
| Page Inputs | Pass values to the destination page's declared query parameters. Appear in the destination URL as ?name=value. |
| Dynamic Params | Fill in dynamic URL segment values for destinations that use a dynamic path. For example, pass a record's ID to a detail page. |
Example — Navigating to an order detail page from a table row
// On row click in an Orders table: Action: Go to Page Page: Order Details Dynamic Params: orderId: {{ currentRow.id }} // The resulting URL will be something like: // /orders/ORD-2847/details // In the Order Details page, access the param: // {{ page.params.orderId }} → "ORD-2847" // Then use it as a data source input to fetch the order.
Related Navigation Actions
| Action | What it does |
| Go to URL | Navigates to any URL — internal or external. For external links, enable Open in new tab. |
| Navigate Back | Equivalent to the browser's Back button. Goes to the previous entry in history. |
| Set URL Parameters | Updates the current page's query string without navigating away. Changes URL params that the page reads without triggering a full page reload. |
Deep Linking
Because every page and every record has a deterministic URL, sharing deep links is built in. To share a link to a specific record:
Navigate to the detail page for the record
Copy the URL from the browser address bar
Share it — anyone with access to the app who opens the link lands on that exact record's detail view
This works because the dynamic URL segment captures the record ID in the path, and the On Page Load trigger uses that ID to fetch the correct record from the data source.
Example — Fetching a record from a deep-linked URL
// Shared URL: // /orders/ORD-2847/details // In the Order Details page, on Page Load: // Run data source: order_query // Input — orderId: {{ page.params.orderId }} // order_query fetches the specific order with id ORD-2847. // The page displays that order's data — same as if the user // had clicked through from the Orders list.
Privacy and Access
Every page has a Privacy setting that controls who can open it:
| Privacy | Who can open it | Default page requirement |
| Private | Signed-in users only. Unauthenticated visitors are redirected to the login page. | Can be the logged-in default page. |
| Public | Anyone with the link. No sign-in required. | Required if set as the logged-out default page. |
Permissions (role-based access) layer on top of Privacy. A Private page is first gated by authentication; Permissions then control which authenticated users can see the page.
Warning: No two pages can share the same URL slug. If you try to set a slug that is already used by another page, the platform will prevent the save and show a conflict error. Rename one of the pages to resolve the conflict.
Document Title
The document title is the text shown in the browser tab when this page is open. It can be:
| Mode | How to configure | When to use |
| Default (page name) | Leave the Document Title field blank or set it to the page name | Static pages where the title never changes |
| Fixed string | Type any text into the Document Title field | When you want a custom title different from the page name |
| Dynamic expression | Bind the field to a data expression: {{ order_query.data.orderNumber }} | Detail pages — the tab title should reflect the specific record being viewed |
Example — Dynamic document title on an order detail page
Document Title: Order {{ order_query.data.orderNumber }} — Acme App // While the page is loading: // Browser tab: "Order — Acme App" (orderNumber not yet resolved) // After data loads: // Browser tab: "Order ORD-2847 — Acme App"
The title updates automatically when the bound expression resolves — no extra actions required.
Query Parameters (Page Inputs)
Pages can accept input values via the URL query string. These are declared as Query Parameters in Page Settings and received by the page as named inputs.
| Concept | Details |
| Declared parameters | Only parameters explicitly declared in Page Settings are read from the query string. Any undeclared parameters in the URL are silently ignored. |
| Reserved name | pageInputs is a reserved query parameter name and cannot be used for a declared page input. |
| Passing values | Use the Page Inputs field in the Go to Page action to pass values when navigating. Or include them in the URL query string directly for deep links. |
| Reading values | Access declared inputs in page expressions as page inputs — typically via the page's context object. |
Routing Summary
Note: Dynamic params (URL path segments like /orders/:orderId) are best for identifying the main subject of the page — the record being viewed. Query parameters (URL query string like ?tab=overview) are best for supplemental context like active tab, filter state, or display preferences. Both are readable in the page via expressions.
| Scenario | Mechanism | Example URL |
| Fixed page with no context | Static slug | /dashboard |
| Detail page for a specific record | Dynamic URL segment | /orders/ORD-2847/details |
| Page with supplemental context | Query string parameter | /dashboard?tab=overview |
| Detail page with supplemental context | Both — dynamic segment + query param | /orders/ORD-2847/details?tab=history |
| External URL or legacy link | Go to URL action | Any absolute URL |