Chat with us, powered by LiveChat
← Return to MyDisct Solver

BrowserAPI Navigation Methods

The BrowserAPI class exposes five navigation methods through the session.browser interface that give you full control over page navigation within an adaptive mode BBRE session. The navigate(url, options) method loads a new URL in the browser with configurable wait conditions and timeout values, making it the primary way to move between pages. The goto(url, options) method is a convenience alias for navigate() that provides identical functionality with a shorter name for developers who prefer that syntax. The reload(options) method refreshes the current page with the same wait condition and timeout options available in navigate(), which is useful for retrying failed page loads or refreshing dynamic content. The back() method navigates to the previous page in the browser history stack, simulating a user clicking the browser back button. The forward() method navigates to the next page in the browser history stack, simulating a user clicking the browser forward button. All five navigation methods require an active adaptive mode session because they operate on a real browser instance managed by the BBRE engine. This page provides complete documentation for every navigation method, including method signatures, parameter tables, wait condition explanations, practical code examples covering multi-page crawling, SPA navigation, redirect handling, and navigation with custom wait conditions, along with best practices, common issues, and links to related documentation.

Adaptive Mode Required

All BrowserAPI navigation methods require an active session running in adaptive mode. Adaptive mode sessions launch a real browser instance managed by the BBRE engine, which is necessary for navigation, DOM interaction, and page state management. If you attempt to call navigation methods on a passive mode session, the operation will fail with a BROWSER_ACTION_FAILED error. Create your session with mode: "adaptive" to use these methods.

session.browser.goto(url, options)

The goto() method is a convenience alias for navigate(). It accepts exactly the same parameters, produces exactly the same behavior, and returns exactly the same result. Internally, goto() simply calls navigate() with the provided arguments and returns its result. The method exists to provide a familiar API for developers who are accustomed to browser automation libraries like Puppeteer and Playwright, where goto() is the standard method name for URL navigation. You can use goto() and navigate() interchangeably throughout your code. There is no performance difference, no behavioral difference, and no reason to prefer one over the other beyond personal or team coding style preferences.

Method Signature

JavaScript
const result = await session.browser.goto(url, options);

Parameters

The goto() method accepts the same parameters as navigate(). Refer to the navigate() parameter table above for complete details on each parameter.

Parameter Type Required Description
url string Required The full URL to navigate to. Must include the protocol. Identical to the url parameter in navigate().
options object Optional Configuration object with waitUntil and timeout properties. Identical to the options parameter in navigate().
options.waitUntil string Optional Page readiness condition. Accepted values: "load", "domcontentloaded", "networkidle". Defaults to "load".
options.timeout number Optional Maximum seconds to wait for the page to reach the readiness state. Defaults to 30.

Basic Usage

Use goto() exactly as you would use navigate(). The following example demonstrates basic URL loading with goto().

JavaScript
const BBREClient = require("mydisctsolver-bbre");

const client = new BBREClient({ apiKey: "YOUR_API_KEY" });

async function gotoExample() {
  const session = client.createSession({ mode: "adaptive" });
  await session.start();

  await session.browser.goto("https://example.com");

  const title = await session.browser.getTitle();
  console.log("Page title:", title);

  await session.close();
}

gotoExample();

goto() with Options

Just like navigate(), you can pass waitUntil and timeout options to goto() to control the navigation behavior.

JavaScript
const BBREClient = require("mydisctsolver-bbre");

const client = new BBREClient({ apiKey: "YOUR_API_KEY" });

async function gotoWithOptions() {
  const session = client.createSession({ mode: "adaptive" });
  await session.start();

  await session.browser.goto("https://dashboard.example.com", {
    waitUntil: "networkidle",
    timeout: 45
  });

  const url = await session.browser.getUrl();
  console.log("Current URL:", url);

  await session.close();
}

gotoWithOptions();

Interchangeable Usage with navigate()

The following example demonstrates that goto() and navigate() can be used interchangeably within the same workflow. Both methods produce identical results and maintain the same browser state.

JavaScript
const BBREClient = require("mydisctsolver-bbre");

const client = new BBREClient({ apiKey: "YOUR_API_KEY" });

