JavaScript BOM

Why should you care about BOM?

BOM gives your JavaScript access to browser features like URL control, history, and local storage. It is essential when building real web app behavior beyond page content.

The BOM (Browser Object Model) refers to browser-provided APIs that let JavaScript interact with the browser environment beyond the page's DOM content. It gives you access to things like the URL, screen size, browser history, and storage.

The BOM is not part of the JavaScript language standard, but modern browsers provide these APIs consistently. Many commonly used browser APIs are exposed through properties and methods of the global window object.

Why does the BOM matter?

  • Redirect users or read the current URL with window.location.
  • Navigate browser history programmatically with window.history.
  • Read browser and device information with window.navigator.
  • Read display information with window.screen.
  • Store data in the browser with localStorage and sessionStorage.
  • Show dialogs, set timers, and control the viewport through the window object itself.

BOM hierarchy

Many commonly used browser APIs are exposed through properties and methods of the global window object:

  • window - represents the current browsing context and provides access to many browser APIs
    • window.history - the session navigation history
    • window.navigator - browser and device information
    • window.screen - information about the display
    • window.location - current URL and navigation
    • window.localStorage - persistent key-value storage
    • window.sessionStorage - tab-scoped key-value storage

How these APIs work together

A real browser feature usually combines several BOM tools. For example, a weather page can read a city from location.search, use navigator.onLine to decide whether to show an offline message, save the last city in localStorage, and use history.pushState() when the user selects a new city. The APIs are separate tools, but they work together around one user task.

javascript

const params = new URLSearchParams(location.search);
const city = params.get("city") || localStorage.getItem("lastCity") || "London";

if (!navigator.onLine) {
  console.log("You are offline. Showing the last saved city:", city);
}

localStorage.setItem("lastCity", city);
history.pushState({ city }, "", `?city=${encodeURIComponent(city)}`);

In a normal browser page, window is the global object for classic scripts, so you can omit it when calling many of its properties. Writing location.href is the same as writing window.location.href. In a classic script, a top-level var declaration becomes a window property, but top-level let and const declarations do not. ES modules have their own module scope.

javascript

// The window object is the global object for classic browser scripts
console.log(window); // shows all browser properties and methods

// A top-level var becomes a property of window
var appTitle = "TaskManager";
console.log(window.appTitle); // Output: TaskManager

In a browser, window represents the current browsing context and provides access to many browser APIs. It is the global object for classic scripts running in a normal browser page. Common properties and methods include innerWidth, innerHeight, alert(), confirm(), setTimeout(), and setInterval().

javascript

// Viewport size
console.log(window.innerWidth);  // e.g. 1440
console.log(window.innerHeight); // e.g. 900

// Open a popup
window.alert("Hello!");

// Run code after a delay (milliseconds)
window.setTimeout(function () {
  console.log("1 second later");
}, 1000);

// Run code repeatedly
const id = window.setInterval(function () {
  console.log("every 2 seconds");
}, 2000);

// Stop the interval
window.clearInterval(id);

window.history gives access to the browser's session history, which is the list of pages the user has visited in the current tab. You can navigate back and forward without a page reload.

javascript

// Go back one page (same as clicking the Back button)
history.back();

// Go forward one page
history.forward();

// Go a specific number of steps (-2 = two pages back)
history.go(-2);

// Total number of entries in the history stack
console.log(history.length);

Changing the URL without reloading: pushState adds a new entry to the history stack and changes the address bar. replaceState changes the current entry instead, so it does not add another Back-button step. Neither method downloads a new page by itself.

History methods used by browser navigation and single-page apps.
Method What changes Does it add a history entry?
history.back() or forward() Moves to an existing entry. No
history.pushState(data, "", url) Updates the URL and stores optional state data. Yes
history.replaceState(data, "", url) Updates the current URL and state data. No, it replaces the current entry
popstate event Lets code respond when the user moves through state entries with Back or Forward. It reacts to navigation; it does not create an entry

javascript

// Adds /products to the current page's history
history.pushState({ page: "products" }, "", "/products");

// Changes the current entry without adding another Back-button step
history.replaceState({ page: "products" }, "", "/products?sort=price");

// Back and Forward can trigger this event in a single-page app
window.addEventListener("popstate", (event) => {
  const page = event.state?.page || "home";
  console.log("Render the page for:", page);
});

SPA use case: a single-page app can show a different view, such as Home or Products, while keeping the same document loaded. Each link calls pushState; the popstate listener renders the view again when the user clicks the browser Back or Forward button.

javascript

const app = document.querySelector("#app");

function render(page) {
  app.textContent = page === "products" ? "Products view" : "Home view";
}

function navigate(page) {
  history.pushState({ page }, "", `/${page}`);
  render(page);
}

document.querySelector("#products-link").addEventListener("click", (event) => {
  event.preventDefault();
  navigate("products");
});

window.addEventListener("popstate", (event) => {
  render(event.state?.page || "home");
});

render(history.state?.page || "home");

In a real app, the link and #app element would be part of the HTML. The important pattern is: update the URL with pushState, render the selected view, and listen for popstate so browser navigation stays synchronized.

Important: state URLs must normally stay on the same origin, and changing the address with pushState does not make the server serve a new file. A deployed SPA also needs server fallback configuration so a direct visit to a route such as /products can load the app.

window.navigator contains information about the user's browser and device. It is commonly used to read the browser language, check whether the user is online, and detect supported features. Do not rely on userAgent alone to identify a browser; feature detection is usually more reliable.

