diff --git a/files/en-us/web/api/navigateevent/canintercept/index.md b/files/en-us/web/api/navigateevent/canintercept/index.md new file mode 100644 index 000000000000000..c3a742cc5984391 --- /dev/null +++ b/files/en-us/web/api/navigateevent/canintercept/index.md @@ -0,0 +1,79 @@ +--- +title: NavigateEvent.canIntercept +slug: Web/API/NavigateEvent/canIntercept +page-type: web-api-instance-property +tags: + - API + - canIntercept + - Experimental + - History + - Navigate + - NavigateEvent + - Navigation + - Navigation API + - Property + - Read-only + - Reference + - Scroll + - Traversal +browser-compat: api.NavigateEvent.canIntercept +--- + +{{APIRef("Navigation API")}}{{seecompattable}} + +The **`canIntercept`** read-only property of the +{{domxref("NavigateEvent")}} interface returns `true` if the navigation can be intercepted and have its URL rewritten, or `false` otherwise + +There are several rules around when a navigation can be intercepted. For example: + +- You can't intercept cross-origin navigations. +- You can intercept `http` or `https` URLs if only the `path`, `query`, and `fragment` portions of the new URL differ from the current URL. +- You can intercept `file` URLs if only the `query` and `fragment` portions of the new URL differ. +- For other URL types you can intercept the navigation if only the `fragment` portion differs. + +See the spec for more explanation on [when a Document can have its URL rewritten](https://html.spec.whatwg.org/multipage/nav-history-apis.html#can-have-its-url-rewritten), including a table of examples. + +## Value + +A boolean value—`true` if the navigation can be intercepted, `false` if not. + +## Examples + +```js +navigation.addEventListener("navigate", event => { + // Some navigations, e.g. cross-origin navigations, we + // cannot intercept. Let the browser handle those normally. + if (!event.canIntercept) { + return; + } + + // Don't intercept fragment navigations or downloads. + if (event.hashChange || event.downloadRequest !== null) { + return; + } + + event.intercept({ + handler() { + if (event.formData) { + processFormDataAndUpdateUI(event.formData, event.signal); + } else { + doSinglePageAppNav(event.destination, event.signal); + } + } + }); +}); +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- [Modern client-side routing: the Navigation API](https://developer.chrome.com/docs/web-platform/navigation-api/) +- [Navigation API explainer](https://github.com/WICG/navigation-api/blob/main/README.md) +- Domenic Denicola's [Navigation API live demo](https://gigantic-honored-octagon.glitch.me/) diff --git a/files/en-us/web/api/navigateevent/destination/index.md b/files/en-us/web/api/navigateevent/destination/index.md new file mode 100644 index 000000000000000..4f75521707d6cdd --- /dev/null +++ b/files/en-us/web/api/navigateevent/destination/index.md @@ -0,0 +1,71 @@ +--- +title: NavigateEvent.destination +slug: Web/API/NavigateEvent/destination +page-type: web-api-instance-property +tags: + - API + - destination + - Experimental + - History + - Navigate + - NavigateEvent + - Navigation + - Navigation API + - Property + - Read-only + - Reference + - Scroll + - Traversal +browser-compat: api.NavigateEvent.destination +--- + +{{APIRef("Navigation API")}}{{seecompattable}} + +The **`destination`** read-only property of the +{{domxref("NavigateEvent")}} interface returns a {{domxref("NavigationDestination")}} object representing the destination being navigated to. + +## Value + +A {{domxref("NavigationDestination")}} object. + +## Examples + +```js +navigation.addEventListener('navigate', (event) => { + // Exit early if this navigation shouldn't be intercepted, + // e.g. if the navigation is cross-origin, or a download request + if (shouldNotIntercept(event)) { + return; + } + + const url = new URL(event.destination.url); + + if (url.pathname.startsWith('/articles/')) { + event.intercept({ + async handler() { + // The URL has already changed, so show a placeholder while + //fetching the new content, such as a spinner or loading page + renderArticlePagePlaceholder(); + + // Fetch the new content and display when ready + const articleContent = await getArticleContent(url.pathname); + renderArticlePage(articleContent); + }, + }); + } +}); +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- [Modern client-side routing: the Navigation API](https://developer.chrome.com/docs/web-platform/navigation-api/) +- [Navigation API explainer](https://github.com/WICG/navigation-api/blob/main/README.md) +- Domenic Denicola's [Navigation API live demo](https://gigantic-honored-octagon.glitch.me/) diff --git a/files/en-us/web/api/navigateevent/downloadrequest/index.md b/files/en-us/web/api/navigateevent/downloadrequest/index.md new file mode 100644 index 000000000000000..d99b907fa589379 --- /dev/null +++ b/files/en-us/web/api/navigateevent/downloadrequest/index.md @@ -0,0 +1,70 @@ +--- +title: NavigateEvent.downloadRequest +slug: Web/API/NavigateEvent/downloadRequest +page-type: web-api-instance-property +tags: + - API + - downloadRequest + - Experimental + - History + - Navigate + - NavigateEvent + - Navigation + - Navigation API + - Property + - Read-only + - Reference + - Scroll + - Traversal +browser-compat: api.NavigateEvent.downloadRequest +--- + +{{APIRef("Navigation API")}}{{seecompattable}} + +The **`downloadRequest`** read-only property of the +{{domxref("NavigateEvent")}} interface returns the filename of the file requested for download, in the case of a download navigation (e.g. an {{htmlelement("a")}} or {{htmlelement("area")}} element with a `download` attribute), or `null` otherwise. + +## Value + +A string containing the filename of the file requested for download, or `null`. + +## Examples + +```js +navigation.addEventListener("navigate", (event) => { + // Some navigations, e.g. cross-origin navigations, we + // cannot intercept. Let the browser handle those normally. + if (!event.canIntercept) { + return; + } + + // Don't intercept fragment navigations or downloads. + if (event.hashChange || event.downloadRequest !== null) { + return; + } + + event.intercept({ + handler() { + if (event.formData) { + processFormDataAndUpdateUI(event.formData, event.signal); + } else { + doSinglePageAppNav(event.destination, event.signal); + } + } + }); +}); +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- [Modern client-side routing: the Navigation API](https://developer.chrome.com/docs/web-platform/navigation-api/) +- [Navigation API explainer](https://github.com/WICG/navigation-api/blob/main/README.md) +- Domenic Denicola's [Navigation API live demo](https://gigantic-honored-octagon.glitch.me/) diff --git a/files/en-us/web/api/navigateevent/formdata/index.md b/files/en-us/web/api/navigateevent/formdata/index.md new file mode 100644 index 000000000000000..f8aa3602366afac --- /dev/null +++ b/files/en-us/web/api/navigateevent/formdata/index.md @@ -0,0 +1,70 @@ +--- +title: NavigateEvent.formData +slug: Web/API/NavigateEvent/formData +page-type: web-api-instance-property +tags: + - API + - Experimental + - formData + - History + - Navigate + - NavigateEvent + - Navigation + - Navigation API + - Property + - Read-only + - Reference + - Scroll + - Traversal +browser-compat: api.NavigateEvent.formData +--- + +{{APIRef("Navigation API")}}{{seecompattable}} + +The **`formData`** read-only property of the +{{domxref("NavigateEvent")}} interface returns the {{domxref("FormData")}} object representing the submitted data in the case of a [`POST`](/en-US/docs/Web/HTTP/Methods/POST) form submission, or `null` otherwise. + +## Value + +A {{domxref("FormData")}} object, or `null`. + +## Examples + +```js +navigation.addEventListener("navigate", (event) => { + // Some navigations, e.g. cross-origin navigations, we + // cannot intercept. Let the browser handle those normally. + if (!event.canIntercept) { + return; + } + + // Don't intercept fragment navigations or downloads. + if (event.hashChange || event.downloadRequest !== null) { + return; + } + + event.intercept({ + handler() { + if (event.formData) { + processFormDataAndUpdateUI(event.formData, event.signal); + } else { + doSinglePageAppNav(event.destination, event.signal); + } + } + }); +}); +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- [Modern client-side routing: the Navigation API](https://developer.chrome.com/docs/web-platform/navigation-api/) +- [Navigation API explainer](https://github.com/WICG/navigation-api/blob/main/README.md) +- Domenic Denicola's [Navigation API live demo](https://gigantic-honored-octagon.glitch.me/) diff --git a/files/en-us/web/api/navigateevent/hashchange/index.md b/files/en-us/web/api/navigateevent/hashchange/index.md new file mode 100644 index 000000000000000..519b3578f0a3e2b --- /dev/null +++ b/files/en-us/web/api/navigateevent/hashchange/index.md @@ -0,0 +1,70 @@ +--- +title: NavigateEvent.hashChange +slug: Web/API/NavigateEvent/hashChange +page-type: web-api-instance-property +tags: + - API + - Experimental + - hashChange + - History + - Navigate + - NavigateEvent + - Navigation + - Navigation API + - Property + - Read-only + - Reference + - Scroll + - Traversal +browser-compat: api.NavigateEvent.hashChange +--- + +{{APIRef("Navigation API")}}{{seecompattable}} + +The **`hashChange`** read-only property of the +{{domxref("NavigateEvent")}} interface returns `true` if the navigation is a fragment navigation (i.e. to a fragment identifier in the same document), or `false` otherwise. + +## Value + +A boolean value—`true` if the navigation is a fragment navigation, `false` if not. + +## Examples + +```js +navigation.addEventListener("navigate", (event) => { + // Some navigations, e.g. cross-origin navigations, we + // cannot intercept. Let the browser handle those normally. + if (!event.canIntercept) { + return; + } + + // Don't intercept fragment navigations or downloads. + if (event.hashChange || event.downloadRequest !== null) { + return; + } + + event.intercept({ + handler() { + if (event.formData) { + processFormDataAndUpdateUI(event.formData, event.signal); + } else { + doSinglePageAppNav(event.destination, event.signal); + } + } + }); +}); +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- [Modern client-side routing: the Navigation API](https://developer.chrome.com/docs/web-platform/navigation-api/) +- [Navigation API explainer](https://github.com/WICG/navigation-api/blob/main/README.md) +- Domenic Denicola's [Navigation API live demo](https://gigantic-honored-octagon.glitch.me/) diff --git a/files/en-us/web/api/navigateevent/index.md b/files/en-us/web/api/navigateevent/index.md new file mode 100644 index 000000000000000..4e7c44bf7ebb331 --- /dev/null +++ b/files/en-us/web/api/navigateevent/index.md @@ -0,0 +1,130 @@ +--- +title: NavigateEvent +slug: Web/API/NavigateEvent +page-type: web-api-interface +tags: + - API + - Experimental + - History + - Interface + - Landing + - Navigate + - NavigateEvent + - Navigation API + - Reference + - Scroll + - Traversal +browser-compat: api.NavigateEvent +--- + +{{APIRef("Navigation API")}}{{seecompattable}} + +The **`NavigateEvent`** interface of the {{domxref("Navigation API", "Navigation API", "", "nocode")}} is the event object for the {{domxref("Navigation/navigate_event", "navigate")}} event, which fires when [any type of navigation](https://github.com/WICG/navigation-api#appendix-types-of-navigations) is initiated (this includes usage of {{domxref("History API", "History API", "", "nocode")}} features like {{domxref("History.go()")}}). `NavigateEvent` provides access to information about that navigation, and allows developers to intercept and control the navigation handling. + +{{InheritanceDiagram}} + +## Constructor + +- {{domxref("NavigateEvent.NavigateEvent", "NavigateEvent()")}} + - : Creates a new `NavigateEvent` object instance. + +## Instance properties + +_Inherits properties from its parent, {{DOMxRef("Event")}}._ + +- {{domxref("NavigateEvent.canIntercept", "canIntercept")}} {{ReadOnlyInline}} + - : Returns `true` if the navigation can be intercepted, or `false` otherwise (e.g. you can't intercept a cross-origin navigation). +- {{domxref("NavigateEvent.destination", "destination")}} {{ReadOnlyInline}} + - : Returns a {{domxref("NavigationDestination")}} object representing the destination being navigated to. +- {{domxref("NavigateEvent.downloadRequest", "downloadRequest")}} {{ReadOnlyInline}} + - : Returns the filename of the file requested for download, in the case of a download navigation (e.g. an {{htmlelement("a")}} or {{htmlelement("area")}} element with a `download` attribute), or `null` otherwise. +- {{domxref("NavigateEvent.formData", "formData")}} {{ReadOnlyInline}} + - : Returns the {{domxref("FormData")}} object representing the submitted data in the case of a `POST` form submission, or `null` otherwise. +- {{domxref("NavigateEvent.hashChange", "hashChange")}} {{ReadOnlyInline}} + - : Returns `true` if the navigation is a fragment navigation (i.e. to a fragment identifier in the same document), or `false` otherwise. +- {{domxref("NavigateEvent.info", "info")}} {{ReadOnlyInline}} + - : Returns the `info` data value passed by the initiating navigation operation (e.g. {{domxref("Navigation.back()")}}, or {{domxref("Navigation.navigate()")}}), or `undefined` if no `info` data was passed. +- {{domxref("NavigateEvent.navigationType", "navigationType")}} {{ReadOnlyInline}} + - : Returns the type of the navigation — `push`, `reload`, `replace`, or `traverse`. +- {{domxref("NavigateEvent.signal", "signal")}} {{ReadOnlyInline}} + - : Returns an {{domxref("AbortSignal")}}, which will become aborted if the navigation is cancelled (e.g. by the user pressing the browser's "Stop" button, or another navigation starting and thus cancelling the ongoing one). +- {{domxref("NavigateEvent.userInitiated", "userInitiated")}} {{ReadOnlyInline}} + - : Returns `true` if the navigation was initiated by the user (e.g. by clicking a link, submitting a form, or pressing the browser's "Back"/"Forward" buttons), or `false` otherwise. + +## Instance methods + +_Inherits methods from its parent, {{DOMxRef("Event")}}._ + +- {{domxref("NavigateEvent.intercept", "intercept()")}} + - : Intercepts this navigation, turning it into a same-document navigation to the {{domxref("NavigationDestination.url", "destination")}} URL. It can accept a handler function that defines what the navigation handling behavior should be, plus `focusReset` and `scroll` options to control behavior as desired. +- {{domxref("NavigateEvent.scroll", "scroll()")}} + - : Can be called to manually trigger the browser-driven scrolling behavior that occurs in response to the navigation, if you want it to happen before the navigation handling has completed. + +## Examples + +### Handling a navigation using `intercept()` + +```js +navigation.addEventListener('navigate', event => { + // Exit early if this navigation shouldn't be intercepted, + // e.g. if the navigation is cross-origin, or a download request + if (shouldNotIntercept(event)) return; + + const url = new URL(event.destination.url); + + if (url.pathname.startsWith('/articles/')) { + event.intercept({ + async handler() { + // The URL has already changed, so show a placeholder while + //fetching the new content, such as a spinner or loading page + renderArticlePagePlaceholder(); + + // Fetch the new content and display when ready + const articleContent = await getArticleContent(url.pathname); + renderArticlePage(articleContent); + }, + }); + } +}); +``` + +> **Note:** Before the Navigation API was available, to do something similar you'd have to listen for all click events on links, run `e.preventDefault()`, perform the appropriate {{domxref("History.pushState()")}} call, then set up the page view based on the new URL. And this wouldn't handle all navigations — only user-initiated link clicks. + +### Handling scrolling using `scroll()` + +In this example of intercepting a navigation, the `handler()` function starts by fetching and rendering some article content, but then fetches and renders some secondary content afterwards. It makes sense to scroll the page to the main article content as soon as it is available so the user can interact with it, rather than waiting until the secondary content is also rendered. To achieve this, we have added a {{domxref("NavigateEvent.scroll", "scroll()")}} call between the two. + +```js +navigation.addEventListener('navigate', event => { + if (shouldNotIntercept(navigateEvent)) return; + const url = new URL(event.destination.url); + + if (url.pathname.startsWith('/articles/')) { + event.intercept({ + async handler() { + const articleContent = await getArticleContent(url.pathname); + renderArticlePage(articleContent); + + event.scroll(); + + const secondaryContent = await getSecondaryContent(url.pathname); + addSecondaryContent(secondaryContent); + }, + }); + } +}); +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- [Modern client-side routing: the Navigation API](https://developer.chrome.com/docs/web-platform/navigation-api/) +- [Navigation API explainer](https://github.com/WICG/navigation-api/blob/main/README.md) +- Domenic Denicola's [Navigation API live demo](https://gigantic-honored-octagon.glitch.me/) diff --git a/files/en-us/web/api/navigateevent/info/index.md b/files/en-us/web/api/navigateevent/info/index.md new file mode 100644 index 000000000000000..072b647d1b94c65 --- /dev/null +++ b/files/en-us/web/api/navigateevent/info/index.md @@ -0,0 +1,73 @@ +--- +title: NavigateEvent.info +slug: Web/API/NavigateEvent/info +page-type: web-api-instance-property +tags: + - API + - Experimental + - History + - info + - Navigate + - NavigateEvent + - Navigation + - Navigation API + - Property + - Read-only + - Reference + - Scroll + - Traversal +browser-compat: api.NavigateEvent.info +--- + +{{APIRef("Navigation API")}}{{seecompattable}} + +The **`info`** read-only property of the +{{domxref("NavigateEvent")}} interface returns the `info` data value passed by the initiating navigation operation (e.g. {{domxref("Navigation.back()")}}, or {{domxref("Navigation.navigate()")}}), or `undefined` if no `info` data was passed. + +## Value + +The `info` value passed by the initiating navigation operation, or `undefined` if none was passed. + +## Examples + +One example of how `info` might be used is to trigger different single-page navigation renderings depending on how a certain route was reached. For example, consider a photo gallery app, where you can reach the same photo URL and state via various routes. You might want to use a different animation to show the photo for each route. + +```js +navigation.addEventListener("navigate", (event) => { + if (isPhotoNavigation(event)) { + event.intercept({ async handler() { + switch (event.info.?via) { + case "go-left": { + await animateLeft(); + break; + } + case "go-right": { + await animateRight(); + break; + } + case "gallery": { + await animateZoomFromThumbnail(event.info.thumbnail); + break; + } + } + + // TODO: actually load the photo. + } }); + } +}); +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- [Modern client-side routing: the Navigation API](https://developer.chrome.com/docs/web-platform/navigation-api/) +- [Navigation API explainer](https://github.com/WICG/navigation-api/blob/main/README.md) +- Domenic Denicola's [Navigation API live demo](https://gigantic-honored-octagon.glitch.me/) +- Methods that allow info to be passed — {{domxref("Navigation.back()")}}, {{domxref("Navigation.forward()")}}, {{domxref("Navigation.navigate()")}}, {{domxref("Navigation.reload()")}}, and {{domxref("Navigation.traverseTo()")}} diff --git a/files/en-us/web/api/navigateevent/intercept/index.md b/files/en-us/web/api/navigateevent/intercept/index.md new file mode 100644 index 000000000000000..7776033fa511a55 --- /dev/null +++ b/files/en-us/web/api/navigateevent/intercept/index.md @@ -0,0 +1,133 @@ +--- +title: NavigateEvent.intercept() +slug: Web/API/NavigateEvent/intercept +page-type: web-api-instance-method +tags: + - API + - Experimental + - History + - intercept + - Method + - NavigateEvent + - Navigation + - Navigation API + - Reference + - Scroll + - transition + - Traversal +browser-compat: api.NavigateEvent.intercept +--- + +{{APIRef("Navigation API")}}{{seecompattable}} + +The **`intercept()`** method of the +{{domxref("NavigateEvent")}} interface intercepts this navigation, turning it into a same-document navigation to the {{domxref("NavigationDestination.url", "destination")}} URL. + +## Syntax + +```js-nolint +intercept() +intercept(options) +``` + +### Parameters + +- `options` {{optional_inline}} + - : An options object containing the following properties: + - `handler` + - : A callback function that defines what the navigation handling behavior should be. This generally handles resource fetching, and returns a promise. + - `focusReset` {{optional_inline}} + - : Defines the navigation's focus behavior. This may take one of the following values: + - `after-transition` + - : Once the promise returned by your handler function resolves, the browser will focus the first element with the [`autofocus`](/en-US/docs/Web/HTML/Global_attributes/autofocus) attribute, or the {{htmlelement("body")}} element if no element has `autofocus` set. This is the default value. + - `manual` + - : Disable the default behavior. + - `scroll` {{optional_inline}} + - : Defines the navigation's scrolling behavior. This may take one of the following values: + - `after-transition` + - : Allow the browser to handle scrolling, for example by scrolling to the relevant fragment identifier if the URL contains a fragment, or restoring the scroll position to the same place as last time if the page is reloaded or a page in the history is revisited. This is the default value. + - `manual` + - : Disable the default behavior. + +### Return value + +None (`undefined`). + +### Exceptions + +- `InvalidStateError` {{domxref("DOMException")}} + - : Thrown if the current {{domxref("Document")}} is not yet active, or if the navigation has been cancelled. +- `SecurityError` {{domxref("DOMException")}} + - : Thrown if the event was dispatched by a {{domxref("EventTarget.dispatchEvent", "dispatchEvent()")}} call, rather than the user agent, or if the navigation cannot be intercepted (i.e. {{domxref("NavigateEvent.canIntercept")}} is `false`). + +## Examples + +### Handling a navigation using `intercept()` + +```js +navigation.addEventListener('navigate', event => { + // Exit early if this navigation shouldn't be intercepted, + // e.g. if the navigation is cross-origin, or a download request + if (shouldNotIntercept(event)) return; + + const url = new URL(event.destination.url); + + if (url.pathname.startsWith('/articles/')) { + event.intercept({ + async handler() { + // The URL has already changed, so show a placeholder while + //fetching the new content, such as a spinner or loading page + renderArticlePagePlaceholder(); + + // Fetch the new content and display when ready + const articleContent = await getArticleContent(url.pathname); + renderArticlePage(articleContent); + }, + }); + } +}); +``` + +### Using `focusReset` and `scroll` + +Form submission can be detected by querying for the {{domxref("NavigateEvent.formData")}} property. The following example turns any form submission into one which stays on the current page. In this case, you don't update the DOM, so you can cancel any default reset and scroll behavior using `focusReset` and `scroll`. + +```js +navigation.addEventListener('navigate', (event) => { + if (event.formData && event.canIntercept) { + // User submitted a POST form to a same-domain URL + // (If canIntercept is false, the event is just informative: + // you can't intercept this request, although you could + // likely still call .preventDefault() to stop it completely). + + event.intercept({ + // Since we don't update the DOM in this navigation, + // don't allow focus or scrolling to reset: + focusReset: 'manual', + scroll: 'manual', + async handler() { + await fetch(event.destination.url, { + method: 'POST', + body: event.formData, + }); + // You could navigate again with {history: 'replace'} to change the URL here, + // which might indicate "done" + }, + }); + } +}); +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- [Modern client-side routing: the Navigation API](https://developer.chrome.com/docs/web-platform/navigation-api/) +- [Navigation API explainer](https://github.com/WICG/navigation-api/blob/main/README.md) +- Domenic Denicola's [Navigation API live demo](https://gigantic-honored-octagon.glitch.me/) diff --git a/files/en-us/web/api/navigateevent/navigateevent/index.md b/files/en-us/web/api/navigateevent/navigateevent/index.md new file mode 100644 index 000000000000000..ce5ebdcd857d771 --- /dev/null +++ b/files/en-us/web/api/navigateevent/navigateevent/index.md @@ -0,0 +1,98 @@ +--- +title: NavigateEvent() +slug: Web/API/NavigateEvent/NavigateEvent +page-type: web-api-constructor +tags: + - API + - Constructor + - Experimental + - History + - Navigate + - NavigateEvent + - Navigation + - Navigation API + - Reference + - Scroll + - Traversal +browser-compat: api.NavigateEvent.NavigateEvent +--- + +{{APIRef("Navigation API")}}{{seecompattable}} + +The **`NavigateEvent()`** constructor creates a new +{{domxref("NavigateEvent")}} object instance. + +## Syntax + +```js-nolint +new NavigateEvent(type, init) +``` + +### Parameters + +- `type` + - : A string representing the type of event. In the case of `NavigateEvent` this is always `navigate`. +- `init` + - : An object containing the following properties: + - `canIntercept` {{optional_inline}} + - : A boolean defining whether the navigation can be intercepted or not (e.g. you can't intercept a cross-origin navigation). Defaults to `false`. + - `destination` + - : A {{domxref("NavigationDestination")}} object representing the location being navigated to. + - `downloadRequest` {{optional_inline}} + - : The filename of the file requested for download, in the case of a download navigation (e.g. an {{htmlelement("a")}} or {{htmlelement("area")}} element with a `download` attribute). Defaults to `null`. + - `formData` {{optional_inline}} + - : The {{domxref("FormData")}} object representing the submitted data in the case of a `POST` form submission. Defaults to `null`. + - `hashChange` {{optional_inline}} + - : A boolean defining if the navigation is a fragment navigation (i.e. to a fragment identifier in the same document). Defaults to `false`. + - `info` {{optional_inline}} + - : The `info` data value passed by the initiating navigation operation (e.g. {{domxref("Navigation.back()")}}, or {{domxref("Navigation.navigate()")}}). + - `navigationType` {{optional_inline}} + - : The type of the navigation. Possible values — `push`, `reload`, `replace`, and `traverse`. Defaults to `push`. + - `signal` + - : An {{domxref("AbortSignal")}}, which will become aborted if the navigation is cancelled (e.g. by the user pressing the browser's "Stop" button, or another navigation starting and thus cancelling the ongoing one). + - `userInitiated` {{optional_inline}} + - : A boolean defining whether the navigation was initiated by the user (e.g. by clicking a link, submitting a form, or pressing the browser's "Back"/"Forward" buttons). Defaults to `false`. + +## Examples + +A developer would not use this constructor manually. A new `NavigateEvent` object is constructed when a handler is invoked as a result of the {{domxref("Navigation.navigate_event", "navigate")}} event firing. + +```js +navigation.addEventListener('navigate', (event) => { + // Exit early if this navigation shouldn't be intercepted, + // e.g. if the navigation is cross-origin, or a download request + if (shouldNotIntercept(event)) { + return; + } + + const url = new URL(event.destination.url); + + if (url.pathname.startsWith('/articles/')) { + event.intercept({ + async handler() { + // The URL has already changed, so show a placeholder while + //fetching the new content, such as a spinner or loading page + renderArticlePagePlaceholder(); + + // Fetch the new content and display when ready + const articleContent = await getArticleContent(url.pathname); + renderArticlePage(articleContent); + }, + }); + } +}); +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- [Modern client-side routing: the Navigation API](https://developer.chrome.com/docs/web-platform/navigation-api/) +- [Navigation API explainer](https://github.com/WICG/navigation-api/blob/main/README.md) +- Domenic Denicola's [Navigation API live demo](https://gigantic-honored-octagon.glitch.me/) diff --git a/files/en-us/web/api/navigateevent/navigationtype/index.md b/files/en-us/web/api/navigateevent/navigationtype/index.md new file mode 100644 index 000000000000000..ee09d9ea28a3e61 --- /dev/null +++ b/files/en-us/web/api/navigateevent/navigationtype/index.md @@ -0,0 +1,87 @@ +--- +title: NavigateEvent.navigationType +slug: Web/API/NavigateEvent/navigationType +page-type: web-api-instance-property +tags: + - API + - Experimental + - History + - Navigate + - NavigateEvent + - Navigation + - Navigation API + - navigationType + - Property + - Read-only + - Reference + - Scroll + - Traversal +browser-compat: api.NavigateEvent.navigationType +--- + +{{APIRef("Navigation API")}}{{seecompattable}} + +The **`navigationType`** read-only property of the +{{domxref("NavigateEvent")}} interface returns the type of the navigation — `push`, `reload`, `replace`, or `traverse`. + +## Value + +An enumerated value representing the type of navigation. + +The possible values are: + +- `push`: A new location is navigated to, causing a new entry to be pushed onto the history list. +- `reload`: The {{domxref("Navigation.currentEntry")}} is reloaded. +- `replace`: The {{domxref("Navigation.currentEntry")}} is replaced with a new history entry. This new entry will reuse the same {{domxref("NavigationHistoryEntry.key", "key")}}, but be assigned a different {{domxref("NavigationHistoryEntry.id", "id")}}. +- `traverse`: The browser navigates from one existing history entry to another existing history entry. + +## Examples + +### Async transitions with special back/forward handling + +Sometimes it's desirable to handle back/forward navigations specially, e.g. reusing cached views by transitioning them onto the screen. This can be done by branching as follows: + +```js +navigation.addEventListener("navigate", (event) => { + // Some navigations, e.g. cross-origin navigations, we + // cannot intercept. Let the browser handle those normally. + if (!event.canIntercept) { + return; + } + + // Don't intercept fragment navigations or downloads. + if (event.hashChange || event.downloadRequest !== null) { + return; + } + + event.intercept({ async handler() { + if (myFramework.currentPage) { + await myFramework.currentPage.transitionOut(); + } + + let { key } = event.destination; + + if (event.navigationType === "traverse" && myFramework.previousPages.has(key)) { + await myFramework.previousPages.get(key).transitionIn(); + } else { + // This will probably result in myFramework storing + // the rendered page in myFramework.previousPages. + await myFramework.renderPage(event.destination); + } + } }); +}); +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- [Modern client-side routing: the Navigation API](https://developer.chrome.com/docs/web-platform/navigation-api/) +- [Navigation API explainer](https://github.com/WICG/navigation-api/blob/main/README.md) +- Domenic Denicola's [Navigation API live demo](https://gigantic-honored-octagon.glitch.me/) diff --git a/files/en-us/web/api/navigateevent/scroll/index.md b/files/en-us/web/api/navigateevent/scroll/index.md new file mode 100644 index 000000000000000..57822caedc55ee7 --- /dev/null +++ b/files/en-us/web/api/navigateevent/scroll/index.md @@ -0,0 +1,85 @@ +--- +title: NavigateEvent.scroll() +slug: Web/API/NavigateEvent/scroll +page-type: web-api-instance-method +tags: + - API + - Experimental + - History + - Method + - NavigateEvent + - Navigation + - Navigation API + - Reference + - Scroll + - transition + - Traversal +browser-compat: api.NavigateEvent.scroll +--- + +{{APIRef("Navigation API")}}{{seecompattable}} + +The **`scroll()`** method of the +{{domxref("NavigateEvent")}} interface can be called to manually trigger the browser-driven scrolling behavior that occurs in response to the navigation, if you want it to happen before the navigation handling has completed. + +## Syntax + +```js-nolint +scroll() +``` + +### Parameters + +None. + +### Return value + +`undefined`. + +### Exceptions + +- `InvalidStateError` {{domxref("DOMException")}} + - : Thrown if the current {{domxref("Document")}} is not yet active, if the navigation was not intercepted using {{domxref("NavigateEvent.intercept", "intercept()")}}, or if the default scroll behavior has already ocurred. + +## Examples + +### Handling scrolling using `scroll()` + +In this example of intercepting a navigation, the `handler()` function starts by fetching and rendering some article content, but then fetches and renders some secondary content afterwards. It makes sense to scroll the page to the main article content as soon as it is available so the user can interact with it, rather than waiting until the secondary content is also rendered. To achieve this, we have added a {{domxref("NavigateEvent.scroll", "scroll()")}} call between the two. + +```js +navigation.addEventListener('navigate', (event) => { + if (shouldNotIntercept(navigateEvent)) { + return; + } + const url = new URL(event.destination.url); + + if (url.pathname.startsWith('/articles/')) { + event.intercept({ + async handler() { + const articleContent = await getArticleContent(url.pathname); + renderArticlePage(articleContent); + + event.scroll(); + + const secondaryContent = await getSecondaryContent(url.pathname); + addSecondaryContent(secondaryContent); + }, + }); + } +}); +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- [Modern client-side routing: the Navigation API](https://developer.chrome.com/docs/web-platform/navigation-api/) +- [Navigation API explainer](https://github.com/WICG/navigation-api/blob/main/README.md) +- Domenic Denicola's [Navigation API live demo](https://gigantic-honored-octagon.glitch.me/) diff --git a/files/en-us/web/api/navigateevent/signal/index.md b/files/en-us/web/api/navigateevent/signal/index.md new file mode 100644 index 000000000000000..47d0f63020f16dd --- /dev/null +++ b/files/en-us/web/api/navigateevent/signal/index.md @@ -0,0 +1,63 @@ +--- +title: NavigateEvent.signal +slug: Web/API/NavigateEvent/signal +page-type: web-api-instance-property +tags: + - API + - Experimental + - History + - Navigate + - NavigateEvent + - Navigation + - Navigation API + - Property + - Read-only + - Reference + - Scroll + - signal + - Traversal +browser-compat: api.NavigateEvent.signal +--- + +{{APIRef("Navigation API")}}{{seecompattable}} + +The **`signal`** read-only property of the +{{domxref("NavigateEvent")}} interface returns an {{domxref("AbortSignal")}}, which will become aborted if the navigation is cancelled (e.g. by the user pressing the browser's "Stop" button, or another navigation starting and thus cancelling the ongoing one). + +## Value + +An {{domxref("AbortSignal")}} object. + +## Examples + +The general idea here is that the `signal` property can be passed to an associated {{domxref("fetch()")}} operation so that if the navigation is cancelled, the `fetch()` operation can be safely aborted, avoiding wasting bandwidth on fetches that are no longer needed. + +```js +navigation.addEventListener("navigate", (event) => { + event.intercept({ async handler() { + + // ... + + await fetch(`/img/some-image.jpg`, { signal: event.signal }); + + // ... + + } }); +}); +``` + +> **Note:** See [Example: next/previous buttons](https://github.com/WICG/navigation-api#example-nextprevious-buttons) for a more detailed example. + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- [Modern client-side routing: the Navigation API](https://developer.chrome.com/docs/web-platform/navigation-api/) +- [Navigation API explainer](https://github.com/WICG/navigation-api/blob/main/README.md) +- Domenic Denicola's [Navigation API live demo](https://gigantic-honored-octagon.glitch.me/) diff --git a/files/en-us/web/api/navigateevent/userinitiated/index.md b/files/en-us/web/api/navigateevent/userinitiated/index.md new file mode 100644 index 000000000000000..57a3fa502d3fd47 --- /dev/null +++ b/files/en-us/web/api/navigateevent/userinitiated/index.md @@ -0,0 +1,53 @@ +--- +title: NavigateEvent.userInitiated +slug: Web/API/NavigateEvent/userInitiated +page-type: web-api-instance-property +tags: + - API + - Experimental + - History + - Navigate + - NavigateEvent + - Navigation + - Navigation API + - Property + - Read-only + - Reference + - Scroll + - Traversal + - userInitiated +browser-compat: api.NavigateEvent.userInitiated +--- + +{{APIRef("Navigation API")}}{{seecompattable}} + +The **`userInitiated`** read-only property of the +{{domxref("NavigateEvent")}} interface returns `true` if the navigation was initiated by the user (e.g. by clicking a link, submitting a form, or pressing the browser's "Back"/"Forward" buttons), or `false` otherwise. + +> **Note:** The table found at [Appendix: types of navigations](https://github.com/WICG/navigation-api#appendix-types-of-navigations) shows which navigation types are user-initiated. + +## Value + +A boolean value—`true` if the navigation is user-initiated, `false` if not. + +## Examples + +```js +navigation.addEventListener("navigate", (event) => { + console.log(event.userInitiated); +}); +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- [Modern client-side routing: the Navigation API](https://developer.chrome.com/docs/web-platform/navigation-api/) +- [Navigation API explainer](https://github.com/WICG/navigation-api/blob/main/README.md) +- Domenic Denicola's [Navigation API live demo](https://gigantic-honored-octagon.glitch.me/) diff --git a/files/en-us/web/api/navigation/back/index.md b/files/en-us/web/api/navigation/back/index.md new file mode 100644 index 000000000000000..ec046448f940683 --- /dev/null +++ b/files/en-us/web/api/navigation/back/index.md @@ -0,0 +1,91 @@ +--- +title: Navigation.back() +slug: Web/API/Navigation/back +page-type: web-api-instance-method +tags: + - API + - Experimental + - back + - History + - Method + - Navigate + - Navigation + - Navigation API + - Reference + - Scroll + - transition + - Traversal +browser-compat: api.Navigation.back +--- + +{{APIRef("Navigation API")}}{{seecompattable}} + +The **`back()`** method of the +{{domxref("Navigation")}} interface navigates backwards by one entry in the navigation history. + +## Syntax + +```js-nolint +back(options) +``` + +### Parameters + +- `options` {{optional_inline}} + - : An options object containing the following properties: + - `info` + - : Developer-defined information to be passed along to the {{domxref("Navigation/navigate_event", "navigate")}} event, made available in {{domxref("NavigateEvent.info")}}. This can be any data type. You might, for example, wish to display newly-navigated content with a different animation depending on how it was navigated to (swipe left, swipe right, or go home). A string indicating which animation to use could be passed in as `info`. + +### Return value + +An object with the following properties: + +- `committed` + - : A {{jsxref("Promise")}} which will fulfill when the visible URL has changed and a new {{domxref("NavigationHistoryEntry")}} has been created. +- `finished` + - : A {{jsxref("Promise")}} which will fulfill when all promises returned by the `intercept()` handler are fulfilled. This is equivalent to the {{domxref("NavigationTransition.finished")}} promise fulfilling, when the {{domxref("Navigation/navigatesuccess_event", "navigatesuccess")}} event fires. + +Either one of these promises rejects if the navigation has failed for some reason. + +### Exceptions + +- `InvalidStateError` {{domxref("DOMException")}} + - : Thrown if the {{domxref("Navigation.currentEntry")}}'s {{domxref("NavigationHistoryEntry.index")}} value is -1 or 0, i.e. either the current {{domxref("Document")}} is not yet active, or the current history entry is the first one in the history, meaning that backwards navigation is not possible. + +## Examples + +```js +async function backHandler() { + if(navigation.canGoBack) { + await navigation.back().finished; + // Handle any required clean-up after + // navigation has finished + } else { + displayBanner('You are on the first page'); + } +} + +async function forwardHandler() { + if(navigation.canGoForward) { + await navigation.forward().finished; + // Handle any required clean-up after + // navigation has finished + } else { + displayBanner('You are on the last page'); + } +} +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- [Modern client-side routing: the Navigation API](https://developer.chrome.com/docs/web-platform/navigation-api/) +- [Navigation API explainer](https://github.com/WICG/navigation-api/blob/main/README.md) +- Domenic Denicola's [Navigation API live demo](https://gigantic-honored-octagon.glitch.me/) diff --git a/files/en-us/web/api/navigation/cangoback/index.md b/files/en-us/web/api/navigation/cangoback/index.md new file mode 100644 index 000000000000000..fda395223d53e4f --- /dev/null +++ b/files/en-us/web/api/navigation/cangoback/index.md @@ -0,0 +1,70 @@ +--- +title: Navigation.canGoBack +slug: Web/API/Navigation/canGoBack +page-type: web-api-instance-property +tags: + - API + - canGoBack + - Experimental + - History + - Navigate + - Navigation + - Navigation API + - Property + - Read-only + - Reference + - Scroll + - Traversal +browser-compat: api.Navigation.canGoBack +--- + +{{APIRef("Navigation API")}}{{seecompattable}} + +The **`canGoBack`** read-only property of the +{{domxref("Navigation")}} interface returns `true` +if it is possible to navigate backwards in the navigation history +(i.e. the {{domxref("Navigation.currentEntry", "currentEntry")}} is +not the first one in the history entry list), +and `false` if it is not. + +## Value + +A boolean value: `true` if it is possible to navigate backwards in the navigation history, `false` otherwise. + +## Examples + +```js +async function backHandler() { + if(navigation.canGoBack) { + await navigation.back().finished; + // Handle any required clean-up after + // navigation has finished + } else { + displayBanner('You are on the first page'); + } +} + +async function forwardHandler() { + if(navigation.canGoForward) { + await navigation.forward().finished; + // Handle any required clean-up after + // navigation has finished + } else { + displayBanner('You are on the last page'); + } +} +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- [Modern client-side routing: the Navigation API](https://developer.chrome.com/docs/web-platform/navigation-api/) +- [Navigation API explainer](https://github.com/WICG/navigation-api/blob/main/README.md) +- Domenic Denicola's [Navigation API live demo](https://gigantic-honored-octagon.glitch.me/) diff --git a/files/en-us/web/api/navigation/cangoforward/index.md b/files/en-us/web/api/navigation/cangoforward/index.md new file mode 100644 index 000000000000000..dae4d57df47c62a --- /dev/null +++ b/files/en-us/web/api/navigation/cangoforward/index.md @@ -0,0 +1,68 @@ +--- +title: Navigation.canGoForward +slug: Web/API/Navigation/canGoForward +page-type: web-api-instance-property +tags: + - API + - canGoForward + - Experimental + - History + - Navigate + - Navigation + - Navigation API + - Property + - Read-only + - Reference + - Scroll + - Traversal +browser-compat: api.Navigation.canGoForward +--- + +{{APIRef("Navigation API")}}{{seecompattable}} + +The **`canGoForward`** read-only property of the +{{domxref("Navigation")}} interface returns `true` if it is possible to navigate forwards in the navigation history +(i.e. the {{domxref("Navigation.currentEntry", "currentEntry")}} is not the last one in the history entry list), +and `false` if it is not. + +## Value + +A boolean value:`true` if it is possible to navigate forwards in the navigation history, `false`otherwise. + +## Examples + +```js +async function backHandler() { + if(navigation.canGoBack) { + await navigation.back().finished; + // Handle any required clean-up after + // navigation has finished + } else { + displayBanner('You are on the first page'); + } +} + +async function forwardHandler() { + if(navigation.canGoForward) { + await navigation.forward().finished; + // Handle any required clean-up after + // navigation has finished + } else { + displayBanner('You are on the last page'); + } +} +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- [Modern client-side routing: the Navigation API](https://developer.chrome.com/docs/web-platform/navigation-api/) +- [Navigation API explainer](https://github.com/WICG/navigation-api/blob/main/README.md) +- Domenic Denicola's [Navigation API live demo](https://gigantic-honored-octagon.glitch.me/) diff --git a/files/en-us/web/api/navigation/currententry/index.md b/files/en-us/web/api/navigation/currententry/index.md new file mode 100644 index 000000000000000..c6f04e3fde8ab0c --- /dev/null +++ b/files/en-us/web/api/navigation/currententry/index.md @@ -0,0 +1,65 @@ +--- +title: Navigation.currentEntry +slug: Web/API/Navigation/currentEntry +page-type: web-api-instance-property +tags: + - API + - currentEntry + - Experimental + - History + - Navigate + - Navigation + - Navigation API + - Property + - Read-only + - Reference + - Scroll + - Traversal +browser-compat: api.Navigation.currentEntry +--- + +{{APIRef("Navigation API")}}{{seecompattable}} + +The **`currentEntry`** read-only property of the +{{domxref("Navigation")}} interface returns a {{domxref("NavigationHistoryEntry")}} object representing the location the user is currently navigated to right now. + +## Value + +A {{domxref("NavigationHistoryEntry")}} object. + +## Examples + +```js +function initHomeBtn() { + // Get the key of the first loaded entry + // so the user can always go back to this view. + const {key} = navigation.currentEntry; + backToHomeButton.onclick = () => { + navigation.traverseTo(key); + } +} +// Intercept navigate events, such as link clicks, and +// replace them with single-page navigations +navigation.addEventListener("navigate", event => { + event.intercept({ + async handler() { + // Navigate to a different view, + // but the "home" button will always work. + } + }); +}); +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- [Modern client-side routing: the Navigation API](https://developer.chrome.com/docs/web-platform/navigation-api/) +- [Navigation API explainer](https://github.com/WICG/navigation-api/blob/main/README.md) +- Domenic Denicola's [Navigation API live demo](https://gigantic-honored-octagon.glitch.me/) diff --git a/files/en-us/web/api/navigation/currententrychange_event/index.md b/files/en-us/web/api/navigation/currententrychange_event/index.md new file mode 100644 index 000000000000000..f58e866a9e8e76a --- /dev/null +++ b/files/en-us/web/api/navigation/currententrychange_event/index.md @@ -0,0 +1,83 @@ +--- +title: "Navigation: currententrychange event" +slug: Web/API/Navigation/currententrychange_event +page-type: web-api-event +tags: + - API + - currententrychange + - Event + - Experimental + - History + - Navigate + - Navigation + - Navigation API + - Property + - Reference + - Scroll + - Traversal + - updateCurrentEntry +browser-compat: api.Navigation.currententrychange_event +--- + +{{APIRef("Navigation API")}}{{SeeCompatTable}} + +The **`currententrychange`** event of the {{domxref("Navigation")}} interface is fired when the {{domxref("Navigation.currentEntry")}} has changed. + +This event will fire for: + +- Same-document navigations (e.g. {{domxref("Navigation.back", "back()")}} or {{domxref("Navigation.traverseTo", "traverseTo()")}}). + +- Replacements (i.e. a {{domxref("Navigation.navigate", "navigate()")}} call with `history` set to `replace`). + +- Other calls that change the entry's state (e.g. {{domxref("Navigation.updateCurrentEntry", "updateCurrentEntry()")}}, or the {{domxref("History API", "History API", "", "nocode")}}'s {{domxref("History.replaceState()")}}). + +This event fires after the navigation is committed, meaning that the visible URL has changed and the {{domxref("NavigationHistoryEntry")}} update has occurred. It is useful for migrating from usage of older API features like the {{domxref("Window/hashchange_event", "hashchange")}} or {{domxref("Window/popstate_event", "popstate")}} events. + +## Syntax + +Use the event name in methods like {{domxref("EventTarget.addEventListener", "addEventListener()")}}, or set an event handler property. + +```js +addEventListener("currententrychange", (event) => {}); + +oncurrententrychange = (event) => {}; +``` + +## Event type + +An {{domxref("NavigationCurrentEntryChangeEvent")}}. Inherits from {{domxref("Event")}}. + +{{InheritanceDiagram("NavigationCurrentEntryChangeEvent")}} + +## Examples + +Navigation data reporting: + +```js +navigation.addEventListener("currententrychange", () => { + const data = navigation.currentEntry.getState(); + submitAnalyticsData(data.analytics); +}); +``` + +Setting up a per-entry event: + +```js +navigation.addEventListener("currententrychange", () => { + navigation.currentEntry.addEventListener("dispose", genericDisposeHandler); +}); +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- [Modern client-side routing: the Navigation API](https://developer.chrome.com/docs/web-platform/navigation-api/) +- [Navigation API explainer](https://github.com/WICG/navigation-api/blob/main/README.md) +- Domenic Denicola's [Navigation API live demo](https://gigantic-honored-octagon.glitch.me/) diff --git a/files/en-us/web/api/navigation/entries/index.md b/files/en-us/web/api/navigation/entries/index.md new file mode 100644 index 000000000000000..3f66c55f3b854e8 --- /dev/null +++ b/files/en-us/web/api/navigation/entries/index.md @@ -0,0 +1,80 @@ +--- +title: Navigation.entries() +slug: Web/API/Navigation/entries +page-type: web-api-instance-method +tags: + - API + - entries + - Experimental + - History + - Method + - Navigate + - Navigation + - Navigation API + - Reference + - Scroll + - transition + - Traversal +browser-compat: api.Navigation.entries +--- + +{{APIRef("Navigation API")}}{{seecompattable}} + +The **`entries()`** method of the +{{domxref("Navigation")}} interface returns an array of {{domxref("NavigationHistoryEntry")}} objects representing all existing history entries. + +## Syntax + +```js-nolint +entries() +``` + +### Parameters + +None. + +### Return value + +An array of {{domxref("NavigationHistoryEntry")}} objects. + +### Exceptions + +None. + +## Examples + +### Return the number of entries in the history + +```js +let numOfEntries = Navigation.entries().length - 1; +``` + +### A smart back button + +A page-supplied "back" button can take you back, even after reload, by inspecting the previous history entries: + +```js +backButtonEl.addEventListener("click", () => { + if (navigation.entries()[navigation.currentEntry.index - 1]?.url === "/product-listing") { + navigation.back(); + } else { + // If the user arrived here in some other way + // e.g. by typing the URL directly: + navigation.navigate("/product-listing", { history: "replace" }); + } +}); +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- [Modern client-side routing: the Navigation API](https://developer.chrome.com/docs/web-platform/navigation-api/) +- [Navigation API explainer](https://github.com/WICG/navigation-api/blob/main/README.md) +- Domenic Denicola's [Navigation API live demo](https://gigantic-honored-octagon.glitch.me/) diff --git a/files/en-us/web/api/navigation/forward/index.md b/files/en-us/web/api/navigation/forward/index.md new file mode 100644 index 000000000000000..f636b270bc56e85 --- /dev/null +++ b/files/en-us/web/api/navigation/forward/index.md @@ -0,0 +1,91 @@ +--- +title: Navigation.forward() +slug: Web/API/Navigation/forward +page-type: web-api-instance-method +tags: + - API + - Experimental + - forward + - History + - Method + - Navigate + - Navigation + - Navigation API + - Reference + - Scroll + - transition + - Traversal +browser-compat: api.Navigation.forward +--- + +{{APIRef("Navigation API")}}{{seecompattable}} + +The **`forward()`** method of the +{{domxref("Navigation")}} interface navigates forwards by one entry in the navigation history. + +## Syntax + +```js-nolint +forward(options) +``` + +### Parameters + +- `options` {{optional_inline}} + - : An options object containing the following properties: + - `info` + - : Developer-defined information to be passed along to the {{domxref("Navigation/navigate_event", "navigate")}} event, made available in {{domxref("NavigateEvent.info")}}. This can be any data type. You might, for example, wish to display newly-navigated content with a different animation depending on how it was navigated to (swipe left, swipe right, or go home). A string indicating which animation to use could be passed in as `info`. + +### Return value + +An object with the following properties: + +- `committed` + - : A {{jsxref("Promise")}} which will fulfill when the visible URL has changed and a new {{domxref("NavigationHistoryEntry")}} has been created. +- `finished` + - : A {{jsxref("Promise")}} which will fulfill when all promises returned by the `intercept()` handler are fulfilled. This is equivalent to the {{domxref("NavigationTransition.finished")}} promise fulfilling, when the {{domxref("Navigation/navigatesuccess_event", "navigatesuccess")}} event fires. + +Either one of these promises rejects if the navigation has failed for some reason. + +### Exceptions + +- `InvalidStateError` {{domxref("DOMException")}} + - : Thrown if the {{domxref("Navigation.currentEntry")}}'s {{domxref("NavigationHistoryEntry.index")}} value is -1 or {{domxref("Navigation.entries", "Navigation.entries().length - 1")}}, i.e. either the current {{domxref("Document")}} is not yet active, or the current history entry is the last one in the history, meaning that forwards navigation is not possible. + +## Examples + +```js +async function backHandler() { + if(navigation.canGoBack) { + await navigation.back().finished; + // Handle any required clean-up after + // navigation has finished + } else { + displayBanner('You are on the first page'); + } +} + +async function forwardHandler() { + if(navigation.canGoForward) { + await navigation.forward().finished; + // Handle any required clean-up after + // navigation has finished + } else { + displayBanner('You are on the last page'); + } +} +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- [Modern client-side routing: the Navigation API](https://developer.chrome.com/docs/web-platform/navigation-api/) +- [Navigation API explainer](https://github.com/WICG/navigation-api/blob/main/README.md) +- Domenic Denicola's [Navigation API live demo](https://gigantic-honored-octagon.glitch.me/) diff --git a/files/en-us/web/api/navigation/index.md b/files/en-us/web/api/navigation/index.md new file mode 100644 index 000000000000000..4edd8bad7f90a04 --- /dev/null +++ b/files/en-us/web/api/navigation/index.md @@ -0,0 +1,148 @@ +--- +title: Navigation +slug: Web/API/Navigation +page-type: web-api-interface +tags: + - API + - Experimental + - History + - Interface + - Landing + - Navigate + - Navigation + - Navigation API + - Reference + - Scroll + - Traversal +browser-compat: api.Navigation +--- + +{{APIRef("Navigation API")}}{{seecompattable}} + +The **`Navigation`** interface of the {{domxref("Navigation API", "Navigation API", "", "nocode")}} allows control over all navigation actions for the current `window` in one central place, including initiating navigations programmatically, examining navigation history entries, and managing navigations as they happen. + +It is accessed via the {{domxref("Window.navigation")}} property. + +The Navigation API only exposes history entries created in the current browsing context that have the same origin as the current page (e.g. not navigations inside embedded {{htmlelement("iframe")}}s, or cross-origin navigations), providing an accurate list of all previous history entries just for your app. This makes traversing the history a much less fragile proposition than with the older {{domxref("History API", "History API", "", "nocode")}}. + +{{InheritanceDiagram}} + +## Instance properties + +_Inherits properties from its parent, {{DOMxRef("EventTarget")}}._ + +- {{domxref("Navigation.canGoBack", "canGoBack")}} {{ReadOnlyInline}} + - : Returns `true` if it is possible to navigate backwards in the navigation history + (i.e. the {{domxref("Navigation.currentEntry", "currentEntry")}} is not the first one in the history entry list), + and `false` if it is not. +- {{domxref("Navigation.canGoForward", "canGoForward")}} {{ReadOnlyInline}} + - : Returns `true` if it is possible to navigate forwards in the navigation history + (i.e. the {{domxref("Navigation.currentEntry", "currentEntry")}} is not the last one in the history entry list), + and `false` if it is not. +- {{domxref("Navigation.currentEntry", "currentEntry")}} {{ReadOnlyInline}} + - : Returns a {{domxref("NavigationHistoryEntry")}} object representing the location the user is currently + navigated to right now. +- {{domxref("Navigation.transition", "transition")}} {{ReadOnlyInline}} + - : Returns a {{domxref("NavigationTransition")}} object representing the status of an in-progress navigation, + which can be used to track it. Returns `null` if no navigation is currently in progress. + +## Instance methods + +_Inherits methods from its parent, {{DOMxRef("EventTarget")}}._ + +- {{domxref("Navigation.back", "back()")}} + - : Navigates backwards by one entry in the navigation history. +- {{domxref("Navigation.entries", "entries()")}} + - : Returns an array of {{domxref("NavigationHistoryEntry")}} objects representing all existing history entries. +- {{domxref("Navigation.forward", "forward()")}} + - : Navigates forwards by one entry in the navigation history. +- {{domxref("Navigation.navigate", "navigate()")}} + - : Navigates to a specific URL, updating any provided state in the history entries list. +- {{domxref("Navigation.reload", "reload()")}} + - : Reloads the current URL, updating any provided state in the history entries list. +- {{domxref("Navigation.traverseTo", "traverseTo()")}} + - : Navigates to a specific {{domxref("NavigationHistoryEntry")}} identified by {{domxref("NavigationHistoryEntry.key", "key")}}. +- {{domxref("Navigation.updateCurrentEntry", "updateCurrentEntry()")}} + - : Updates the state of the {{domxref("Navigation.currentEntry","currentEntry")}}; used + in cases where the state change will be independent from a navigation or reload. + +## Events + +- {{domxref("Navigation/currententrychange_event", "currententrychange")}} + - : Fired when the {{domxref("Navigation.currentEntry")}} has changed. +- {{domxref("Navigation/navigate_event", "navigate")}} + - : Fired when [any type of navigation](https://github.com/WICG/navigation-api#appendix-types-of-navigations) is initiated, allowing you to intercept as required. +- {{domxref("Navigation/navigateerror_event", "navigateerror")}} + - : Fired when a navigation fails. +- {{domxref("Navigation/navigatesuccess_event", "navigatesuccess")}} + - : Fired when a successful navigation has finished. + +## Examples + +### Moving forwards and backwards in the history + +```js +async function backHandler() { + if(navigation.canGoBack) { + await navigation.back().finished; + // Handle any required clean-up after + // navigation has finished + } else { + displayBanner('You are on the first page'); + } +} + +async function forwardHandler() { + if(navigation.canGoForward) { + await navigation.forward().finished; + // Handle any required clean-up after + // navigation has finished + } else { + displayBanner('You are on the last page'); + } +} +``` + +### Traversing to a specific history entry + +```js +// On JS startup, get the key of the first loaded page +// so the user can always go back there. +const {key} = navigation.currentEntry; +backToHomeButton.onclick = () => navigation.traverseTo(key); + +// Navigate away, but the button will always work. +await navigation.navigate('/another_url').finished; +``` + +### Navigating and updating state + +```js +navigation.navigate(url, {state: newState}); +``` + +Or + +```js +navigation.reload({state: newState}); +``` + +Or if the state is independent from a navigation or reload: + +```js +navigation.updateCurrentEntry({state: newState}); +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- [Modern client-side routing: the Navigation API](https://developer.chrome.com/docs/web-platform/navigation-api/) +- [Navigation API explainer](https://github.com/WICG/navigation-api/blob/main/README.md) +- Domenic Denicola's [Navigation API live demo](https://gigantic-honored-octagon.glitch.me/) diff --git a/files/en-us/web/api/navigation/navigate/index.md b/files/en-us/web/api/navigation/navigate/index.md new file mode 100644 index 000000000000000..91831bf94b245ce --- /dev/null +++ b/files/en-us/web/api/navigation/navigate/index.md @@ -0,0 +1,133 @@ +--- +title: Navigation.navigate() +slug: Web/API/Navigation/navigate +page-type: web-api-instance-method +tags: + - API + - Experimental + - History + - Method + - Navigate + - Navigation + - Navigation API + - Reference + - Scroll + - transition + - Traversal +browser-compat: api.Navigation.navigate +--- + +{{APIRef("Navigation API")}}{{seecompattable}} + +The **`navigate()`** method of the +{{domxref("Navigation")}} interface navigates to a specific URL, updating any provided state in the history entries list. + +## Syntax + +```js-nolint +navigate(url) +navigate(url, options) +``` + +### Parameters + +- `url` + - : The destination URL to navigate to. +- `options` {{optional_inline}} + - : An options object containing the following properties: + - `state` + - : Developer-defined information to be stored in the associated {{domxref("NavigationHistoryEntry")}} once the navigation is complete, retrievable via {{domxref("NavigationHistoryEntry.getState", "getState()")}}. This can be any data type. You might, for example, wish to store a page visit count for analytics purposes, or store UI state details so the view can be shown exactly as the user last left it. Any data stored in `state` must be [structured-clonable](/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm). + - `info` + - : Developer-defined information to be passed along to the {{domxref("Navigation/navigate_event", "navigate")}} event, made available in {{domxref("NavigateEvent.info")}}. This can be any data type. You might, for example, wish to display newly-navigated content with a different animation depending on how it was navigated to (swipe left, swipe right, or go home). A string indicating which animation to use could be passed in as `info`. + - `history` + - : An enumerated value that sets the history behavior of this navigation. The available values are: + - `auto`: The default value; will usually perform a `push` navigation but will perform a `replace` navigation under special circumstances (see the `NotSupportedError` description below). + - `push`: Will push a new {{domxref("NavigationHistoryEntry")}} onto the entries list, or fail under special circumstances (see the `NotSupportedError` description below). + - `replace`: Will replace the current {{domxref("NavigationHistoryEntry")}}. + +### Return value + +An object with the following properties: + +- `committed` + - : A {{jsxref("Promise")}} which will fulfill when the visible URL has changed and a new {{domxref("NavigationHistoryEntry")}} has been created. +- `finished` + - : A {{jsxref("Promise")}} which will fulfill when all promises returned by the `intercept()` handler are fulfilled. This is equivalent to the {{domxref("NavigationTransition.finished")}} promise fulfilling, when the {{domxref("Navigation/navigatesuccess_event", "navigatesuccess")}} event fires. + +Either one of these promises rejects if the navigation has failed for some reason. + +### Exceptions + +- `DataCloneError` {{domxref("DOMException")}} + - : Thrown if the `state` parameter had values included in it that are not structured-clonable. +- `SyntaxError` {{domxref("DOMException")}} + - : Thrown if the `url` parameter is not a valid URL. +- `NotSupportedError` {{domxref("DOMException")}} + - : Thrown if the `history` option is set to `push`, and any of the following special circumstances are true: + - The browser is currently showing the initial `about:blank` document. + - The current {{domxref("Document")}} is not yet loaded. + - The `url` parameter is set to the current URL. + - The `url`'s scheme is `javascript`. + +## Examples + +### Set up home button + +```js +function initHomeBtn() { + // Get the key of the first loaded entry + // so the user can always go back to this view. + const {key} = navigation.currentEntry; + backToHomeButton.onclick = () => { + navigation.traverseTo(key); + } +} +// Intercept navigate events, such as link clicks, and +// replace them with single-page navigations +navigation.addEventListener("navigate", event => { + event.intercept({ + async handler() { + // Navigate to a different view, + // but the "home" button will always work. + } + }); +}); +``` + +### A smart back button + +A page-supplied "back" button can take you back, even after reload, by inspecting the previous history entries: + +```js +backButtonEl.addEventListener("click", () => { + if (navigation.entries()[navigation.currentEntry.index - 1]?.url === "/product-listing") { + navigation.back(); + } else { + // If the user arrived here in some other way + // e.g. by typing the URL directly: + navigation.navigate("/product-listing", { history: "replace" }); + } +}); +``` + +### Using info and state + +```js +async function navigateHandler() { + await navigation.navigate(url, { info: { animation: "swipe-right" }, state: { infoPaneOpen: true } } ); +} +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- [Modern client-side routing: the Navigation API](https://developer.chrome.com/docs/web-platform/navigation-api/) +- [Navigation API explainer](https://github.com/WICG/navigation-api/blob/main/README.md) +- Domenic Denicola's [Navigation API live demo](https://gigantic-honored-octagon.glitch.me/) diff --git a/files/en-us/web/api/navigation/navigate_event/index.md b/files/en-us/web/api/navigation/navigate_event/index.md new file mode 100644 index 000000000000000..579d11a324c4d59 --- /dev/null +++ b/files/en-us/web/api/navigation/navigate_event/index.md @@ -0,0 +1,112 @@ +--- +title: "Navigation: navigate event" +slug: Web/API/Navigation/navigate_event +page-type: web-api-event +tags: + - API + - Event + - Experimental + - History + - Navigate + - Navigation + - Navigation API + - Property + - Reference + - Scroll + - Traversal + - updateCurrentEntry +browser-compat: api.Navigation.navigate_event +--- + +{{APIRef("Navigation API")}}{{SeeCompatTable}} + +The **`navigate`** event of the {{domxref("Navigation")}} interface is fired when [any type of navigation](https://github.com/WICG/navigation-api#appendix-types-of-navigations) is initiated, allowing you to intercept as required. + +## Syntax + +Use the event name in methods like {{domxref("EventTarget.addEventListener", "addEventListener()")}}, or set an event handler property. + +```js +addEventListener("navigate", (event) => {}); + +onnavigate = (event) => {}; +``` + +## Event type + +An {{domxref("NavigateEvent")}}. Inherits from {{domxref("Event")}}. + +{{InheritanceDiagram("NavigateEvent")}} + +## Examples + +### Handling a navigation using `intercept()` + +```js +navigation.addEventListener('navigate', (event) => { + // Exit early if this navigation shouldn't be intercepted, + // e.g. if the navigation is cross-origin, or a download request + if (shouldNotIntercept(event)) { + return; + } + + const url = new URL(event.destination.url); + + if (url.pathname.startsWith('/articles/')) { + event.intercept({ + async handler() { + // The URL has already changed, so show a placeholder while + //fetching the new content, such as a spinner or loading page + renderArticlePagePlaceholder(); + + // Fetch the new content and display when ready + const articleContent = await getArticleContent(url.pathname); + renderArticlePage(articleContent); + }, + }); + } +}); +``` + +> **Note:** Before the Navigation API was available, to do something similar you'd have to listen for all click events on links, run `event.preventDefault()`, perform the appropriate {{domxref("History.pushState()")}} call, then set up the page view based on the new URL. And this wouldn't handle all navigations — only user-initiated link clicks. + +### Handling scrolling using `scroll()` + +In this example of intercepting a navigation, the `handler()` function starts by fetching and rendering some article content, but then fetches and renders some secondary content afterwards. It makes sense to scroll the page to the main article content as soon as it is available so the user can interact with it, rather than waiting until the secondary content is also rendered. To achieve this, we have added a {{domxref("NavigateEvent.scroll", "scroll()")}} call between the two. + +```js +navigation.addEventListener('navigate', (event) => { + if (shouldNotIntercept(navigateEvent)) { + return; + } + const url = new URL(event.destination.url); + + if (url.pathname.startsWith('/articles/')) { + event.intercept({ + async handler() { + const articleContent = await getArticleContent(url.pathname); + renderArticlePage(articleContent); + + event.scroll(); + + const secondaryContent = await getSecondaryContent(url.pathname); + addSecondaryContent(secondaryContent); + }, + }); + } +}); +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- [Modern client-side routing: the Navigation API](https://developer.chrome.com/docs/web-platform/navigation-api/) +- [Navigation API explainer](https://github.com/WICG/navigation-api/blob/main/README.md) +- Domenic Denicola's [Navigation API live demo](https://gigantic-honored-octagon.glitch.me/) diff --git a/files/en-us/web/api/navigation/navigateerror_event/index.md b/files/en-us/web/api/navigation/navigateerror_event/index.md new file mode 100644 index 000000000000000..21dcc0767ee5849 --- /dev/null +++ b/files/en-us/web/api/navigation/navigateerror_event/index.md @@ -0,0 +1,75 @@ +--- +title: "Navigation: navigateerror event" +slug: Web/API/Navigation/navigateerror_event +page-type: web-api-event +tags: + - API + - Event + - Experimental + - History + - Navigate + - navigateerror + - Navigation + - Navigation API + - Property + - Reference + - Scroll + - Traversal + - updateCurrentEntry +browser-compat: api.Navigation.navigateerror_event +--- + +{{APIRef("Navigation API")}}{{SeeCompatTable}} + +The **`navigateerror`** event of the {{domxref("Navigation")}} interface is fired when a navigation fails. + +For example, if the network is down, any {{domxref("fetch()")}} method invoked to handle a navigation will fail, and the error will be routed to `navigateerror`. + +## Syntax + +Use the event name in methods like {{domxref("EventTarget.addEventListener", "addEventListener()")}}, or set an event handler property. + +```js +addEventListener("navigateerror", (event) => {}); + +onnavigateerror = (event) => {}; +``` + +## Event type + +An {{domxref("ErrorEvent")}}. Inherits from {{domxref("Event")}}. + +{{InheritanceDiagram("ErrorEvent")}} + +## Examples + +You might deal with a successful navigation by hiding a previously displayed progress indicator, like this: + +```js +navigation.addEventListener('navigatesuccess', (event) => { + loadingIndicator.hidden = true; +}); +``` + +Or you might show an error message on failure: + +```js +navigation.addEventListener('navigateerror', (event) => { + loadingIndicator.hidden = true; // also hide indicator + showMessage(`Failed to load page: ${event.message}`); +}); +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- [Modern client-side routing: the Navigation API](https://developer.chrome.com/docs/web-platform/navigation-api/) +- [Navigation API explainer](https://github.com/WICG/navigation-api/blob/main/README.md) +- Domenic Denicola's [Navigation API live demo](https://gigantic-honored-octagon.glitch.me/) diff --git a/files/en-us/web/api/navigation/navigatesuccess_event/index.md b/files/en-us/web/api/navigation/navigatesuccess_event/index.md new file mode 100644 index 000000000000000..dcb48da359872c3 --- /dev/null +++ b/files/en-us/web/api/navigation/navigatesuccess_event/index.md @@ -0,0 +1,73 @@ +--- +title: "Navigation: navigatesuccess event" +slug: Web/API/Navigation/navigatesuccess_event +page-type: web-api-event +tags: + - API + - Event + - Experimental + - History + - Navigate + - navigatesuccess + - Navigation + - Navigation API + - Property + - Reference + - Scroll + - Traversal + - updateCurrentEntry +browser-compat: api.Navigation.navigatesuccess_event +--- + +{{APIRef("Navigation API")}}{{SeeCompatTable}} + +The **`navigatesuccess`** event of the {{domxref("Navigation")}} interface is fired when a successful navigation has finished. + +In the case of an intercepted navigation, this would occur after any promises returned by your {{domxref("NavigateEvent.intercept", "intercept()")}} handler are fulfilled. The {{domxref("NavigationTransition.finished")}} promise will also fulfill at the same time. + +## Syntax + +Use the event name in methods like {{domxref("EventTarget.addEventListener", "addEventListener()")}}, or set an event handler property. + +```js +addEventListener("navigatesuccess", (event) => {}); + +onnavigatesuccess = (event) => {}; +``` + +## Event type + +A generic {{domxref("Event")}}. + +## Examples + +You might deal with a successful navigation by hiding a previously displayed progress indicator, like this: + +```js +navigation.addEventListener('navigatesuccess', (event) => { + loadingIndicator.hidden = true; +}); +``` + +Or you might show an error message on failure: + +```js +navigation.addEventListener('navigateerror', (event) => { + loadingIndicator.hidden = true; // also hide indicator + showMessage(`Failed to load page: ${event.message}`); +}); +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- [Modern client-side routing: the Navigation API](https://developer.chrome.com/docs/web-platform/navigation-api/) +- [Navigation API explainer](https://github.com/WICG/navigation-api/blob/main/README.md) +- Domenic Denicola's [Navigation API live demo](https://gigantic-honored-octagon.glitch.me/) diff --git a/files/en-us/web/api/navigation/reload/index.md b/files/en-us/web/api/navigation/reload/index.md new file mode 100644 index 000000000000000..858cf864297456b --- /dev/null +++ b/files/en-us/web/api/navigation/reload/index.md @@ -0,0 +1,91 @@ +--- +title: Navigation.reload() +slug: Web/API/Navigation/reload +page-type: web-api-instance-method +tags: + - API + - Experimental + - History + - Method + - Navigate + - Navigation + - Navigation API + - Reference + - reload + - Scroll + - transition + - Traversal +browser-compat: api.Navigation.reload +--- + +{{APIRef("Navigation API")}}{{seecompattable}} + +The **`reload()`** method of the +{{domxref("Navigation")}} interface reloads the current URL, updating any provided state in the history entries list. + +## Syntax + +```js-nolint +navigate(options) +``` + +### Parameters + +- `options` {{optional_inline}} + - : An options object containing the following properties: + - `state` + - : Developer-defined information to be stored in the associated {{domxref("NavigationHistoryEntry")}} once the navigation is complete, retrievable via {{domxref("NavigationHistoryEntry.getState", "getState()")}}. This can be any data type. You might, for example, wish to store a page visit count for analytics purposes, or store UI state details so the view can be shown exactly as the user last left it. Any data stored in `state` must be [structured-clonable](/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm). + - `info` + - : Developer-defined information to be passed along to the {{domxref("Navigation/navigate_event", "navigate")}} event, made available in {{domxref("NavigateEvent.info")}}. This can be any data type. You might, for example, wish to display newly-navigated content with a different animation depending on how it was navigated to (swipe left, swipe right, or go home). A string indicating which animation to use could be passed in as `info`. + +### Return value + +An object with the following properties: + +- `committed` + - : A {{jsxref("Promise")}} which will fulfill when the visible URL has changed and a new {{domxref("NavigationHistoryEntry")}} has been created. +- `finished` + - : A {{jsxref("Promise")}} which will fulfill when all promises returned by the `intercept()` handler are fulfilled. This is equivalent to the {{domxref("NavigationTransition.finished")}} promise fulfilling, when the {{domxref("Navigation/navigatesuccess_event", "navigatesuccess")}} event fires. + +Either one of these promises rejects if the navigation has failed for some reason. + +### Exceptions + +- `DataCloneError` {{domxref("DOMException")}} + - : Thrown if the `state` parameter had values included in it that are not structured-clonable. + +## Examples + +### Using info and state + +```js +async function handleReload() { + await navigation.reload({ info: { animation: "fade-in" }, state: { infoPaneOpen: true } } ); + + // ... +} +``` + +Reload page and add a new state item: + +```js +async function handleReload() { + await navigation.reload({ state: { ...navigation.currentEntry.getState(), newState: 3 } }); + + // ... +} +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- [Modern client-side routing: the Navigation API](https://developer.chrome.com/docs/web-platform/navigation-api/) +- [Navigation API explainer](https://github.com/WICG/navigation-api/blob/main/README.md) +- Domenic Denicola's [Navigation API live demo](https://gigantic-honored-octagon.glitch.me/) diff --git a/files/en-us/web/api/navigation/transition/index.md b/files/en-us/web/api/navigation/transition/index.md new file mode 100644 index 000000000000000..96a5df38e8bd34c --- /dev/null +++ b/files/en-us/web/api/navigation/transition/index.md @@ -0,0 +1,53 @@ +--- +title: Navigation.transition +slug: Web/API/Navigation/transition +page-type: web-api-instance-property +tags: + - API + - Experimental + - History + - Navigate + - Navigation + - Navigation API + - Property + - Read-only + - Reference + - Scroll + - transition + - Traversal +browser-compat: api.Navigation.transition +--- + +{{APIRef("Navigation API")}}{{seecompattable}} + +The **`transition`** read-only property of the {{domxref("Navigation")}} interface returns a {{domxref("NavigationTransition")}} object representing the status of an in-progress navigation, which can be used to track it. + +## Value + +A {{domxref("NavigationTransition")}} object, or `null` if no navigation is currently in progress. + +## Examples + +```js +async function handleTransition() { + if(navigation.transition) { + showLoadingSpinner(); + await navigation.transition.finished; + hideLoadingSpinner(); + } +} +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- [Modern client-side routing: the Navigation API](https://developer.chrome.com/docs/web-platform/navigation-api/) +- [Navigation API explainer](https://github.com/WICG/navigation-api/blob/main/README.md) +- Domenic Denicola's [Navigation API live demo](https://gigantic-honored-octagon.glitch.me/) diff --git a/files/en-us/web/api/navigation/traverseto/index.md b/files/en-us/web/api/navigation/traverseto/index.md new file mode 100644 index 000000000000000..d27ec98717f6c37 --- /dev/null +++ b/files/en-us/web/api/navigation/traverseto/index.md @@ -0,0 +1,94 @@ +--- +title: Navigation.traverseTo() +slug: Web/API/Navigation/traverseTo +page-type: web-api-instance-method +tags: + - API + - Experimental + - History + - Method + - Navigate + - Navigation + - Navigation API + - Reference + - Scroll + - transition + - Traversal + - traverseTo +browser-compat: api.Navigation.traverseTo +--- + +{{APIRef("Navigation API")}}{{seecompattable}} + +The **`traverseTo()`** method of the {{domxref("Navigation")}} interface navigates to the {{domxref("NavigationHistoryEntry")}} identified by the given {{domxref("NavigationHistoryEntry.key", "key")}}. + +## Syntax + +```js-nolint +traverseTo(key) +traverseTo(key, options) +``` + +### Parameters + +- `key` + - : The `key` of the {{domxref("NavigationHistoryEntry")}} to navigate to. +- `options` {{optional_inline}} + - : An options object containing the following properties: + - `info` + - : Developer-defined information to be passed along to the {{domxref("Navigation/navigate_event", "navigate")}} event, made available in {{domxref("NavigateEvent.info")}}. This can be any data type. You might, for example, wish to display newly-navigated content with a different animation depending on how it was navigated to (swipe left, swipe right, or go home). A string indicating which animation to use could be passed in as `info`. + +### Return value + +An object with the following properties: + +- `committed` + - : A {{jsxref("Promise")}} which will fulfill when the visible URL has changed and a new {{domxref("NavigationHistoryEntry")}} has been created. +- `finished` + - : A {{jsxref("Promise")}} which will fulfill when all promises returned by the `intercept()` handler are fulfilled. This is equivalent to the {{domxref("NavigationTransition.finished")}} promise fulfilling, when the {{domxref("Navigation/navigatesuccess_event", "navigatesuccess")}} event fires. + +Either one of these promises rejects if the navigation has failed for some reason. + +### Exceptions + +- `InvalidStateError` {{domxref("DOMException")}} + - : Thrown if the {{domxref("Navigation.currentEntry")}}'s {{domxref("NavigationHistoryEntry.index")}} value is -1, meaning the current {{domxref("Document")}} is not yet active, of if the navigation history list does not contain a {{domxref("NavigationHistoryEntry")}} with the specified key. + +## Examples + +### Set up home button + +```js +function initHomeBtn() { + // Get the key of the first loaded entry + // so the user can always go back to this view. + const {key} = navigation.currentEntry; + backToHomeButton.onclick = () => { + navigation.traverseTo(key); + } +} +// Intercept navigate events, such as link clicks, and +// replace them with single-page navigations +navigation.addEventListener("navigate", event => { + event.intercept({ + async handler() { + // Navigate to a different view, + // but the "home" button will always work. + } + }); +}); +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- [Modern client-side routing: the Navigation API](https://developer.chrome.com/docs/web-platform/navigation-api/) +- [Navigation API explainer](https://github.com/WICG/navigation-api/blob/main/README.md) +- Domenic Denicola's [Navigation API live demo](https://gigantic-honored-octagon.glitch.me/) diff --git a/files/en-us/web/api/navigation/updatecurrententry/index.md b/files/en-us/web/api/navigation/updatecurrententry/index.md new file mode 100644 index 000000000000000..787cebff0107fd0 --- /dev/null +++ b/files/en-us/web/api/navigation/updatecurrententry/index.md @@ -0,0 +1,72 @@ +--- +title: Navigation.updateCurrentEntry() +slug: Web/API/Navigation/updateCurrentEntry +page-type: web-api-instance-method +tags: + - API + - Experimental + - History + - Method + - Navigate + - Navigation + - Navigation API + - Reference + - reload + - Scroll + - Traversal + - updateCurrentEntry +browser-compat: api.Navigation.updateCurrentEntry +--- + +{{APIRef("Navigation API")}}{{seecompattable}} + +The **`updateCurrentEntry()`** method of the {{domxref("Navigation")}} interface updates the `state` of the {{domxref("Navigation.currentEntry","currentEntry")}}; used in cases where the state change will be independent from a navigation or reload. + +## Syntax + +```js-nolint +updateCurrentEntry() +updateCurrentEntry(options) +``` + +### Parameters + +- `options` {{optional_inline}} + - : An options object containing the following properties: + - `state` + - : Developer-defined information to be stored in the associated {{domxref("NavigationHistoryEntry")}} once the navigation is complete, retrievable via {{domxref("NavigationHistoryEntry.getState", "getState()")}}. This can be any data type. You might, for example, wish to store a page visit count for analytics purposes, or store UI state details so the view can be shown exactly as the user last left it. Any data stored in `state` must be [structured-clonable](/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm). + +### Return value + +None (`undefined`). + +### Exceptions + +- `DataCloneError` {{domxref("DOMException")}} + - : Thrown if the `state` parameter had values included in it that are not structured-clonable. +- `InvalidStateError` {{domxref("DOMException")}} + - : Thrown if the {{domxref("Navigation.currentEntry")}} is `null`, i.e. there is no current history entry. This could occur for exaple if the current page is `about:blank`. + +## Examples + +You could use something like the following to update the open/closed state of a {{htmlelement("details")}} element so that the state can be restored when reloading the page or navigating back from somewhere else. + +```js +detailsElem.addEventListener('toggle', () => { + navigation.updateCurrentEntry({ state: { detailOpen : detailsElem.open } }); +}) +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- [Modern client-side routing: the Navigation API](https://developer.chrome.com/docs/web-platform/navigation-api/) +- [Navigation API explainer](https://github.com/WICG/navigation-api/blob/main/README.md) +- Domenic Denicola's [Navigation API live demo](https://gigantic-honored-octagon.glitch.me/) diff --git a/files/en-us/web/api/navigation_api/index.md b/files/en-us/web/api/navigation_api/index.md new file mode 100644 index 000000000000000..d95f4dc230e2bd4 --- /dev/null +++ b/files/en-us/web/api/navigation_api/index.md @@ -0,0 +1,209 @@ +--- +title: Navigation API +slug: Web/API/Navigation_API +page-type: web-api-overview +tags: + - API + - Experimental + - History + - Landing + - Navigate + - Navigation + - Navigation API + - Overview + - Reference + - Scroll + - Traversal +browser-compat: + - api.Navigation + - api.NavigateEvent +--- + +{{seecompattable}}{{DefaultAPISidebar("Navigation API")}} + +The **Navigation API** provides the ability to initiate, intercept, and manage browser navigation actions. It can also examine an application's history entries. This is a successor to previous web platform features such as the {{domxref("History API", "History API", "", "nocode")}} and {{domxref("window.location")}}, which solves their shortcomings and is specifically aimed at the needs of {{glossary("SPA", "single-page applications (SPAs)")}}. + +## Concepts and usage + +In SPAs, the page template tends to stay the same during usage, and the content is dynamically rewritten as the user visits different pages or features. As a result, only one distinct page is loaded in the browser, which breaks the expected user experience of navigating back and forth between different locations in the viewing history. This problem can be solved to a degree via the {{domxref("History API", "History API", "", "nocode")}}, but it is not designed for the needs of SPAs. The Navigation API aims to bridge that gap. + +The API is accessed via the {{domxref("Window.navigation")}} property, which returns a reference to a global {{domxref("Navigation")}} object. Each `window` object has its own corresponding `navigation` instance. + +### Handling navigations + +The `navigation` interface has several associated events, the most notable being the {{domxref("Navigation/navigate_event", "navigate")}} event. This is fired when [any type of navigation](https://github.com/WICG/navigation-api#appendix-types-of-navigations) is initiated, meaning that you can control all page navigations from one central place, ideal for routing functionality in SPA frameworks. (This is not the case with the {{domxref("History API", "History API", "", "nocode")}}, where it is sometimes hard to figure out responding to all navigations.) The `navigate` event handler is passed a {{domxref("NavigateEvent")}} object, which contains detailed information including details around the navigation's destination, type, whether it contains `POST` form data or a download request, and more. + +The `NavigationEvent` object also provides two methods: + +- {{domxref("NavigateEvent.intercept", "intercept()")}} takes as an argument a callback handler function returning a promise. It allows you to control what happens when the navigation is initiated. For example, in the case of an SPA, it can be used to load relevant new content into the UI based on the path of the URL navigated to. +- {{domxref("NavigateEvent.scroll", "scroll()")}} allows you to manually initiate the browser's scroll behavior (e.g. to a fragment identifier in the URL), if it makes sense for your code, rather than waiting for the browser to handle it automatically. + +Once a navigation is initiated, and your `intercept()` handler is called, a {{domxref("NavigationTransition")}} object instance is created (accessible via {{domxref("Navigation.transition")}}), which can be used used to track the process of the ongoing navigation. + +> **Note:** In this context "transition" refers to the transition between one history entry and another. It isn't related to CSS transitions. + +> **Note:** You can also call {{domxref("Event.preventDefault", "preventDefault()")}} to stop the navigation entirely for most [navigation types](/en-US/docs/Web/API/NavigateEvent/navigationType#value); cancellation of traverse navigations is not yet implemented. + +When the `intercept()` handler function's promise fulfills, the `Navigation` object's {{domxref("Navigation/navigatesuccess_event", "navigatesuccess")}} event fires, allowing you to run cleanup code after a successful navigation has completed. If it rejects, meaning the navigation has failed, {{domxref("Navigation/navigateerror_event", "navigateerror")}} fires instead, allowing you to gracefully handle the failure case. There is also a {{domxref("NavigationTransition.finished", "finished")}} property on the `NavigationTransition` object, which fullfills or rejects at the same time as the aforementioned events are fired, providing another path for handling the success and failure cases. + +> **Note:** Before the Navigation API was available, to do something similar you'd have to listen for all click events on links, run `e.preventDefault()`, perform the appropriate {{domxref("History.pushState()")}} call, then set up the page view based on the new URL. And this wouldn't handle all navigations — only user-initiated link clicks. + +### Programmatically updating and traversing the navigation history + +As the user navigates through your application, each new location navigated to results in the creation of a navigation history entry. Each history entry is represented by a distinct {{domxref("NavigationHistoryEntry")}} object instance. These contain several properties such as the entry's key, URL, and state information. You can get the entry that the user is currently on right now using {{domxref("Navigation.currentEntry")}}, and an array of all existing history entries using {{domxref("Navigation.entries()")}}. Each `NavigationHistoryEntry` object has a {{domxref("NavigationHistoryEntry/dispose_event", "dispose")}} event, which fires when the entry is no longer part of the browser history. For example, if the user navigates back three times, then navigates forward to somewhere else, those three history entries will be disposed of. + +> **Note:** The Navigation API only exposes history entries created in the current browsing context that have the same origin as the current page (e.g. not navigations inside embedded {{htmlelement("iframe")}}s, or cross-origin navigations), providing an accurate list of all previous history entries just for your app. This makes traversing the history a much less fragile proposition than with the older {{domxref("History API", "History API", "", "nocode")}}. + +The `Navigation` object contains all the methods you'll need to update and traverse through the navigation history: + +- {{domxref("Navigation.navigate", "navigate()")}} navigates to a new URL, creating a new navigation history entry. +- {{domxref("Navigation.reload", "reload()")}} reloads the current navigation history entry. +- {{domxref("Navigation.back", "back()")}} navigates to the previous navigation history entry, if that is possible. +- {{domxref("Navigation.forward", "forward()")}} navigates to the next navigation history entry, if that is possible. +- {{domxref("Navigation.traverseTo", "traverseTo()")}} navigates to a specific navigation history entry identified by its key value, which is obtained via the relevant entry's {{domxref("NavigationHistoryEntry.key")}} property. + +Each one of the above methods returns an object containing two promises — `{ committed, finished }`. This allows the invoking function to wait on taking further action until: + +- `committed` fulfills, meaning that the visible URL has changed and a new {{domxref("NavigationHistoryEntry")}} has been created. +- `finished` fulfills, meaning that all promises returned by your `intercept()` handler are fulfilled. This is equivalent to the {{domxref("NavigationTransition.finished")}} promise fulfilling, when the {{domxref("Navigation/navigatesuccess_event", "navigatesuccess")}} event fires, as mentioned earlier. +- either one of the above promises rejects, meaning that the navigation has failed for some reason. + +### State + +The Navigation API allows you to store state on each history entry. This is developer-defined information — it can be whatever you like. For example, you might want to store a `visitCount` property that records the number of times a view has been visited, or an object containing multiple properties related to UI state, so that state can be restored when a user returns to that view. + +To get a {{domxref("NavigationHistoryEntry")}}'s state, you call its {{domxref("NavigationHistoryEntry.getState", "getState()")}} method. It is initially `undefined`, but when state information is set on the entry, it will return the previously-set state information. + +Setting state is a bit more nuanced. You can't retrieve the state value and then update it directly — the copy stored on the entry will not change. Instead, you update it while performing a {{domxref("Navigation.navigate", "navigate()")}} or {{domxref("Navigation.reload", "reload()")}} — each one of these optionally takes an options object parameter, which includes a `state` property containing the new state to set on the history entry. When these navigations commit, the state change will be automatically applied. + +In some cases however, a state change will be independent from a navigation or reload — for example when a page contains an expandable/collapsible {{htmlelement("details")}} element. In this case, you might want to store the expanded/collapsed state in your history entry, so you can restore it when the user returns to the page or restarts their browser. Cases like this are handled using {{domxref("Navigation.updateCurrentEntry()")}}. The {{domxref("Navigation/currententrychange_event", "currententrychange")}} will fire when the current entry change is complete. + +### Limitations + +There are a few perceived limitations with the Navigation API: + +1. The current specification doesn't trigger a {{domxref("Navigation.navigate_event", "navigate")}} event on a page's first load. This might be fine for sites that use Server Side Rendering (SSR)—your server could return the correct initial state, which is the fastest way to get content to your users. But sites that leverage client-side code to create their pages may need an additional function to initialize the page. +2. The Navigation API operates only within a single frame—the top-level page, or a single specific {{htmlelement("iframe")}}. This has some interesting implications that are [further documented in the spec](https://github.com/WICG/navigation-api#warning-backforward-are-not-always-opposites), but in practice, will reduce developer confusion. The previous {{domxref("History API", "History API", "", "nocode")}} has several confusing edge cases, like support for frames, which the Navigation API handles up-front. +3. You can't currently use the Navigation API to programmatically modify or rearrange the history list. It might be useful to have a temporary state, for example navigating the user to a temporary modal that asks them for some information, then going back to the previous URL. In this case, you'd want to delete the temporary modal navigation entry so the user cannot mess up the application flow by hitting the forward button and opening it again. + +## Interfaces + +- {{domxref("NavigateEvent")}} + - : Event object for the {{domxref("Navigation/navigate_event", "navigate")}} event, which fires when [any type of navigation](https://github.com/WICG/navigation-api#appendix-types-of-navigations) is initiated. It provides access to information about that navigation, and most notably the {{domxref("NavigateEvent.intercept", "intercept()")}}, which allows you to control what happens when the navigation is initiated. +- {{domxref("Navigation")}} + - : Allows control over all navigation actions for the current `window` in one central place, including initiating navigations programmatically, examining navigation history entries, and managing navigations as they happen. +- {{domxref("NavigationCurrentEntryChangeEvent")}} + - : Event object for the {{domxref("Navigation/currententrychange_event", "currententrychange")}} event, which fires when the {{domxref("Navigation.currentEntry")}} has changed. It provides access to the navigation type, and the previous history entry that was navigated from. +- {{domxref("NavigationDestination")}} + - : Represents the destination being navigated to in the current navigation. +- {{domxref("NavigationHistoryEntry")}} + - : Represents a single navigation history entry. +- {{domxref("NavigationTransition")}} + - : Represents an ongoing navigation. + +## Extensions to other interfaces + +- {{domxref("Window.navigation")}} + - : Returns the current `window`'s associated {{domxref("Navigation")}} object. Entry point for the API. + +## Examples + +> **Note:** Check out Domenic Denicola's [Navigation API live demo](https://gigantic-honored-octagon.glitch.me/). + +### Handling a navigation using `intercept()` + +```js +navigation.addEventListener('navigate', (event) => { + // Exit early if this navigation shouldn't be intercepted, + // e.g. if the navigation is cross-origin, or a download request + if (shouldNotIntercept(event)) { + return; + } + + const url = new URL(event.destination.url); + + if (url.pathname.startsWith('/articles/')) { + event.intercept({ + async handler() { + // The URL has already changed, so show a placeholder while + //fetching the new content, such as a spinner or loading page + renderArticlePagePlaceholder(); + + // Fetch the new content and display when ready + const articleContent = await getArticleContent(url.pathname); + renderArticlePage(articleContent); + }, + }); + } +}); +``` + +### Handling scrolling using `scroll()` + +In this example of intercepting a navigation, the `handler()` function starts by fetching and rendering some article content, but then fetches and renders some secondary content afterwards. It makes sense to scroll the page to the main article content as soon as it is available so the user can interact with it, rather than waiting until the secondary content is also rendered. To achieve this, we have added a {{domxref("NavigateEvent.scroll", "scroll()")}} call between the two. + +```js +navigation.addEventListener('navigate', (event) => { + if (shouldNotIntercept(event)) { + return; + } + const url = new URL(event.destination.url); + + if (url.pathname.startsWith('/articles/')) { + event.intercept({ + async handler() { + const articleContent = await getArticleContent(url.pathname); + renderArticlePage(articleContent); + + event.scroll(); + + const secondaryContent = await getSecondaryContent(url.pathname); + addSecondaryContent(secondaryContent); + }, + }); + } +}); +``` + +### Traversing to a specific history entry + +```js +// On JS startup, get the key of the first loaded page +// so the user can always go back there. +const {key} = navigation.currentEntry; +backToHomeButton.onclick = () => navigation.traverseTo(key); + +// Navigate away, but the button will always work. +await navigation.navigate('/another_url').finished; +``` + +### Updating state + +```js +navigation.navigate(url, {state: newState}); +``` + +Or + +```js +navigation.reload({state: newState}); +``` + +Or if the state is independent from a navigation or reload: + +```js +navigation.updateCurrentEntry({state: newState}); +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- [Modern client-side routing: the Navigation API](https://developer.chrome.com/docs/web-platform/navigation-api/) +- [Navigation API explainer](https://github.com/WICG/navigation-api/blob/main/README.md) diff --git a/files/en-us/web/api/navigationcurrententrychangeevent/from/index.md b/files/en-us/web/api/navigationcurrententrychangeevent/from/index.md new file mode 100644 index 000000000000000..54c0d42552f6739 --- /dev/null +++ b/files/en-us/web/api/navigationcurrententrychangeevent/from/index.md @@ -0,0 +1,50 @@ +--- +title: NavigationCurrentEntryChangeEvent.from +slug: Web/API/NavigationCurrentEntryChangeEvent/from +page-type: web-api-instance-property +tags: + - API + - Experimental + - from + - History + - Navigate + - Navigation + - Navigation API + - Property + - Read-only + - Reference + - Scroll + - Traversal +browser-compat: api.NavigationCurrentEntryChangeEvent.from +--- + +{{APIRef("Navigation API")}}{{seecompattable}} + +The **`from`** read-only property of the +{{domxref("NavigationCurrentEntryChangeEvent")}} interface returns the {{domxref("NavigationHistoryEntry")}} that was navigated from. + +## Value + +A {{domxref("NavigationHistoryEntry")}} object. + +## Examples + +```js +navigation.addEventListener("currententrychange", (event) => { + console.log(event.from); +}); +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- [Modern client-side routing: the Navigation API](https://developer.chrome.com/docs/web-platform/navigation-api/) +- [Navigation API explainer](https://github.com/WICG/navigation-api/blob/main/README.md) +- Domenic Denicola's [Navigation API live demo](https://gigantic-honored-octagon.glitch.me/) diff --git a/files/en-us/web/api/navigationcurrententrychangeevent/index.md b/files/en-us/web/api/navigationcurrententrychangeevent/index.md new file mode 100644 index 000000000000000..c96c97d4a2c3c41 --- /dev/null +++ b/files/en-us/web/api/navigationcurrententrychangeevent/index.md @@ -0,0 +1,75 @@ +--- +title: NavigationCurrentEntryChangeEvent +slug: Web/API/NavigationCurrentEntryChangeEvent +page-type: web-api-interface +tags: + - API + - Experimental + - History + - Interface + - Landing + - Navigate + - NavigationCurrentEntryChangeEvent + - Navigation API + - Reference + - Scroll + - Traversal +browser-compat: api.NavigationCurrentEntryChangeEvent +--- + +{{APIRef("Navigation API")}}{{seecompattable}} + +The **`NavigationCurrentEntryChangeEvent`** interface of the {{domxref("Navigation API", "Navigation API", "", "nocode")}} is the event object for the {{domxref("Navigation/currententrychange_event", "currententrychange")}} event, which fires when the {{domxref("Navigation.currentEntry")}} has changed. + +This event will fire for same-document navigations (e.g. {{domxref("Navigation.back", "back()")}} or {{domxref("Navigation.traverseTo", "traverseTo()")}}), replacements (i.e. a {{domxref("Navigation.navigate", "navigate()")}} call with `history` set to `replace`), or other calls that change the entry's state (e.g. {{domxref("Navigation.updateCurrentEntry", "updateCurrentEntry()")}}, or the {{domxref("History API", "History API", "", "nocode")}}'s {{domxref("History.replaceState()")}}). + +This event fires after the navigation is committed, meaning that the visible URL has changed and the {{domxref("NavigationHistoryEntry")}} update has occurred. It is useful for migrating from usage of older API features like the {{domxref("Window/hashchange_event", "hashchange")}} or {{domxref("Window/popstate_event", "popstate")}} events. + +{{InheritanceDiagram}} + +## Constructor + +- {{domxref("NavigationCurrentEntryChangeEvent.NavigationCurrentEntryChangeEvent", "NavigationCurrentEntryChangeEvent()")}} + - : Creates a new `NavigationCurrentEntryChangeEvent` object instance. + +## Instance properties + +_Inherits properties from its parent, {{DOMxRef("Event")}}._ + +- {{domxref("NavigationCurrentEntryChangeEvent.from", "from")}} {{ReadOnlyInline}} + - : Returns the {{domxref("NavigationHistoryEntry")}} that was navigated from. +- {{domxref("NavigationCurrentEntryChangeEvent.navigationType", "navigationType")}} {{ReadOnlyInline}} + - : Returns the type of the navigation that resulted in the change. + +## Examples + +Navigation data reporting: + +```js +navigation.addEventListener("currententrychange", () => { + const data = navigation.currentEntry.getState(); + submitAnalyticsData(data.analytics); +}); +``` + +Setting up a per-entry event: + +```js +navigation.addEventListener("currententrychange", () => { + navigation.currentEntry.addEventListener("dispose", genericDisposeHandler); +}); +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- [Modern client-side routing: the Navigation API](https://developer.chrome.com/docs/web-platform/navigation-api/) +- [Navigation API explainer](https://github.com/WICG/navigation-api/blob/main/README.md) +- Domenic Denicola's [Navigation API live demo](https://gigantic-honored-octagon.glitch.me/) diff --git a/files/en-us/web/api/navigationcurrententrychangeevent/navigationcurrententrychangeevent/index.md b/files/en-us/web/api/navigationcurrententrychangeevent/navigationcurrententrychangeevent/index.md new file mode 100644 index 000000000000000..b12ce6fca7f3e0b --- /dev/null +++ b/files/en-us/web/api/navigationcurrententrychangeevent/navigationcurrententrychangeevent/index.md @@ -0,0 +1,63 @@ +--- +title: NavigationCurrentEntryChangeEvent() +slug: Web/API/NavigationCurrentEntryChangeEvent/NavigationCurrentEntryChangeEvent +page-type: web-api-constructor +tags: + - API + - Constructor + - Experimental + - History + - Navigate + - Navigation + - Navigation API + - Reference + - Scroll + - Traversal +browser-compat: api.NavigationCurrentEntryChangeEvent.NavigationCurrentEntryChangeEvent +--- + +{{APIRef("Navigation API")}}{{seecompattable}} + +The **`NavigationCurrentEntryChangeEvent()`** constructor creates a new +{{domxref("NavigationCurrentEntryChangeEvent")}} object. + +## Syntax + +```js-nolint +new NavigationCurrentEntryChangeEvent(type, init) +``` + +### Parameters + +- `type` + - : A string representing the type of event. In the case of `NavigationCurrentEntryChangeEvent` this is always `event`. +- `init` + - : An object containing the following properties: + - `destination` + - : A {{domxref("NavigationHistoryEntry")}} object representing the location being navigated to. + - `navigationType` + - : The type of the navigation that resulted in the change. Possible values — `push`, `reload`, `replace`, and `traverse`. + +## Examples + +A developer would not use this constructor manually. A new `NavigationCurrentEntryChangeEvent` object is constructed when a handler is invoked as a result of the {{domxref("Navigation.currententrychange_event", "currententrychange")}} event firing. + +```js +navigation.addEventListener("currententrychange", (event) => { + console.log(event.navigationType); +}); +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- [Modern client-side routing: the Navigation API](https://developer.chrome.com/docs/web-platform/navigation-api/) +- [Navigation API explainer](https://github.com/WICG/navigation-api/blob/main/README.md) +- Domenic Denicola's [Navigation API live demo](https://gigantic-honored-octagon.glitch.me/) diff --git a/files/en-us/web/api/navigationcurrententrychangeevent/navigationtype/index.md b/files/en-us/web/api/navigationcurrententrychangeevent/navigationtype/index.md new file mode 100644 index 000000000000000..b432e10cb263784 --- /dev/null +++ b/files/en-us/web/api/navigationcurrententrychangeevent/navigationtype/index.md @@ -0,0 +1,57 @@ +--- +title: NavigationCurrentEntryChangeEvent.navigationType +slug: Web/API/NavigationCurrentEntryChangeEvent/navigationType +page-type: web-api-instance-property +tags: + - API + - Experimental + - History + - Navigate + - Navigation + - Navigation API + - navigationType + - Property + - Read-only + - Reference + - Scroll + - Traversal +browser-compat: api.NavigationCurrentEntryChangeEvent.navigationType +--- + +{{APIRef("Navigation API")}}{{seecompattable}} + +The **`navigationType`** read-only property of the +{{domxref("NavigationCurrentEntryChangeEvent")}} interface returns the type of the navigation that resulted in the change. + +## Value + +An enumerated value representing the type of navigation. + +The possible values are: + +- `push`: A new location is navigated to, causing a new entry to be pushed onto the history list. +- `reload`: The {{domxref("Navigation.currentEntry")}} is reloaded. +- `replace`: The {{domxref("Navigation.currentEntry")}} is replaced with a new history entry. This new entry will reuse the same {{domxref("NavigationHistoryEntry.key", "key")}}, but be assigned a different {{domxref("NavigationHistoryEntry.id", "id")}}. +- `traverse`: The browser navigates from one existing history entry to another existing history entry. + +## Examples + +```js +navigation.addEventListener("currententrychange", (event) => { + console.log(event.navigationType); +}); +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- [Modern client-side routing: the Navigation API](https://developer.chrome.com/docs/web-platform/navigation-api/) +- [Navigation API explainer](https://github.com/WICG/navigation-api/blob/main/README.md) +- Domenic Denicola's [Navigation API live demo](https://gigantic-honored-octagon.glitch.me/) diff --git a/files/en-us/web/api/navigationdestination/getstate/index.md b/files/en-us/web/api/navigationdestination/getstate/index.md new file mode 100644 index 000000000000000..db54e6e0ac2d1aa --- /dev/null +++ b/files/en-us/web/api/navigationdestination/getstate/index.md @@ -0,0 +1,67 @@ +--- +title: NavigationDestination.getState() +slug: Web/API/NavigationDestination/getState +page-type: web-api-instance-method +tags: + - API + - Experimental + - getState + - History + - Method + - Navigate + - Navigation + - Navigation API + - Reference + - Scroll + - transition + - Traversal +browser-compat: api.NavigationDestination.getState +--- + +{{APIRef("Navigation API")}}{{seecompattable}} + +The **`getState()`** method of the +{{domxref("NavigationDestination")}} interface returns a clone of the developer-supplied state associated with the destination {{domxref("NavigationHistoryEntry")}}, or navigation operation (e.g. {{domxref("Navigation.navigate()", "navigate()")}}) as appropriate. + +## Syntax + +```js-nolint +getState() +``` + +### Parameters + +None. + +### Return value + +A value representing the state. This can be any type. + +If no state is defined, it returns `undefined`. + +### Exceptions + +None. + +## Examples + +```js +navigation.addEventListener('navigate', (event) => { + console.log(event.destination.getState()); +}); +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- [Modern client-side routing: the Navigation API](https://developer.chrome.com/docs/web-platform/navigation-api/) +- [Navigation API explainer](https://github.com/WICG/navigation-api/blob/main/README.md) +- Domenic Denicola's [Navigation API live demo](https://gigantic-honored-octagon.glitch.me/) +- Methods that allow state to be updated — {{domxref("Navigation.navigate()")}}, {{domxref("Navigation.reload()")}}, and {{domxref("Navigation.updateCurrentEntry()")}} diff --git a/files/en-us/web/api/navigationdestination/id/index.md b/files/en-us/web/api/navigationdestination/id/index.md new file mode 100644 index 000000000000000..892e365911d9588 --- /dev/null +++ b/files/en-us/web/api/navigationdestination/id/index.md @@ -0,0 +1,52 @@ +--- +title: NavigationDestination.id +slug: Web/API/NavigationDestination/id +page-type: web-api-instance-property +tags: + - API + - Experimental + - History + - id + - Navigate + - Navigation + - Navigation API + - Property + - Read-only + - Reference + - Scroll + - Traversal +browser-compat: api.NavigationDestination.id +--- + +{{APIRef("Navigation API")}}{{seecompattable}} + +The **`id`** read-only property of the +{{domxref("NavigationDestination")}} interface returns the {{domxref("NavigationHistoryEntry.id", "id")}} value of the destination {{domxref("NavigationHistoryEntry")}} if the {{domxref("NavigateEvent.navigationType")}} is `traverse`, or `null` otherwise. + +The `id` is a unique, UA-generated value that always represents the history entry, useful to correlate a history entry with an external resource such as a storage cache. + +## Value + +A string representing the `id` of the destination {{domxref("NavigationHistoryEntry")}}, or `null`. + +## Examples + +```js +navigation.addEventListener('navigate', (event) => { + console.log(event.destination.id); +}); +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- [Modern client-side routing: the Navigation API](https://developer.chrome.com/docs/web-platform/navigation-api/) +- [Navigation API explainer](https://github.com/WICG/navigation-api/blob/main/README.md) +- Domenic Denicola's [Navigation API live demo](https://gigantic-honored-octagon.glitch.me/) diff --git a/files/en-us/web/api/navigationdestination/index.md b/files/en-us/web/api/navigationdestination/index.md new file mode 100644 index 000000000000000..48491c360bfb77e --- /dev/null +++ b/files/en-us/web/api/navigationdestination/index.md @@ -0,0 +1,88 @@ +--- +title: NavigationDestination +slug: Web/API/NavigationDestination +page-type: web-api-interface +tags: + - API + - Experimental + - History + - Interface + - Landing + - Navigate + - NavigationDestination + - Navigation API + - Reference + - Scroll + - Traversal +browser-compat: api.NavigationDestination +--- + +{{APIRef("Navigation API")}}{{seecompattable}} + +The **`NavigationDestination`** interface of the {{domxref("Navigation API", "Navigation API", "", "nocode")}} represents the destination being navigated to in the current navigation. + +It is accessed via the {{domxref("NavigateEvent.destination")}} property. + +{{InheritanceDiagram}} + +## Instance properties + +- {{domxref("NavigationDestination.id", "id")}} {{ReadOnlyInline}} + - : Returns the {{domxref("NavigationHistoryEntry.id", "id")}} value of the destination {{domxref("NavigationHistoryEntry")}} if the {{domxref("NavigateEvent.navigationType")}} is `traverse`, or `null` otherwise. +- {{domxref("NavigationDestination.index", "index")}} {{ReadOnlyInline}} + - : Returns the {{domxref("NavigationHistoryEntry.index", "index")}} value of the destination {{domxref("NavigationHistoryEntry")}} if the {{domxref("NavigateEvent.navigationType")}} is `traverse`, or `-1` otherwise. +- {{domxref("NavigationDestination.key", "key")}} {{ReadOnlyInline}} + - : Returns the {{domxref("NavigationHistoryEntry.key", "key")}} value of the destination {{domxref("NavigationHistoryEntry")}} if the {{domxref("NavigateEvent.navigationType")}} is `traverse`, or `null` otherwise. +- {{domxref("NavigationDestination.sameDocument", "sameDocument")}} {{ReadOnlyInline}} + - : Returns `true` if the navigation is to the same `document` as the current {{domxref("Document")}} value, or `false` otherwise. +- {{domxref("NavigationDestination.url", "url")}} {{ReadOnlyInline}} + - : Returns the URL being navigated to. + +## Instance methods + +- {{domxref("NavigationDestination.getState", "getState()")}} + - : Returns a clone of the available state associated with the destination {{domxref("NavigationHistoryEntry")}}, or navigation operation (e.g. {{domxref("Navigation.navigate()", "navigate()")}}) as appropriate. + +## Examples + +```js +navigation.addEventListener('navigate', (event) => { + // Exit early if this navigation shouldn't be intercepted, + // e.g. if the navigation is cross-origin, or a download request + if (shouldNotIntercept(event)) { + return; + } + + // Returns a URL() object constructed from the + // NavigationDestination.url value + const url = new URL(event.destination.url); + + if (url.pathname.startsWith('/articles/')) { + event.intercept({ + async handler() { + // The URL has already changed, so show a placeholder while + //fetching the new content, such as a spinner or loading page + renderArticlePagePlaceholder(); + + // Fetch the new content and display when ready + const articleContent = await getArticleContent(url.pathname); + renderArticlePage(articleContent); + }, + }); + } +}); +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- [Modern client-side routing: the Navigation API](https://developer.chrome.com/docs/web-platform/navigation-api/) +- [Navigation API explainer](https://github.com/WICG/navigation-api/blob/main/README.md) +- Domenic Denicola's [Navigation API live demo](https://gigantic-honored-octagon.glitch.me/) diff --git a/files/en-us/web/api/navigationdestination/index/index.md b/files/en-us/web/api/navigationdestination/index/index.md new file mode 100644 index 000000000000000..460a49b6f6c7971 --- /dev/null +++ b/files/en-us/web/api/navigationdestination/index/index.md @@ -0,0 +1,50 @@ +--- +title: NavigationDestination.index +slug: Web/API/NavigationDestination/index +page-type: web-api-instance-property +tags: + - API + - Experimental + - History + - index + - Navigate + - Navigation + - Navigation API + - Property + - Read-only + - Reference + - Scroll + - Traversal +browser-compat: api.NavigationDestination.index +--- + +{{APIRef("Navigation API")}}{{seecompattable}} + +The **`index`** read-only property of the +{{domxref("NavigationDestination")}} interface returns the {{domxref("NavigationHistoryEntry.index", "index")}} value of the destination {{domxref("NavigationHistoryEntry")}} if the {{domxref("NavigateEvent.navigationType")}} is `traverse`, or `-1` otherwise. + +## Value + +A number representing the `index` of the destination {{domxref("NavigationHistoryEntry")}}, or -1. + +## Examples + +```js +navigation.addEventListener('navigate', (event) => { + console.log(event.destination.index); +}); +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- [Modern client-side routing: the Navigation API](https://developer.chrome.com/docs/web-platform/navigation-api/) +- [Navigation API explainer](https://github.com/WICG/navigation-api/blob/main/README.md) +- Domenic Denicola's [Navigation API live demo](https://gigantic-honored-octagon.glitch.me/) diff --git a/files/en-us/web/api/navigationdestination/key/index.md b/files/en-us/web/api/navigationdestination/key/index.md new file mode 100644 index 000000000000000..8d08ef44c7b1b8a --- /dev/null +++ b/files/en-us/web/api/navigationdestination/key/index.md @@ -0,0 +1,52 @@ +--- +title: NavigationDestination.key +slug: Web/API/NavigationDestination/key +page-type: web-api-instance-property +tags: + - API + - Experimental + - History + - key + - Navigate + - Navigation + - Navigation API + - Property + - Read-only + - Reference + - Scroll + - Traversal +browser-compat: api.NavigationDestination.key +--- + +{{APIRef("Navigation API")}}{{seecompattable}} + +The **`key`** read-only property of the +{{domxref("NavigationDestination")}} interface returns the {{domxref("NavigationHistoryEntry.key", "key")}} value of the destination {{domxref("NavigationHistoryEntry")}} if the {{domxref("NavigateEvent.navigationType")}} is `traverse`, or `null` otherwise. + +The `key` is a unique, UA-generated value that represents the history entry's slot in the history entries list, used to navigate to this place in the history via {{domxref("Navigation.traverseTo()")}}. It will be reused by other entries that replace the entry in the list (i.e. if the {{domxref("NavigateEvent.navigationType")}} is `replace`). + +## Value + +A string representing the `key` of the destination {{domxref("NavigationHistoryEntry")}}, or `null`. + +## Examples + +```js +navigation.addEventListener('navigate', (event) => { + console.log(event.destination.key); +}); +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- [Modern client-side routing: the Navigation API](https://developer.chrome.com/docs/web-platform/navigation-api/) +- [Navigation API explainer](https://github.com/WICG/navigation-api/blob/main/README.md) +- Domenic Denicola's [Navigation API live demo](https://gigantic-honored-octagon.glitch.me/) diff --git a/files/en-us/web/api/navigationdestination/samedocument/index.md b/files/en-us/web/api/navigationdestination/samedocument/index.md new file mode 100644 index 000000000000000..84b5f5f9d86d9eb --- /dev/null +++ b/files/en-us/web/api/navigationdestination/samedocument/index.md @@ -0,0 +1,52 @@ +--- +title: NavigationDestination.sameDocument +slug: Web/API/NavigationDestination/sameDocument +page-type: web-api-instance-property +tags: + - API + - Experimental + - History + - Navigate + - Navigation + - Navigation API + - Property + - Read-only + - Reference + - sameDocument + - Scroll + - Traversal +browser-compat: api.NavigationDestination.sameDocument +--- + +{{APIRef("Navigation API")}}{{seecompattable}} + +The **`sameDocument`** read-only property of the +{{domxref("NavigationDestination")}} interface returns `true` if the navigation is to the same `document` as the current {{domxref("Document")}} value, or `false` otherwise. + +This is useful for checking whether the navigation will be same-document or cross-document. + +## Value + +A boolean. + +## Examples + +```js +navigation.addEventListener('navigate', (event) => { + console.log(event.destination.sameDocument); +}); +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- [Modern client-side routing: the Navigation API](https://developer.chrome.com/docs/web-platform/navigation-api/) +- [Navigation API explainer](https://github.com/WICG/navigation-api/blob/main/README.md) +- Domenic Denicola's [Navigation API live demo](https://gigantic-honored-octagon.glitch.me/) diff --git a/files/en-us/web/api/navigationdestination/url/index.md b/files/en-us/web/api/navigationdestination/url/index.md new file mode 100644 index 000000000000000..8723a19a7e714c1 --- /dev/null +++ b/files/en-us/web/api/navigationdestination/url/index.md @@ -0,0 +1,72 @@ +--- +title: NavigationDestination.url +slug: Web/API/NavigationDestination/url +page-type: web-api-instance-property +tags: + - API + - Experimental + - History + - Navigate + - Navigation + - Navigation API + - Property + - Read-only + - Reference + - Scroll + - Traversal + - url +browser-compat: api.NavigationDestination.url +--- + +{{APIRef("Navigation API")}}{{seecompattable}} + +The **`url`** read-only property of the +{{domxref("NavigationDestination")}} interface returns the URL being navigated to. + +## Value + +A string. + +## Examples + +### Handling a navigation using `intercept()` + +```js +navigation.addEventListener('navigate', (event) => { + // Exit early if this navigation shouldn't be intercepted, + // e.g. if the navigation is cross-origin, or a download request + if (shouldNotIntercept(event)) { + return; + } + + const url = new URL(event.destination.url); + + if (url.pathname.startsWith('/articles/')) { + event.intercept({ + async handler() { + // The URL has already changed, so show a placeholder while + //fetching the new content, such as a spinner or loading page + renderArticlePagePlaceholder(); + + // Fetch the new content and display when ready + const articleContent = await getArticleContent(url.pathname); + renderArticlePage(articleContent); + }, + }); + } +}); +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- [Modern client-side routing: the Navigation API](https://developer.chrome.com/docs/web-platform/navigation-api/) +- [Navigation API explainer](https://github.com/WICG/navigation-api/blob/main/README.md) +- Domenic Denicola's [Navigation API live demo](https://gigantic-honored-octagon.glitch.me/) diff --git a/files/en-us/web/api/navigationhistoryentry/dispose_event/index.md b/files/en-us/web/api/navigationhistoryentry/dispose_event/index.md new file mode 100644 index 000000000000000..1d3cb6091540cb7 --- /dev/null +++ b/files/en-us/web/api/navigationhistoryentry/dispose_event/index.md @@ -0,0 +1,67 @@ +--- +title: "NavigationHistoryEntry: dispose event" +slug: Web/API/NavigationHistoryEntry/dispose_event +page-type: web-api-event +tags: + - API + - dispose + - Event + - Experimental + - History + - Navigate + - navigateerror + - Navigation + - Navigation API + - Property + - Reference + - Scroll + - Traversal + - updateCurrentEntry +browser-compat: api.NavigationHistoryEntry.dispose_event +--- + +{{APIRef("Navigation API")}}{{SeeCompatTable}} + +The **`dispose`** event of the {{domxref("NavigationHistoryEntry")}} interface is fired when the entry is no longer part of the history entry list. + +Disposal occurs when: + +- Forward history entries are cleared. See the example at [Notifications on entry disposal](https://github.com/wicg/navigation-api#notifications-on-entry-disposal) for more information. +- The user clears their browser history using settings or provided UI controls. +- The history limit is exceeded. This is not specified anywhere, but browsers tend to have a history limit of 50 pages. + +## Syntax + +Use the event name in methods like {{domxref("EventTarget.addEventListener", "addEventListener()")}}, or set an event handler property. + +```js +addEventListener("dispose", (event) => {}); + +ondispose = (event) => {}; +``` + +## Event type + +A generic {{domxref("Event")}}. + +## Examples + +```js +navigation.addEventListener("currententrychange", () => { + navigation.currentEntry.addEventListener("dispose", disposeHandler); +}); +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- [Modern client-side routing: the Navigation API](https://developer.chrome.com/docs/web-platform/navigation-api/) +- [Navigation API explainer](https://github.com/WICG/navigation-api/blob/main/README.md) +- Domenic Denicola's [Navigation API live demo](https://gigantic-honored-octagon.glitch.me/) diff --git a/files/en-us/web/api/navigationhistoryentry/getstate/index.md b/files/en-us/web/api/navigationhistoryentry/getstate/index.md new file mode 100644 index 000000000000000..62b6a009f96d0c4 --- /dev/null +++ b/files/en-us/web/api/navigationhistoryentry/getstate/index.md @@ -0,0 +1,72 @@ +--- +title: NavigationHistoryEntry.getState() +slug: Web/API/NavigationHistoryEntry/getState +page-type: web-api-instance-method +tags: + - API + - Experimental + - getState + - History + - Method + - Navigate + - Navigation + - Navigation API + - Reference + - Scroll + - transition + - Traversal +browser-compat: api.NavigationHistoryEntry.getState +--- + +{{APIRef("Navigation API")}}{{seecompattable}} + +The **`getState()`** method of the +{{domxref("NavigationHistoryEntry")}} interface returns a clone of the developer-supplied state associated with this history entry. + +## Syntax + +```js-nolint +getState() +``` + +### Parameters + +None. + +### Return value + +A value representing the state. This can be any [structured-clonable](/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm) data type. + +If no state is defined, it returns `undefined`. + +### Exceptions + +None. + +## Examples + +```js +async function handleReload() { + // Update existing state via reload() + await navigation.reload({ state: { ...navigation.currentEntry.getState(), newState: 3 } }); + + // Print current state to the console + const current = navigation.currentEntry; + console.log(current.getState()); +} +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- [Modern client-side routing: the Navigation API](https://developer.chrome.com/docs/web-platform/navigation-api/) +- [Navigation API explainer](https://github.com/WICG/navigation-api/blob/main/README.md) +- Domenic Denicola's [Navigation API live demo](https://gigantic-honored-octagon.glitch.me/) +- Methods that allow state to be updated — {{domxref("Navigation.navigate()")}}, {{domxref("Navigation.reload()")}}, and {{domxref("Navigation.updateCurrentEntry()")}} diff --git a/files/en-us/web/api/navigationhistoryentry/id/index.md b/files/en-us/web/api/navigationhistoryentry/id/index.md new file mode 100644 index 000000000000000..dc5bb7e5bb88640 --- /dev/null +++ b/files/en-us/web/api/navigationhistoryentry/id/index.md @@ -0,0 +1,51 @@ +--- +title: NavigationHistoryEntry.id +slug: Web/API/NavigationHistoryEntry/id +page-type: web-api-instance-property +tags: + - API + - Experimental + - History + - id + - Navigate + - Navigation + - Navigation API + - Property + - Read-only + - Reference + - Scroll + - Traversal +browser-compat: api.NavigationHistoryEntry.id +--- + +{{APIRef("Navigation API")}}{{seecompattable}} + +The **`id`** read-only property of the +{{domxref("NavigationHistoryEntry")}} interface returns the `id` of the history entry. This is a unique, UA-generated value that always represents a specific history entry, useful to correlate it with an external resource such as a storage cache. + +This differs from the {{domxref("NavigationHistoryEntry.key", "key")}} of a history entry. The `key` is a unique, UA-generated value that represents the history entry's slot in the entries list rather than the entry itself. It is used to navigate that particular slot via {{domxref("Navigation.traverseTo()")}}. The `key` will be reused by other entries that replace the entry in the list (that is, if the {{domxref("NavigateEvent.navigationType")}} is `replace`). + +## Value + +A string representing the `id` of the {{domxref("NavigationHistoryEntry")}}. + +## Examples + +```js +const current = navigation.currentEntry; +console.log(current.id); +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- [Modern client-side routing: the Navigation API](https://developer.chrome.com/docs/web-platform/navigation-api/) +- [Navigation API explainer](https://github.com/WICG/navigation-api/blob/main/README.md) +- Domenic Denicola's [Navigation API live demo](https://gigantic-honored-octagon.glitch.me/) diff --git a/files/en-us/web/api/navigationhistoryentry/index.md b/files/en-us/web/api/navigationhistoryentry/index.md new file mode 100644 index 000000000000000..eff0a5350facc5f --- /dev/null +++ b/files/en-us/web/api/navigationhistoryentry/index.md @@ -0,0 +1,92 @@ +--- +title: NavigationHistoryEntry +slug: Web/API/NavigationHistoryEntry +page-type: web-api-interface +tags: + - API + - Experimental + - History + - Interface + - Landing + - Navigate + - NavigationHistoryEntry + - Navigation API + - Reference + - Scroll + - Traversal +browser-compat: api.NavigationHistoryEntry +--- + +{{APIRef("Navigation API")}}{{seecompattable}} + +The **`NavigationHistoryEntry`** interface of the {{domxref("Navigation API", "Navigation API", "", "nocode")}} represents a single navigation history entry. + +These objects are commonly accessed via the {{domxref("Navigation.currentEntry")}} property and {{domxref("Navigation.entries()")}} method. + +The Navigation API only exposes history entries created in the current browsing context that have the same origin as the current page (e.g. not navigations inside embedded {{htmlelement("iframe")}}s, or cross-origin navigations), providing an accurate list of all previous history entries just for your app. This makes traversing the history a much less fragile proposition than with the older {{domxref("History API", "History API", "", "nocode")}}. + +{{InheritanceDiagram}} + +## Instance properties + +_Inherits properties from its parent, {{DOMxRef("EventTarget")}}._ + +- {{domxref("NavigationHistoryEntry.id", "id")}} {{ReadOnlyInline}} + - : Returns the `id` of the history entry. This is a unique, UA-generated value that always represents a specific history entry, useful to correlate it with an external resource such as a storage cache. +- {{domxref("NavigationHistoryEntry.index", "index")}} {{ReadOnlyInline}} + - : Returns the index of the history entry in the history entries list (that is, the list returned by {{domxref("Navigation.entries()")}}), or `-1` if the entry does not appear in the list. +- {{domxref("NavigationHistoryEntry.key", "key")}} {{ReadOnlyInline}} + - : Returns the `key` of the history entry. This is a unique, UA-generated value that represents the history entry's slot in the entries list rather than the entry itself. It is used to navigate that particular slot via {{domxref("Navigation.traverseTo()")}}. The `key` will be reused by other entries that replace the entry in the list (that is, if the {{domxref("NavigateEvent.navigationType")}} is `replace`). +- {{domxref("NavigationHistoryEntry.sameDocument", "sameDocument")}} {{ReadOnlyInline}} + - : Returns `true` if this history entry is for the same `document` as the current {{domxref("Document")}} value, or `false` otherwise. +- {{domxref("NavigationHistoryEntry.url", "url")}} {{ReadOnlyInline}} + - : Returns the absolute URL of this history entry. + +## Instance methods + +_Inherits methods from its parent, {{DOMxRef("EventTarget")}}._ + +- {{domxref("NavigationHistoryEntry.getState", "getState()")}} + - : Returns a clone of the available state associated with this history entry. + +## Events + +- {{domxref("NavigationHistoryEntry/dispose_event", "dispose")}} + - : Fires when the entry is no longer part of the history entry list. + +## Examples + +```js +function initHomeBtn() { + // Get the key of the first loaded entry + // so the user can always go back to this view. + const {key} = navigation.currentEntry; + backToHomeButton.onclick = () => { + navigation.traverseTo(key); + } +} +// Intercept navigate events, such as link clicks, and +// replace them with single-page navigations +navigation.addEventListener("navigate", event => { + event.intercept({ + async handler() { + // Navigate to a different view, + // but the "home" button will always work. + } + }); +}); +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- [Modern client-side routing: the Navigation API](https://developer.chrome.com/docs/web-platform/navigation-api/) +- [Navigation API explainer](https://github.com/WICG/navigation-api/blob/main/README.md) +- Domenic Denicola's [Navigation API live demo](https://gigantic-honored-octagon.glitch.me/) diff --git a/files/en-us/web/api/navigationhistoryentry/index/index.md b/files/en-us/web/api/navigationhistoryentry/index/index.md new file mode 100644 index 000000000000000..c39924594e28ea2 --- /dev/null +++ b/files/en-us/web/api/navigationhistoryentry/index/index.md @@ -0,0 +1,49 @@ +--- +title: NavigationHistoryEntry.index +slug: Web/API/NavigationHistoryEntry/index +page-type: web-api-instance-property +tags: + - API + - Experimental + - History + - index + - Navigate + - Navigation + - Navigation API + - Property + - Read-only + - Reference + - Scroll + - Traversal +browser-compat: api.NavigationHistoryEntry.index +--- + +{{APIRef("Navigation API")}}{{seecompattable}} + +The **`index`** read-only property of the +{{domxref("NavigationHistoryEntry")}} interface returns the index of the history entry in the history entries list (that is, the list returned by {{domxref("Navigation.entries()")}}), or `-1` if the entry does not appear in the list. + +## Value + +A number representing the `index` of the entry in the history entries list, or `-1` if this item does not appear in the list. + +## Examples + +```js +const current = navigation.currentEntry; +console.log(current.index); +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- [Modern client-side routing: the Navigation API](https://developer.chrome.com/docs/web-platform/navigation-api/) +- [Navigation API explainer](https://github.com/WICG/navigation-api/blob/main/README.md) +- Domenic Denicola's [Navigation API live demo](https://gigantic-honored-octagon.glitch.me/) diff --git a/files/en-us/web/api/navigationhistoryentry/key/index.md b/files/en-us/web/api/navigationhistoryentry/key/index.md new file mode 100644 index 000000000000000..f0654a2d1888190 --- /dev/null +++ b/files/en-us/web/api/navigationhistoryentry/key/index.md @@ -0,0 +1,76 @@ +--- +title: NavigationHistoryEntry.key +slug: Web/API/NavigationHistoryEntry/key +page-type: web-api-instance-property +tags: + - API + - Experimental + - History + - key + - Navigate + - Navigation + - Navigation API + - Property + - Read-only + - Reference + - Scroll + - Traversal +browser-compat: api.NavigationHistoryEntry.key +--- + +{{APIRef("Navigation API")}}{{seecompattable}} + +The **`key`** read-only property of the +{{domxref("NavigationHistoryEntry")}} interface returns the `key` of the history entry. This is a unique, UA-generated value that represents the history entry's slot in the entries list. It is used to navigate that particular slot via {{domxref("Navigation.traverseTo()")}}. The `key` will be reused by other entries that replace the entry in the list (that is, if the {{domxref("NavigateEvent.navigationType")}} is `replace`). + +This differs from the {{domxref("NavigationHistoryEntry.id", "id")}} of a history entry. The `id` is a unique, UA-generated value that always represents a specific history entry rather than its slot in the entries list. This is useful to correlate it with an external resource such as a storage cache. + +## Value + +A string representing the `key` of the {{domxref("NavigationHistoryEntry")}}. + +## Examples + +### Basic usage + +```js +const current = navigation.currentEntry; +console.log(current.key); +``` + +### Set up a home button + +```js +function initHomeBtn() { + // Get the key of the first loaded entry + // so the user can always go back to this view. + const {key} = navigation.currentEntry; + backToHomeButton.onclick = () => { + navigation.traverseTo(key); + } +} +// Intercept navigate events, such as link clicks, and +// replace them with single-page navigations +navigation.addEventListener("navigate", event => { + event.intercept({ + async handler() { + // Navigate to a different view, + // but the "home" button will always work. + } + }); +}); +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- [Modern client-side routing: the Navigation API](https://developer.chrome.com/docs/web-platform/navigation-api/) +- [Navigation API explainer](https://github.com/WICG/navigation-api/blob/main/README.md) +- Domenic Denicola's [Navigation API live demo](https://gigantic-honored-octagon.glitch.me/) diff --git a/files/en-us/web/api/navigationhistoryentry/samedocument/index.md b/files/en-us/web/api/navigationhistoryentry/samedocument/index.md new file mode 100644 index 000000000000000..4af97ceaeff2526 --- /dev/null +++ b/files/en-us/web/api/navigationhistoryentry/samedocument/index.md @@ -0,0 +1,50 @@ +--- +title: NavigationHistoryEntry.sameDocument +slug: Web/API/NavigationHistoryEntry/sameDocument +page-type: web-api-instance-property +tags: + - API + - Experimental + - History + - Navigate + - Navigation + - Navigation API + - Property + - Read-only + - Reference + - sameDocument + - Scroll + - Traversal +browser-compat: api.NavigationHistoryEntry.sameDocument +--- + +{{APIRef("Navigation API")}}{{seecompattable}} + +The **`sameDocument`** read-only property of the +{{domxref("NavigationHistoryEntry")}} interface returns `true` if this history entry is for the same `document` as the current {{domxref("Document")}} value, or `false` otherwise. + +## Value + +A boolean. + +## Examples + +```js +const current = navigation.currentEntry; +console.log(current.sameDocument); +// Will always return true +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- [Modern client-side routing: the Navigation API](https://developer.chrome.com/docs/web-platform/navigation-api/) +- [Navigation API explainer](https://github.com/WICG/navigation-api/blob/main/README.md) +- Domenic Denicola's [Navigation API live demo](https://gigantic-honored-octagon.glitch.me/) diff --git a/files/en-us/web/api/navigationhistoryentry/url/index.md b/files/en-us/web/api/navigationhistoryentry/url/index.md new file mode 100644 index 000000000000000..c69694e6edb2f0a --- /dev/null +++ b/files/en-us/web/api/navigationhistoryentry/url/index.md @@ -0,0 +1,49 @@ +--- +title: NavigationHistoryEntry.url +slug: Web/API/NavigationHistoryEntry/url +page-type: web-api-instance-property +tags: + - API + - Experimental + - History + - Navigate + - Navigation + - Navigation API + - Property + - Read-only + - Reference + - Scroll + - Traversal + - url +browser-compat: api.NavigationHistoryEntry.url +--- + +{{APIRef("Navigation API")}}{{seecompattable}} + +The **`url`** read-only property of the +{{domxref("NavigationHistoryEntry")}} interface returns the absolute URL of this history entry. + +## Value + +A string representing the URL. + +## Examples + +```js +const current = navigation.currentEntry; +console.log(current.url); +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- [Modern client-side routing: the Navigation API](https://developer.chrome.com/docs/web-platform/navigation-api/) +- [Navigation API explainer](https://github.com/WICG/navigation-api/blob/main/README.md) +- Domenic Denicola's [Navigation API live demo](https://gigantic-honored-octagon.glitch.me/) diff --git a/files/en-us/web/api/navigationtransition/finished/index.md b/files/en-us/web/api/navigationtransition/finished/index.md new file mode 100644 index 000000000000000..a62be69cc121bd1 --- /dev/null +++ b/files/en-us/web/api/navigationtransition/finished/index.md @@ -0,0 +1,52 @@ +--- +title: NavigationTransition.finished +slug: Web/API/NavigationTransition/finished +page-type: web-api-instance-property +tags: + - API + - Experimental + - finished + - History + - Navigate + - Navigation + - Navigation API + - Property + - Read-only + - Reference + - Scroll + - Traversal +browser-compat: api.NavigationTransition.finished +--- + +{{APIRef("Navigation API")}}{{seecompattable}} + +The **`finished`** read-only property of the +{{domxref("NavigationTransition")}} interface returns a {{jsxref("Promise")}} that fulfills at the same time the {{domxref("Navigation/navigatesuccess_event", "navigatesuccess")}} event fires, or rejects at the same time the {{domxref("Navigation/navigateerror_event", "navigateerror")}} event fires. + +## Value + +A {{jsxref("Promise")}} that resolves to `undefined`. + +## Examples + +```js +async function cleanupNavigation() { + await navigation.transition.finished; + // Navigation has completed successfully + // Cleanup any ongoing monitoring +} +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- [Modern client-side routing: the Navigation API](https://developer.chrome.com/docs/web-platform/navigation-api/) +- [Navigation API explainer](https://github.com/WICG/navigation-api/blob/main/README.md) +- Domenic Denicola's [Navigation API live demo](https://gigantic-honored-octagon.glitch.me/) diff --git a/files/en-us/web/api/navigationtransition/from/index.md b/files/en-us/web/api/navigationtransition/from/index.md new file mode 100644 index 000000000000000..2198a9ec993d6f7 --- /dev/null +++ b/files/en-us/web/api/navigationtransition/from/index.md @@ -0,0 +1,48 @@ +--- +title: NavigationTransition.from +slug: Web/API/NavigationTransition/from +page-type: web-api-instance-property +tags: + - API + - Experimental + - from + - History + - Navigate + - Navigation + - Navigation API + - Property + - Read-only + - Reference + - Scroll + - Traversal +browser-compat: api.NavigationTransition.from +--- + +{{APIRef("Navigation API")}}{{seecompattable}} + +The **`from`** read-only property of the +{{domxref("NavigationTransition")}} interface returns the {{domxref("NavigationHistoryEntry")}} that the transition is coming from. + +## Value + +A {{domxref("NavigationHistoryEntry")}} object. + +## Examples + +```js +console.log(navigation.transition.from); +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- [Modern client-side routing: the Navigation API](https://developer.chrome.com/docs/web-platform/navigation-api/) +- [Navigation API explainer](https://github.com/WICG/navigation-api/blob/main/README.md) +- Domenic Denicola's [Navigation API live demo](https://gigantic-honored-octagon.glitch.me/) diff --git a/files/en-us/web/api/navigationtransition/index.md b/files/en-us/web/api/navigationtransition/index.md new file mode 100644 index 000000000000000..fadea7e483b4f74 --- /dev/null +++ b/files/en-us/web/api/navigationtransition/index.md @@ -0,0 +1,59 @@ +--- +title: NavigationTransition +slug: Web/API/NavigationTransition +page-type: web-api-interface +tags: + - API + - Experimental + - History + - Interface + - Landing + - Navigate + - NavigationTransition + - Navigation API + - Reference + - Scroll + - Traversal +browser-compat: api.NavigationTransition +--- + +{{APIRef("Navigation API")}}{{seecompattable}} + +The **`NavigationTransition`** interface of the {{domxref("Navigation API", "Navigation API", "", "nocode")}} represents an ongoing navigation, that is, a navigation that hasn't yet reached the {{domxref("Navigation/navigatesuccess_event", "navigatesuccess")}} or {{domxref("Navigation/navigateerror_event", "navigateerror")}} stage. + +It is accessed via the {{domxref("Navigation.transition")}} property. + +{{InheritanceDiagram}} + +## Instance properties + +- {{domxref("NavigationTransition.finished", "finished")}} {{ReadOnlyInline}} + - : Returns a {{jsxref("Promise")}} that fulfills at the same time the {{domxref("Navigation/navigatesuccess_event", "navigatesuccess")}} event fires, or rejects at the same time the {{domxref("Navigation/navigateerror_event", "navigateerror")}} event fires. +- {{domxref("NavigationTransition.from", "from")}} {{ReadOnlyInline}} + - : Returns the {{domxref("NavigationHistoryEntry")}} that the transition is coming from. +- {{domxref("NavigationTransition.navigationType", "navigationType")}} {{ReadOnlyInline}} + - : Returns the type of the ongoing navigation. + +## Examples + +```js +async function cleanupNavigation() { + await navigation.transition.finished; + // Navigation has completed successfully + // Cleanup any ongoing monitoring +} +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- [Modern client-side routing: the Navigation API](https://developer.chrome.com/docs/web-platform/navigation-api/) +- [Navigation API explainer](https://github.com/WICG/navigation-api/blob/main/README.md) +- Domenic Denicola's [Navigation API live demo](https://gigantic-honored-octagon.glitch.me/) diff --git a/files/en-us/web/api/navigationtransition/navigationtype/index.md b/files/en-us/web/api/navigationtransition/navigationtype/index.md new file mode 100644 index 000000000000000..c9257240dcb4463 --- /dev/null +++ b/files/en-us/web/api/navigationtransition/navigationtype/index.md @@ -0,0 +1,55 @@ +--- +title: NavigationTransition.navigationType +slug: Web/API/NavigationTransition/navigationType +page-type: web-api-instance-property +tags: + - API + - Experimental + - History + - Navigate + - Navigation + - Navigation API + - navigationType + - Property + - Read-only + - Reference + - Scroll + - Traversal +browser-compat: api.NavigationTransition.navigationType +--- + +{{APIRef("Navigation API")}}{{seecompattable}} + +The **`navigationType`** read-only property of the +{{domxref("NavigationTransition")}} interface returns the type of the ongoing navigation. + +## Value + +An enumerated value representing the type of ongoing navigation. + +The possible values are: + +- `push`: A new location is navigated to, causing a new entry to be pushed onto the history list. +- `reload`: The {{domxref("Navigation.currentEntry")}} is reloaded. +- `replace`: The {{domxref("Navigation.currentEntry")}} is replaced with a new history entry. This new entry will reuse the same {{domxref("NavigationHistoryEntry.key", "key")}}, but be assigned a different {{domxref("NavigationHistoryEntry.id", "id")}}. +- `traverse`: The browser navigates from one existing history entry to another existing history entry. + +## Examples + +```js +console.log(navigation.transition.navigationType); +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- [Modern client-side routing: the Navigation API](https://developer.chrome.com/docs/web-platform/navigation-api/) +- [Navigation API explainer](https://github.com/WICG/navigation-api/blob/main/README.md) +- Domenic Denicola's [Navigation API live demo](https://gigantic-honored-octagon.glitch.me/) diff --git a/files/en-us/web/api/window/index.md b/files/en-us/web/api/window/index.md index 675572a8b7e1421..f470a4cebdc6fbc 100644 --- a/files/en-us/web/api/window/index.md +++ b/files/en-us/web/api/window/index.md @@ -41,7 +41,7 @@ See also the [DOM Interfaces](/en-US/docs/Web/API/Document_Object_Model). - {{domxref("HTMLOptionElement.Option")}} - : Used for creating an {{domxref("HTMLOptionElement")}}. - {{domxref("StaticRange")}} {{Experimental_Inline}} {{ReadOnlyInline}} - - : Returns a {{domxref('StaticRange.StaticRange','StaticRange()')}} constructor which creates a {{domxref('StaticRange')}} object. + - : Returns a {{domxref("StaticRange.StaticRange","StaticRange()")}} constructor which creates a {{domxref("StaticRange")}} object. - {{domxref("Worker")}} - : Used for creating a [Web worker](/en-US/docs/Web/API/Web_Workers_API/Using_web_workers). - {{domxref("XMLSerializer")}} @@ -103,6 +103,8 @@ Note that properties which are objects (e.g., for overriding the prototype of bu - : Returns the vertical (Y) coordinate of the top-left corner of the window's viewport, in screen coordinates. This value is reported in CSS pixels. See `mozScreenPixelsPerCSSPixel` for a conversion factor to adapt to screen pixels if needed. - {{domxref("Window.name")}} - : Gets/sets the name of the window. +- {{domxref("Window.navigation")}} {{ReadOnlyInline}} {{Experimental_Inline}} + - : Returns the current `window`'s associated {{domxref("Navigation")}} object. The entry point for the {{domxref("Navigation API")}}. - {{domxref("Window.navigator")}} {{ReadOnlyInline}} - : Returns a reference to the navigator object. - {{domxref("Window.opener")}} diff --git a/files/en-us/web/api/window/navigation/index.md b/files/en-us/web/api/window/navigation/index.md new file mode 100644 index 000000000000000..fc5d2ffc37d011b --- /dev/null +++ b/files/en-us/web/api/window/navigation/index.md @@ -0,0 +1,45 @@ +--- +title: Window.navigation +slug: Web/API/Window/navigation +page-type: web-api-instance-property +tags: + - API + - Experimental + - Navigate + - Navigation + - Navigation API + - Property + - Reference + - Window +browser-compat: api.Window.navigation +--- + +{{APIRef}}{{seecompattable}} + +The `navigation` read-only property of the {{domxref("Window")}} interface returns the current `window`'s associated {{domxref("Navigation")}} object. + +The entry point for the {{domxref("Navigation API")}}. + +## Value + +A {{domxref("Navigation")}} object instance. + +## Examples + +```js +let currentNavEntries = window.navigation.entries(); +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- [Modern client-side routing: the Navigation API](https://developer.chrome.com/docs/web-platform/navigation-api/) +- [Navigation API explainer](https://github.com/WICG/navigation-api/blob/main/README.md) +- Domenic Denicola's [Navigation API live demo](https://gigantic-honored-octagon.glitch.me/) diff --git a/files/jsondata/GroupData.json b/files/jsondata/GroupData.json index 3434b57bdecce14..37f41a7cbe29f63 100644 --- a/files/jsondata/GroupData.json +++ b/files/jsondata/GroupData.json @@ -844,6 +844,21 @@ "properties": [], "events": [] }, + "Navigation API": { + "overview": ["Navigation API"], + "guides": [], + "interfaces": [ + "NavigateEvent", + "Navigation", + "NavigationCurrentEntryChangeEvent", + "NavigationDestination", + "NavigationHistoryEntry", + "NavigationTransition" + ], + "methods": [], + "properties": ["Window.navigation"], + "events": [] + }, "Network Information API": { "overview": ["Network Information API"], "interfaces": ["NetworkInformation"],