async function mixedNavigation() {
  const session = client.createSession({ mode: "adaptive" });
  await session.start();

  await session.browser.navigate("https://example.com/login");
  console.log("Navigated to login page using navigate()");

  await session.browser.fill("#username", "testuser");
  await session.browser.fill("#password", "testpass");
  await session.browser.click("#login-button");

  await session.browser.goto("https://example.com/dashboard", {
    waitUntil: "networkidle"
  });
  console.log("Navigated to dashboard using goto()");

  await session.browser.navigate("https://example.com/settings");
  console.log("Navigated to settings using navigate()");

  await session.close();
}

mixedNavigation();

session.browser.reload(options)

The reload() method refreshes the current page in the browser. It sends a reload action to the BBRE engine, which triggers a full page reload of the currently loaded URL. Like navigate(), the method accepts an optional options object with waitUntil and timeout parameters that control when the reload is considered complete and how long to wait before timing out. The reload() method does not accept a URL parameter because it always reloads the current page. This method is particularly useful in several scenarios: retrying a page load that returned incomplete or stale content, refreshing a page after submitting a form to see updated data, reloading a page that uses server-side rendering to get the latest version, and recovering from transient page load errors where the initial navigation succeeded but the content was not fully rendered. The browser maintains its current state (cookies, local storage, session data) across reloads, so any authentication tokens or session cookies set during previous navigations remain intact.

Method Signature

JavaScript
const result = await session.browser.reload(options);

Parameters

The reload() method accepts an optional options object that controls the wait condition and timeout for the page reload. If no options are provided, the method uses the default values of "load" for waitUntil and 30 seconds for timeout.

Parameter Type Required Description
options object Optional Configuration object for the reload behavior. Contains waitUntil and timeout properties.
options.waitUntil string Optional The page readiness condition to wait for after the reload. Accepted values: "load", "domcontentloaded", "networkidle". Defaults to "load".
options.timeout number Optional Maximum number of seconds to wait for the page to finish reloading. Defaults to 30.

Basic Reload

The simplest usage of reload() refreshes the current page with default options. The browser waits for the load event with a 30-second timeout.

JavaScript
const BBREClient = require("mydisctsolver-bbre");

const client = new BBREClient({ apiKey: "YOUR_API_KEY" });

async function basicReload() {
  const session = client.createSession({ mode: "adaptive" });
  await session.start();

  await session.browser.navigate("https://example.com/dashboard");
  console.log("Initial page loaded");

  await session.browser.reload();
  console.log("Page reloaded successfully");

  const title = await session.browser.getTitle();
  console.log("Page title after reload:", title);

  await session.close();
}

basicReload();

Reload After Form Submission

After submitting a form that modifies server-side data, you may need to reload the page to see the updated content. This pattern is common in admin panels, content management systems, and any application where form submissions trigger server-side changes that are reflected on the same page.

JavaScript
const BBREClient = require("mydisctsolver-bbre");

const client = new BBREClient({ apiKey: "YOUR_API_KEY" });

async function reloadAfterFormSubmission() {
  const session = client.createSession({ mode: "adaptive" });
  await session.start();

  await session.browser.navigate("https://admin.example.com/settings");

  await session.browser.fill("#company-name", "Acme Corporation");
  await session.browser.fill("#contact-email", "[email protected]");
  await session.browser.click("#save-settings");

  await session.browser.wait(2);

  await session.browser.reload({ waitUntil: "networkidle" });
  console.log("Page reloaded with updated settings");

  const companyName = await session.browser.getText("#company-name-display");
  console.log("Updated company name:", companyName);

  await session.close();
}

reloadAfterFormSubmission();

Reload with Retry Logic

When a page load returns incomplete content or encounters a transient error, you can use reload() as part of a retry strategy. The following example reloads the page up to a specified number of times until the expected content appears.

JavaScript
const BBREClient = require("mydisctsolver-bbre");

const client = new BBREClient({ apiKey: "YOUR_API_KEY" });

async function reloadUntilContentReady(session, expectedSelector, maxRetries) {
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      const elements = await session.browser.find(expectedSelector);

      if (elements && elements.length > 0) {
        console.log("Content found on attempt", attempt);
        return true;
      }
    } catch (error) {
      console.log("Attempt", attempt, "- content not found yet");
    }

    if (attempt < maxRetries) {
      console.log("Reloading page, attempt", attempt + 1);
      await session.browser.reload({ waitUntil: "networkidle", timeout: 20 });
    }
  }

  console.log("Content not found after", maxRetries, "attempts");
  return false;
}