javascript

// Browser and OS info
console.log(navigator.userAgent);
// e.g. "Mozilla/5.0 (Windows NT 10.0; Win64; x64) ..."

// User's preferred language
console.log(navigator.language); // e.g. "en-US"

// Check if online
console.log(navigator.onLine); // true or false

// Check for cookies being enabled
console.log(navigator.cookieEnabled); // true or false

window.screen provides information about the user's display, with dimensions reported in CSS pixels. This is different from the browser viewport size (window.innerWidth), and both values can change with display settings or device pixel ratio.

javascript

// Full screen resolution
console.log(screen.width);  // e.g. 1920
console.log(screen.height); // e.g. 1080

// Available area (excluding OS taskbar)
console.log(screen.availWidth);
console.log(screen.availHeight);

// Color depth in bits
console.log(screen.colorDepth); // e.g. 24

window.location holds the current page URL and lets you navigate to a new URL from JavaScript. Use URL or URLSearchParams when you need to read query parameters instead of manually splitting location.search.

javascript

// Full URL
console.log(location.href);
// e.g. "https://example.com/page?q=hello#section"

// Just the domain
console.log(location.hostname); // e.g. "example.com"

// Path after the domain
console.log(location.pathname); // e.g. "/page"

// Query string
console.log(location.search); // e.g. "?q=hello"

// Hash fragment
console.log(location.hash); // e.g. "#section"

// Navigate to a new page
location.href = "https://example.com";

// Reload the current page
location.reload();

Cookies are small pieces of data associated with a website. Depending on their domain, path, and other attributes, matching cookies can be sent with HTTP requests to the server. They are often used for sessions, authentication, and tracking. You read and write cookies through document.cookie.

javascript

// Set a cookie (expires in 7 days)
document.cookie = "username=admin; max-age=604800; path=/";

// Read all cookies (one string)
console.log(document.cookie);
// e.g. "username=admin; theme=dark"

// Delete a cookie by setting an expired date
document.cookie = "username=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/";

Cookies are small and typically limited to around 4 KB per cookie, depending on browser limits. For client-only storage, prefer localStorage or sessionStorage. Sensitive cookies should normally be configured by the server with attributes such as Secure, HttpOnly, and SameSite; JavaScript cannot create an HttpOnly cookie.

localStorage lets you store key-value pairs in the browser with no built-in expiry. Data usually stays after the tab or browser is closed, but users or browser policies can clear it. Storage is per origin, stores strings only, and its quota varies by browser.

javascript

// Save a value
localStorage.setItem("theme", "dark");

// Read a value
const theme = localStorage.getItem("theme");
console.log(theme); // Output: dark

// Remove one item
localStorage.removeItem("theme");

// Clear everything
localStorage.clear();

// Storing objects (must convert to JSON string)
const preferences = { theme: "dark", fontSize: 16 };
localStorage.setItem("preferences", JSON.stringify(preferences));

// Reading back an object
const stored = JSON.parse(localStorage.getItem("preferences"));
console.log(stored.theme); // Output: dark

sessionStorage works like localStorage, but data belongs to the current origin and browsing tab. It is normally cleared when that tab is closed, so it is useful for temporary data that should not persist between browser sessions.

javascript

// Save a value for the session
sessionStorage.setItem("step", "2");

// Read the value
console.log(sessionStorage.getItem("step")); // Output: 2

// Remove it
sessionStorage.removeItem("step");

                          // Data is normally cleared when the tab closes

Key difference: localStorage data persists until the user, browser, or application clears it, while sessionStorage data is normally cleared when the tab is closed.

Browser APIs are powerful because they can remember data, navigate users, and expose device information. Treat anything stored or received in the browser as potentially visible to the user and to scripts running in the page.

  • Never store passwords, private keys, or long-lived authentication tokens in localStorage or sessionStorage. XSS can read them.
  • Do not put secrets in URLs. Query strings can appear in browser history, logs, analytics, and the Referer header.
  • For session cookies, prefer server-set HttpOnly, Secure, and an appropriate SameSite value.
  • Do not trust navigator.userAgent, location, or storage values as proof of identity or authorization. Validate important decisions on the server.
  • Escape or safely render values read from storage, URLs, or cookies. Never insert untrusted values with innerHTML.

Rule of thumb: use storage for preferences and drafts, cookies for server-managed sessions, and server-side validation for anything security-sensitive.

  • The BOM lets JavaScript interact with the browser beyond the page content.
  • window is the global object for classic scripts in a browser page and provides access to many browser APIs.
  • history lets you navigate back and forward in the session history, add entries with pushState, replace the current entry with replaceState, and respond to Back or Forward with popstate.
  • navigator provides information about the browser and device.
  • screen gives display information, with dimensions reported in CSS pixels.
  • location holds the current URL and lets you navigate to another page.
  • Cookies are small browser-stored values that may be sent with matching HTTP requests.
  • localStorage stores data persistently for an origin until it is removed or cleared.
  • sessionStorage stores data only for the current tab session.
Build browser projects

Apply these APIs in small projects that have real browser state and user workflows:

Weather app Todo list Quiz app

Security reminder: storage and browser metadata are convenient, not trusted. Keep secrets out of client storage and validate authorization on the server.

Reviewed by

SimplyJavaScript Editorial Team

Technical editors and JavaScript educators with hands-on experience building frontend projects, writing learning material, and reviewing tutorials for clarity, accuracy, and beginner-friendly guidance.