Every dashboard page runs in a scope. A scope is either a specific site or the Wix user's account. Cross-scope navigation moves the Wix user from 1 scope to another, for example from a site's dashboard to their account, or from their account into a site.
A scope is 1 of 2 kinds of dashboard a Wix user can be in:
You can move a Wix user between scopes with navigate(). This works between a site and the account in either direction, and also directly between 2 sites. The account scope isn't a required stop along the way, so you don't have to route a site-to-site switch through it.
Navigating in a scope is an in-app transition. Moving between scopes means loading a different dashboard. Specify a scope in the destination to move the Wix user to another scope:
A cross-scope navigation is a full page load, unlike an in-scope navigation. navigate() returns void either way, which makes a scope switch one-way. The dashboard tears down the calling page, so there's no response to inspect and no code runs after it succeeds.
Add a pageId to deep-link into the target scope, and a relativeUrl alongside it to restore that page's internal state. This is the same relativeUrl described in Using relativeUrl for internal navigation, applied once the target scope loads:
Without a pageId, the Wix user lands on the target scope's default page. The same thing happens if the page you name isn't available there, rather than the Wix user hitting a "Page Not Found". For example, the page isn't available if your app isn't installed in that scope.
A scope describes where the Wix user should end up, not that a switch has to happen. If they're already there, navigate() falls back to same-scope behavior. With a pageId it performs an ordinary in-scope navigation to that page, and without a pageId it does nothing. This means you can specify a scope unconditionally without first checking where the Wix user is, with 1 exception. displayMode: "overlay" requires a pageId and throws without one, even when the scope doesn't change.
A full page load drops any in-memory state your page was holding. To hand some context to the target scope, specify scopeQueryParams. The dashboard adds these to the target scope's URL for your code to read after landing:
2 constraints apply:
ws for its own deep-linking and drops them.scopeQueryParams requires a scope. For query params scoped to a page, use relativeUrl instead.Because these values land in the URL, they're visible in the address bar, the browser's history, and referrer headers, so never carry secrets in them.
history and displayMode work the same as they do for an in-scope navigation, but they act on the scope switch:
history applies to the page the Wix user is leaving. "replace" keeps the source page out of their session history, so clicking Back doesn't take them back to the scope they just left. The landing page itself is always applied as a replace, so clicking Back never returns them to it.displayMode takes effect when the target scope loads. "main" and "auto" render the deep-linked page as the main page. "overlay" opens it as an overlay over the target scope's default page, and requires a pageId. Without a pageId there's nothing to overlay.If the current page has registered an onBeforeUnload() handler, the dashboard prompts the Wix user before the switch. If they cancel, the dashboard abandons the navigation and leaves them on the current page. Since navigate() returns void, this is silent. navigate() doesn't throw and your code can't detect the cancellation, so don't assume a call to navigate() with a scope has taken effect.
Moving into a site scope requires that the Wix user has access to that site. navigate() doesn't check this before starting the switch. If the Wix user doesn't have access to the target site, Wix's own access control refuses the navigation once it reaches that site, rather than navigate() failing on the calling page.
Last updated: 17 September 2026