async function main() {
  const session = client.createSession({ mode: "adaptive" });
  await session.start();

  await session.browser.navigate("https://example.com/reports");

  const found = await reloadUntilContentReady(session, ".report-table tbody tr", 3);

  if (found) {
    const text = await session.browser.getText(".report-table");
    console.log("Report data:", text);
  }

  await session.close();
}

main();

Reload for Dynamic Content Refresh

Some web applications display real-time data that changes frequently, such as stock prices, order statuses, or live dashboards. Use reload() to periodically refresh the page and capture the latest data.

JavaScript
const BBREClient = require("mydisctsolver-bbre");

const client = new BBREClient({ apiKey: "YOUR_API_KEY" });

async function monitorDynamicContent() {
  const session = client.createSession({ mode: "adaptive" });
  await session.start();

  await session.browser.navigate("https://trading.example.com/portfolio", {
    waitUntil: "networkidle"
  });

  const snapshots = [];

  for (let i = 0; i < 5; i++) {
    const portfolioValue = await session.browser.getText("#total-value");
    const timestamp = new Date().toISOString();
    snapshots.push({ timestamp, value: portfolioValue });
    console.log("[" + timestamp + "] Portfolio value:", portfolioValue);

    if (i < 4) {
      await session.browser.wait(10);
      await session.browser.reload({ waitUntil: "networkidle" });
    }
  }

  console.log("Collected", snapshots.length, "snapshots");

  await session.close();
  return snapshots;
}

monitorDynamicContent();

session.browser.back()

The back() method navigates to the previous page in the browser's history stack. It simulates a user clicking the browser's back button, moving one step backward in the navigation history. This method does not accept any parameters. The browser loads the previous URL from its history and restores the page state as it was when the user last visited that page. The back() method is useful in automation workflows where you need to return to a previous page after inspecting or interacting with a detail page. For example, when crawling a list of items, you might navigate to each item's detail page, extract data, and then call back() to return to the list page before clicking the next item. The method relies on the browser's internal history stack, so it only works if there is a previous page to go back to. If the browser history is empty (for example, if the current page is the first page loaded in the session), calling back() will have no effect or may produce unexpected behavior. Always ensure that your navigation flow has established a history before calling this method.

Method Signature

JavaScript
const result = await session.browser.back();

Parameters

The back() method does not accept any parameters. It navigates to the previous page in the browser history stack using the browser's built-in back navigation mechanism.

Parameter Type Required Description
This method does not accept any parameters.

Basic Back Navigation

The simplest usage of back() navigates from a detail page back to the previous page. After calling back(), the browser loads the previous URL from its history stack.

JavaScript
const BBREClient = require("mydisctsolver-bbre");

const client = new BBREClient({ apiKey: "YOUR_API_KEY" });

async function basicBackNavigation() {
  const session = client.createSession({ mode: "adaptive" });
  await session.start();

  await session.browser.navigate("https://example.com/products");
  console.log("On products page");

  await session.browser.navigate("https://example.com/products/laptop-pro");
  console.log("On product detail page");

  await session.browser.back();
  console.log("Back on products page");

  const url = await session.browser.getUrl();
  console.log("Current URL:", url);

  await session.close();
}

basicBackNavigation();

List-Detail Crawling Pattern

One of the most common use cases for back() is the list-detail crawling pattern. In this pattern, you start on a list page, click on each item to visit its detail page, extract the data you need, and then call back() to return to the list page before clicking the next item. This approach preserves the list page state (scroll position, loaded items, pagination) and avoids re-navigating to the list URL, which would reset any dynamic state.

JavaScript
const BBREClient = require("mydisctsolver-bbre");

const client = new BBREClient({ apiKey: "YOUR_API_KEY" });

