Overlays can configure whether their history state is reflected the
browser's address bar
and in the document <head>
. This property is called history visibility.
A render pass will only update the address bar if it both changes history and the updated layer has visible history:
Link updates history? | Layer has visible history? | Address bar changed? |
---|---|---|
yes | yes | ✔️ yes |
yes | no | ❌ no |
no | yes | ❌ no |
no | no | ❌ no |
Note
When a link updates another layer, only the history visibility of the targeted layer is considered. Settings for the link's own layer is not relevant.
By default overlays will have visible history if their initial fragment is a main element. The intent is to reveal the location of significant content to the user, but hide the internal location of smaller popups or menus.
To override this default, use one of the following methods:
[up-history]
attribute on a link or form that opens an overlay.
For example, a link with [up-history=false]
will open an overlay that never changes the address bar.up.layer.config.overlay.history
. This will be the default for future overlays. The default can
be overridden with an [up-history]
attribute or { history }
option.up.layer.configure.popup.history = false
will disable history visibility for all future popups.up.layer.open()
or up.layer.ask()
,
pass a { history }
option to configure history visibility for that new overlay.Note
The root layer always has visible history. This cannot be configured.
When an overlay has visible history, its location and title are shown in the browser window while
the overlay is open. Also meta tags from the overlay content will be placed into the <head>
.
In the example below, we start with a root layer on the /
path:
location.pathname // => "/"
We now open a new overlay with visible overlay. Note how its URL /overlay
is reflected in the browser's address bar (location.pathname
):
await up.layer.open({ url: '/overlay', history: true }) // mark-phrase "true"
location.pathname // => "/overlay"
You can still access the tracked location for each individual layer:
up.layer.current.location // => "/overlay"
up.layer.root.location // => "/"
When the overlay is closed, the root layer's URL, title and meta tags are restored:
await up.layer.dismiss()
location.pathname // => "/"
If visible history is disabled, its history state will never be reflected in the browser window or document <head>
,
as long as the overlay is open.
In the example below, we open an overlay with invisible history from the URL /overlay
.
Note how the browser's address bar remains on the root layer's location (/
):
location.pathname // => "/"
await up.layer.open({ url: '/overlay', history: false }) // mark-phrase "false"
location.pathname // => "/"
Overlays with invisible history still track their location using the rules described above. You can access the tracked location for each individual layer:
up.layer.current.location // => "/"
up.layer.root.location // => "/"
location.pathname // => "/"
History visibility is not required for .up-current
classes to be set.
When a navigation bar identifies links pointing to the current page,
it compares a link's [href]
with the location tracked in up.layer.current.location
.
When an overlay with invisible history opens another overlay, the nested overlay is forced to also have invisible history.
This cannot be overridden with { history: true }
.
When a previous history is restored while an overlay is open, all overlays will be closed. The restored URL will be rendered in the root layer.
This behavior may cause overlay content to display as a full pages. In a canonic Unpoly app this is a good default, as Unpoly encourages all server routes to be prepared to render full HTML pages. In particular subinteractions make it easy to implement interactions that work both on the root layer, and in an overlay.
If you absolutely cannot work with the way Unpoly restores history with overlays, you have the following options:
up.layer.config.overlay.history = false
.