Page navigation can be either initiated by the Playwright call:
```js
// Load a page
await page.goto('https://example.com')
// Reload a page
await page.reload()
// Click a link
await page.click('text="Continue"')
```
or by the page itself:
```js
// Programmatic navigation
window.location.href = 'https://example.com'
// Single page app navigation
history.pushState({}, 'title', '#deep-link')
```
Navigation intent may result in being canceled, for example transformed into a download or hitting an unresolved DNS address. Only when the navigation succeeds, page starts **loading** the document.
Page load takes time retrieving the response body over the network, parsing, executing the scripts and firing the events. Typical load scenario goes through the following load states:
- [`page.url()`](api.md#pageurl) is set to the new url
- document content is loaded over network and parsed
- [`domcontentloaded`](api.md#event-domcontentloaded) event is fired
- page executes some scripts and loads resources like stylesheets and images
- [`load`](api.md#event-load) event is fired
- page executes dynamically loaded scripts
-`networkidle0` is fired - no new network requests made for at least `500` ms
By default, Playwright handles navigations seamlessly so that you did not need to think about them. Consider the following scenario, where everything is handled by Playwright behind the scenes:
When popup is opened, explicitly calling [`page.waitForLoadState()`](#pagewaitforloadstatestate-options) ensures that popup is loaded to the desired state.
Usually, the client-side redirect happens before the `load` event, and `page.goto()` method automatically waits for the redirect. However, when redirecting from a link click or after the `load` event, it would be easier to explicitly [`waitForNavigation()`](#pagewaitfornavigationoptions) to a specific url.
Notice the `Promise.all` to click and wait for navigation. Awaiting these methods one after the other is racy, because navigation could happen too fast.
When `onclick` handler triggers a navigation from a `setTimeout`, use an explicit [`waitForNavigation()`](#pagewaitfornavigationoptions) call as a last resort.
```js
await Promise.all([
page.waitForNavigation(), // Waits for the next navigation.
Notice the `Promise.all` to click and wait for navigation. Awaiting these methods one after the other is racy, because navigation could happen too fast.
// Ready to take a screenshot, according to the page itself.
await page.screenshot();
```
When clicking on a button triggers some asynchronous processing, issues a couple GET requests and pushes a new history state multiple times, explicit [`waitForNavigation()`](#pagewaitfornavigationoptions) to a specific url is the most reliable option.