async function listDetailCrawl() {
  const session = client.createSession({ mode: "adaptive" });
  await session.start();

  await session.browser.navigate("https://blog.example.com/articles", {
    waitUntil: "networkidle"
  });

  const articleLinks = await session.browser.find("a.article-link");
  const articleCount = articleLinks.length;
  console.log("Found", articleCount, "articles");

  const articles = [];

  for (let i = 0; i < articleCount; i++) {
    await session.browser.click("a.article-link:nth-child(" + (i + 1) + ")");
    await session.browser.waitForSelector(".article-content");

    const title = await session.browser.getText("h1.article-title");
    const author = await session.browser.getText(".article-author");
    const content = await session.browser.getText(".article-content");

    articles.push({ title, author, contentLength: content.length });
    console.log("Extracted article:", title);

    await session.browser.back();
    await session.browser.waitForSelector("a.article-link");
  }

  console.log("Extracted", articles.length, "articles");

  await session.close();
  return articles;
}

listDetailCrawl();

Multi-Step Workflow with Back Navigation

In complex workflows that involve navigating through multiple pages, you can use back() to retrace your steps. This is useful when you need to explore different branches of a website from a common starting point.

JavaScript
const BBREClient = require("mydisctsolver-bbre");

const client = new BBREClient({ apiKey: "YOUR_API_KEY" });

async function multiStepWorkflow() {
  const session = client.createSession({ mode: "adaptive" });
  await session.start();

  await session.browser.navigate("https://store.example.com");
  console.log("On homepage");

  await session.browser.navigate("https://store.example.com/electronics");
  const electronicsTitle = await session.browser.getTitle();
  console.log("Electronics page:", electronicsTitle);

  await session.browser.back();
  console.log("Back on homepage");

  await session.browser.navigate("https://store.example.com/clothing");
  const clothingTitle = await session.browser.getTitle();
  console.log("Clothing page:", clothingTitle);

  await session.browser.back();
  console.log("Back on homepage again");

  await session.browser.navigate("https://store.example.com/books");
  const booksTitle = await session.browser.getTitle();
  console.log("Books page:", booksTitle);

  await session.close();
}

multiStepWorkflow();

session.browser.forward()

The forward() method navigates to the next page in the browser's history stack. It simulates a user clicking the browser's forward button, moving one step forward in the navigation history. This method does not accept any parameters. The forward() method is the counterpart to back() and is only effective when the browser has a forward history entry, which exists after calling back(). If you navigate to page A, then to page B, then call back() to return to page A, calling forward() will take you back to page B. If there is no forward history (for example, if you have not called back() or if you navigated to a new URL after calling back()), calling forward() will have no effect. This method is useful in testing scenarios where you need to verify that forward navigation works correctly, in workflows where you need to revisit a page you previously backed away from, and in complex navigation patterns where you alternate between forward and backward movement through a sequence of pages.

Method Signature

JavaScript
const result = await session.browser.forward();

Parameters

The forward() method does not accept any parameters. It navigates to the next page in the browser history stack using the browser's built-in forward navigation mechanism.

Parameter Type Required Description
This method does not accept any parameters.

Basic Forward Navigation

The simplest usage of forward() moves forward in the browser history after a back() call. The browser loads the next URL from its forward history stack.

JavaScript
const BBREClient = require("mydisctsolver-bbre");

const client = new BBREClient({ apiKey: "YOUR_API_KEY" });

async function basicForwardNavigation() {
  const session = client.createSession({ mode: "adaptive" });
  await session.start();

  await session.browser.navigate("https://example.com/page-one");
  console.log("On page one");

  await session.browser.navigate("https://example.com/page-two");
  console.log("On page two");

  await session.browser.back();
  console.log("Back on page one");

  await session.browser.forward();
  console.log("Forward to page two again");

  const url = await session.browser.getUrl();
  console.log("Current URL:", url);

  await session.close();
}

basicForwardNavigation();

Back and Forward Navigation Pattern

Combining back() and forward() allows you to move freely through the browser history. This pattern is useful for testing navigation flows, verifying page state persistence across history navigation, and building workflows that need to revisit previously viewed pages without re-fetching them from the server.

JavaScript
const BBREClient = require("mydisctsolver-bbre");

const client = new BBREClient({ apiKey: "YOUR_API_KEY" });

