Unify Logo Footer.svg
Unify Applications
Logo
Path Tree and URLs

Path Tree and URLs

Logo

6 mins READ

URL Structure

Every page in a UnifyApps application lives at a deterministic URL. The URL is assembled from three parts:

https://<host>/<app-slug>/<page-path>

  • <host> — the domain where your application is deployed (e.g. app.yourcompany.com).

  • <app-slug> — a unique identifier for the application, set in App Settings → General. This is fixed after the first publish and cannot be changed without breaking existing links.

  • <page-path> — derived automatically from the folder and page structure in the Pages panel. The path is the concatenation of parent folder slugs and the page's own slug, separated by slashes.

📄 Example — URL construction

Given this Pages panel hierarchy:

App (slug: "ops-portal") ├── Dashboard (slug: dashboard) → /ops-portal/dashboard └── Orders/ (folder slug: orders) ├── Order List (slug: list) → /ops-portal/orders/list └── Order Details (slug: detail) → /ops-portal/orders/detail

The root-level Dashboard page gets a single-segment path. Pages nested inside the Orders folder inherit the orders prefix.

How the Page Path Mirrors the Folder Hierarchy

The Pages panel displays your app's pages and folders in a tree. This tree is the source of truth for URL construction — the URL path is a direct mirror of the tree depth and the slugs assigned to each node.

Key rules:

  • A page at the root of the tree has a one-segment path: /app-slug/page-slug.

  • A page inside a folder gets the folder's slug prepended: /app-slug/folder-slug/page-slug.

  • Folders can be nested to any depth. Each additional level adds one path segment: /app-slug/level1/level2/page-slug.

  • Folders themselves do not have pages — they are organizational containers only. If a user navigates to a folder URL (e.g. /app-slug/orders), the platform either 404s or redirects to the folder's configured index page, depending on your settings.

  • Moving a page between folders changes its URL. Existing bookmarks and external links to the old URL will break unless you add a redirect from the old path in App Settings → Redirects.

Warning: Changing a folder's slug propagates to every page inside it. A folder with 20 pages will have all 20 URLs changed at once. Set up redirects before publishing, or coordinate the rename with any teams that have bookmarked or linked to those pages.

Dynamic Path Segments

A page can declare a dynamic segment — a portion of its URL path that is replaced at runtime with a specific value, such as a record ID. Dynamic segments are declared as path parameters in Page Settings.

A page named "Order Details" with a :orderId path parameter gets the URL:

/app-slug/orders/:orderId

When navigating to this page, you supply a concrete value for orderId. The resulting URL might be:

/ops-portal/orders/order-8821

To declare a path parameter:

  1. Open Page Settings: Right-click the page in the Pages panel and select Page Settings, or click the settings icon next to the page name.

  2. Add a path parameter: In the Parameters section, click + Add Parameter. Set the parameter name (e.g. orderId), set Source to Path, and choose a type (typically String or Number).

  3. Reference the parameter in bindings: The parameter is now available as {{page.params.orderId}} anywhere on the page. Pass it to data source queries, use it in conditional logic, or display it directly in a text component.

Query Parameters

Query parameters appear after the ? in a URL. They are optional key-value pairs that do not affect routing — any page can receive any query parameter. There are two ways query parameters arrive on a page:

  • Navigate action page inputs: When you configure a Navigate action and supply page inputs, those inputs are serialized as query parameters: /orders/list?status=open&assignee=user42.

  • Manual URL manipulation: The Set URL Parameters action updates the query string in place without triggering a full navigation. This is useful for syncing filter/sort state to the URL so users can bookmark or share filtered views.

Declare query parameters in Page Settings to get typed access and autocompletion in bindings. Undeclared query parameters are accessible via {{page.queryParams}} as raw strings but do not get type conversion.

Current URL Bindings

UnifyApps exposes the current page's URL state through the page binding namespace. These bindings are reactive — they update automatically when the URL changes.

BindingTypeDescription
{{page.url}}stringThe full current URL including protocol, host, path, and query string. Example: https://app.co/ops-portal/orders/8821?tab=history.
{{page.path}}stringThe pathname only — everything after the host and before the query string. Example: /ops-portal/orders/8821.
{{page.queryParams}}objectAll current query parameters as a key-value object. Example: { "tab": "history", "page": "2" }.
{{page.queryParams.key}}stringA specific query parameter by key. Declared parameters are type-converted; undeclared ones are always strings. Example: {{page.queryParams.tab}} returns "history".
{{page.params.paramName}}any (declared type)A named path parameter declared in Page Settings. Example: {{page.params.orderId}} returns "8821" (or a number if declared as Number type).
{{page.hash}}stringThe URL fragment — the part after #. Rarely used in UnifyApps apps but available for deep-linking into specific sections via anchor IDs.

Canonical URLs and Deep-Linking

Every page in a UnifyApps app is directly accessible by URL — there is no "session state" that must be set up first to visit a page. This means:

  • All pages support deep-linking. You can share a link to any page, including pages with path parameters and query parameters, and the recipient will land directly on that page in the correct state.

  • Dynamic pages require the parameter value in the URL. A link to /orders/:orderId without supplying an orderId value is invalid — the platform will return a 404 or redirect to the default page.

  • Authentication is enforced before the page loads. A recipient who is not authenticated will be redirected to the login page. After successful authentication, they are redirected back to the original URL.

Tip: If your page has filters (status, date range, assignee), wire them to query parameters using the Set URL Parameters action. This makes filtered views shareable — the recipient lands on the page with the same filters applied. It also lets users bookmark a filtered view.

History Modes: pushState vs replaceState

The Navigate action's historyMode property controls whether the navigation adds a new browser history entry or replaces the current one.

ModeHTML5 APIEffect on back buttonUse when
Push (default)history.pushState()Back button returns to the previous page. The old URL remains in the history stack.Normal forward navigation — drilling into a detail, moving to the next step in a wizard, opening a new section. The vast majority of navigations should use Push.
Replacehistory.replaceState()Back button skips the current page and returns to the page before it. The old URL is removed from the history stack.Redirects that should not be revisitable (post-login redirect, post-save redirect, error state recovery). Also useful when updating query parameters in-place — Set URL Parameters always uses Replace.

Note: The Set URL Parameters action updates the query string of the current page without triggering a navigation. It always uses replaceState so that updating a filter does not add a history entry that the user has to back through.

Practical Patterns

Copying the current URL to the clipboard

Wire a "Copy Link" button to a Run JavaScript action with:

navigator.clipboard.writeText({{page.url}})

Construct a shareable URL string in a binding:

{{ "https://app.yourcompany.com/ops-portal/orders/" + page.params.orderId + "?tab=history" }}

Syncing an active tab to the URL

Bind a Tab component's active tab to a query parameter, and wire the tab's onChange event to a Set URL Parameters action that updates tab. On page load, read {{page.queryParams.tab}} as the initial active tab value.