async function backAndForwardPattern() {
  const session = client.createSession({ mode: "adaptive" });
  await session.start();

  await session.browser.navigate("https://docs.example.com/introduction");
  const introTitle = await session.browser.getTitle();
  console.log("Step 1:", introTitle);

  await session.browser.navigate("https://docs.example.com/getting-started");
  const gettingStartedTitle = await session.browser.getTitle();
  console.log("Step 2:", gettingStartedTitle);

  await session.browser.navigate("https://docs.example.com/api-reference");
  const apiRefTitle = await session.browser.getTitle();
  console.log("Step 3:", apiRefTitle);

  await session.browser.back();
  const afterBack1 = await session.browser.getTitle();
  console.log("After back():", afterBack1);

  await session.browser.back();
  const afterBack2 = await session.browser.getTitle();
  console.log("After second back():", afterBack2);

  await session.browser.forward();
  const afterForward1 = await session.browser.getTitle();
  console.log("After forward():", afterForward1);

  await session.browser.forward();
  const afterForward2 = await session.browser.getTitle();
  console.log("After second forward():", afterForward2);

  await session.close();
}

backAndForwardPattern();

History Navigation for Page Comparison

Use back() and forward() to compare content between two pages without re-navigating to their URLs. This is useful for verifying that form submissions changed the page content, comparing before and after states, or validating that navigation does not lose page data.

JavaScript
const BBREClient = require("mydisctsolver-bbre");

const client = new BBREClient({ apiKey: "YOUR_API_KEY" });

async function comparePages() {
  const session = client.createSession({ mode: "adaptive" });
  await session.start();

  await session.browser.navigate("https://example.com/pricing/basic");
  const basicPrice = await session.browser.getText(".price-value");
  const basicFeatures = await session.browser.getText(".features-list");
  console.log("Basic plan price:", basicPrice);

  await session.browser.navigate("https://example.com/pricing/premium");
  const premiumPrice = await session.browser.getText(".price-value");
  const premiumFeatures = await session.browser.getText(".features-list");
  console.log("Premium plan price:", premiumPrice);

  await session.browser.back();
  const backToBasicPrice = await session.browser.getText(".price-value");
  console.log("Back to basic, price:", backToBasicPrice);

  await session.browser.forward();
  const forwardToPremiumPrice = await session.browser.getText(".price-value");
  console.log("Forward to premium, price:", forwardToPremiumPrice);

  console.log("Comparison complete");
  console.log("Basic:", basicPrice, "| Premium:", premiumPrice);

  await session.close();
}

comparePages();

Error Handling

Navigation methods can fail for various reasons, including network errors, timeout expiration, invalid URLs, and session state issues. Understanding the different error scenarios and implementing appropriate error handling is essential for building reliable automation workflows. The following examples demonstrate how to handle navigation errors gracefully.

Error Types

The following table lists the common errors that can occur during navigation operations, along with their causes and recommended solutions.

Error Cause Solution
BROWSER_ACTION_FAILED The navigation action could not be executed by the browser engine. This can happen when the session is not in adaptive mode, the browser instance has crashed, or the session has expired. Verify that your session is created with mode: "adaptive". Check the session status with session.status() to ensure it is still active.
Navigation timeout The page did not reach the specified waitUntil condition within the timeout period. This commonly occurs with slow servers, heavy pages, or when using "networkidle" on pages with persistent network connections. Increase the timeout value, use a less strict waitUntil condition (e.g., "domcontentloaded" instead of "networkidle"), or check if the target server is responding.
Invalid URL The provided URL is malformed, missing the protocol, or points to an unreachable address. Ensure the URL includes the protocol (https:// or http://) and is a valid, reachable address. Validate URLs before passing them to navigate().
Session expired The BBRE session has expired due to inactivity or reaching its maximum lifetime. Navigation methods cannot operate on expired sessions. Check the session status before navigating. If the session has expired, create a new session and restart your workflow.
Session closed The session was explicitly closed with session.close() before the navigation method was called. Ensure you do not call navigation methods after closing the session. Structure your code so that session.close() is always the last operation.

Robust Navigation with Error Recovery

The following example demonstrates a robust navigation function that handles different error types and implements retry logic for transient failures.

JavaScript
const BBREClient = require("mydisctsolver-bbre");

const client = new BBREClient({ apiKey: "YOUR_API_KEY" });

async function robustNavigate(session, url, options, maxRetries) {
  let lastError;

  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      await session.browser.navigate(url, options);
      const finalUrl = await session.browser.getUrl();
      console.log("Navigation successful on attempt", attempt);
      console.log("Final URL:", finalUrl);
      return { success: true, url: finalUrl, attempts: attempt };
    } catch (error) {
      lastError = error;
      console.log("Attempt", attempt, "failed:", error.message);

      const message = error.message.toLowerCase();

      if (message.includes("session") && (message.includes("expired") || message.includes("closed"))) {
        console.log("Session is no longer active, cannot retry");
        return { success: false, error: error.message, recoverable: false };
      }

      if (attempt < maxRetries) {
        const delay = 2000 * attempt;
        console.log("Retrying in", delay, "ms");
        await new Promise(resolve => setTimeout(resolve, delay));
      }
    }
  }

  return { success: false, error: lastError.message, attempts: maxRetries, recoverable: true };
}

async function main() {
  const session = client.createSession({ mode: "adaptive" });
  await session.start();

  const result = await robustNavigate(
    session,
    "https://example.com/data",
    { waitUntil: "networkidle", timeout: 30 },
    3
  );

  if (result.success) {
    const title = await session.browser.getTitle();
    console.log("Page title:", title);
  } else {
    console.log("Navigation failed after all retries:", result.error);
  }

  await session.close();
}

main();

Best Practices

Choose the Right waitUntil Value for Your Use Case

The waitUntil parameter has a significant impact on both reliability and performance. Use "load" (the default) for standard web pages where you need all resources including images and stylesheets to be available. Use "domcontentloaded" when you only need to interact with the DOM structure and do not depend on images or external resources, as this is faster than waiting for the full load event. Use "networkidle" for single-page applications and pages that load content dynamically via JavaScript API calls, since this ensures all asynchronous data fetching has completed. Avoid using "networkidle" on pages with persistent WebSocket connections or long-polling requests, as the network may never become truly idle on those pages.

Set Appropriate Timeout Values Based on Target Page Characteristics

The default timeout of 30 seconds works well for most pages, but you should adjust it based on the characteristics of the pages you are navigating to. For fast, lightweight pages (API documentation, static sites), reduce the timeout to 10 or 15 seconds to fail fast when something goes wrong. For heavy pages that perform server-side processing (report generators, data dashboards), increase the timeout to 45 or 60 seconds to accommodate longer load times. For pages behind slow networks or geographic proxies, consider even higher timeouts. Always set the timeout to the minimum value that reliably works for your target pages to avoid wasting session time on unresponsive servers.

Combine navigate() with Explicit Wait Methods for Maximum Reliability

For pages that load content progressively or render data asynchronously after the initial page load, use a two-step approach: first call navigate() with "domcontentloaded" or "load" to get the page structure loaded, then use waitForSelector() or waitForText() to wait for the specific content you need before proceeding. This approach is more reliable than relying solely on "networkidle" because it targets the exact content your automation depends on, rather than waiting for all network activity to cease. It also handles edge cases where the page makes background requests that are unrelated to the content you need.

Verify the Final URL After Navigation to Detect Redirects

After calling navigate(), always use getUrl() to check the final URL if your workflow depends on being on a specific page. Websites frequently redirect users based on authentication status, geographic location, A/B testing groups, or URL normalization rules. By verifying the final URL, you can detect login redirects early and handle them appropriately, identify geographic redirects that may serve different content, and catch unexpected redirects that could break your automation flow. This is especially important for workflows that navigate to protected pages that require authentication.

Use back() Instead of Re-navigating to Preserve Page State

When you need to return to a previous page in a list-detail crawling pattern, use back() instead of calling navigate() with the list page URL. The back() method restores the page from the browser's history cache, which preserves the scroll position, loaded dynamic content, and any client-side state that was present when you left the page. Re-navigating to the URL would trigger a fresh page load, resetting all dynamic state and potentially losing pagination position, filter selections, or lazy-loaded content. However, be aware that some websites may re-fetch data when navigating back, so test this behavior with your specific target site.

Always Wrap Navigation Calls in Error Handling

Navigation is one of the most failure-prone operations in browser automation because it depends on external factors like network connectivity, server availability, DNS resolution, and page complexity. Always wrap navigate(), goto(), reload(), back(), and forward() calls in try-catch blocks. For critical navigation steps, implement retry logic with increasing delays between attempts. For non-critical navigation (such as crawling optional pages), log the error and continue with the next page rather than crashing the entire workflow. This defensive approach ensures your automation is resilient to transient failures.

Use High Sensibility for Navigation on Protected Websites

When navigating to websites with advanced bot detection systems, create your session with sensibility: "high" to enable the most thorough anti-detection measures. High sensibility mode adds realistic delays between actions, randomizes navigation timing, and applies additional fingerprint protections that make the browser behavior appear more human-like. While high sensibility is slower than low or medium, it significantly reduces the chance of being detected and blocked during navigation. For websites without aggressive bot detection, sensibility: "medium" or "low" provides faster navigation with adequate protection.

Common Issues

Navigation Timeout with networkidle on Pages with Persistent Connections

Symptom: Calling navigate() with waitUntil: "networkidle" times out even though the page appears to be fully loaded.
Cause: The page maintains persistent network connections such as WebSocket connections, long-polling requests, server-sent events, or periodic heartbeat requests. The "networkidle" condition requires zero active network connections for 500 milliseconds, which never occurs on pages with persistent connections.
Solution: Switch to waitUntil: "load" or "domcontentloaded" and then use waitForSelector() to wait for the specific content you need. For example: await session.browser.navigate(url, { waitUntil: "load" }); followed by await session.browser.waitForSelector(".main-content");

BROWSER_ACTION_FAILED When Using Navigation on Passive Mode Sessions

Symptom: Calling any navigation method throws a BROWSER_ACTION_FAILED error.
Cause: The session was created with mode: "passive" instead of mode: "adaptive". Passive mode sessions do not launch a browser instance and therefore cannot execute browser navigation actions. All BrowserAPI methods, including navigate(), goto(), reload(), back(), and forward(), require an adaptive mode session.
Solution: Create your session with mode: "adaptive": const session = client.createSession({ mode: "adaptive" });. If you only need to make HTTP requests without browser interaction, use the passive mode session's request() method instead of browser navigation.

back() Has No Effect When Called on the First Page

Symptom: Calling back() does not change the current URL, and the browser remains on the same page.
Cause: The browser history stack is empty because the current page is the first page loaded in the session. There is no previous page to navigate back to. The back() method relies on the browser's internal history, which only contains entries for pages that were navigated to within the current session.
Solution: Ensure that you have navigated to at least two pages before calling back(). Track your navigation history in your application code if you need to verify that back navigation is possible before calling the method. Alternatively, use navigate() with the desired URL instead of relying on back() when the history state is uncertain.

forward() Does Not Work After Navigating to a New URL

Symptom: After calling back() and then navigating to a new URL with navigate(), calling forward() does not return to the page you were on before calling back().
Cause: This is standard browser behavior. When you navigate to a new URL after calling back(), the forward history is cleared. The browser replaces the forward history with the new navigation, so there is no longer a forward entry to navigate to. This is the same behavior you would experience in a regular browser.
Solution: If you need to return to a specific page after navigating away, store the URL in a variable and use navigate() to go back to it directly. Only use forward() when you have called back() and have not navigated to any new URLs since then.

Page Content Not Updated After reload()

Symptom: After calling reload(), the page content appears to be the same as before the reload, even though you expected it to change.
Cause: The page may be served from the browser cache rather than being fetched fresh from the server. Some websites set aggressive caching headers that cause the browser to serve cached content even after a reload. Additionally, if the page content is generated client-side by JavaScript, the reload may re-execute the same JavaScript with the same cached data.
Solution: Use waitUntil: "networkidle" with reload() to ensure the browser waits for all network requests to complete after the reload. If the content is still cached, try navigating away from the page and then navigating back to it, or clear the browser cookies with session.browser.clearCookies() before reloading if the cached content is tied to cookie-based sessions.

Navigation Fails with URL Missing Protocol

Symptom: Calling navigate("example.com") or navigate("www.example.com") fails or navigates to an unexpected location.
Cause: The URL is missing the protocol prefix (https:// or http://). Without the protocol, the browser may interpret the URL as a relative path or a search query rather than an absolute URL.
Solution: Always include the full protocol in your URLs: await session.browser.navigate("https://example.com");. If you are working with URLs from external sources, validate and normalize them before passing them to navigate(). A simple check like if (!url.startsWith("http")) url = "https://" + url; can prevent this issue.