Skip to content
Happy Programming Guide
Start learning
JavaScript

Client-Side Web APIs in JavaScript

The browser APIs your JavaScript can use directly — fetch, storage, geolocation, clipboard, observers — and how to use each without breaking the page when it is unavailable.

A black wireless router with two antennas on a wooden surface with visible status lights and a cable plugged

A browser gives your JavaScript a large set of built-in capabilities: fetching data, storing values, watching elements, reading the clipboard, asking for a location. These are the client-side web APIs.

They share a pattern worth learning once: check it exists, ask permission where needed, and handle refusal.

Fetch — getting data#

JavaScript
async function loadUsers() {
  const response = await fetch("/api/users");

  if (!response.ok) {
    throw new Error(`Request failed: ${response.status}`);
  }
  return response.json();
}

The single most important detail: fetch does not throw on a 404 or 500. It only rejects when the request could not be made at all. Check response.ok yourself — see the Fetch API guide.

Storage — remembering things#

JavaScript
localStorage.setItem("theme", "dark");
localStorage.getItem("theme");        // "dark", or null

sessionStorage.setItem("step", "3");  // cleared when the tab closes

Storage holds strings only, so objects go through JSON.stringify. It can also throw — in private browsing, or when the quota is full — so wrap writes:

JavaScript
function save(key, value) {
  try {
    localStorage.setItem(key, JSON.stringify(value));
  } catch {
    // Storage unavailable or full. Not fatal.
  }
}

More in localStorage explained.

Geolocation — needs permission#

JavaScript
function findMe() {
  if (!("geolocation" in navigator)) {
    return showMessage("Your browser cannot share a location.");
  }

  navigator.geolocation.getCurrentPosition(
    (position) => {
      const { latitude, longitude } = position.coords;
      showWeather(latitude, longitude);
    },
    (error) => {
      showMessage(
        error.code === error.PERMISSION_DENIED
          ? "Location access was declined."
          : "Could not work out your location."
      );
    },
    { timeout: 10000 }
  );
}

Three rules for any permissioned API: only ask after the user clicks something, always handle refusal, and never leave the page in a loading state if they say no.

Clipboard#

JavaScript
async function copy(text, button) {
  if (!navigator.clipboard) return;

  try {
    await navigator.clipboard.writeText(text);
    button.textContent = "Copied";
    setTimeout(() => (button.textContent = "Copy"), 1400);
  } catch {
    button.textContent = "Press Ctrl+C";
  }
}

Writing to the clipboard only works in response to a real user gesture — a click, not a timer.

IntersectionObserver — reacting to scroll#

Far better than listening to scroll and measuring positions, which runs hundreds of times a second.

JavaScript
const observer = new IntersectionObserver((entries) => {
  entries.forEach((entry) => {
    if (entry.isIntersecting) {
      entry.target.src = entry.target.dataset.src;   // load the image
      observer.unobserve(entry.target);
    }
  });
}, { rootMargin: "200px" });

document.querySelectorAll("img[data-src]").forEach((img) => observer.observe(img));

rootMargin starts the work slightly before the element is visible, so nothing pops in late.

Other ones worth knowing#

JavaScript
// Where am I in the site?
new URL(location.href).searchParams.get("page");

// Change the URL without reloading
history.pushState({}, "", "/results?q=python");

// Is the tab visible?
document.addEventListener("visibilitychange", () => {
  if (document.hidden) pauseTimer();
});

// Notify without blocking
if (Notification.permission === "granted") {
  new Notification("Done", { body: "Your export is ready." });
}

Feature detection#

Test for the thing itself rather than guessing from the browser name:

JavaScript
if ("IntersectionObserver" in window) {
  setUpLazyLoading();
} else {
  loadAllImagesNow();          // works everywhere, just less efficient
}

if (navigator.share) {
  showShareButton();           // hide it entirely when unsupported
}

The goal is that the page still works without the API — it just does less.

Questions people ask#

What is the difference between a web API and a REST API?

A web API here means a capability the browser provides your JavaScript. A REST API is a service on a server you send HTTP requests to. fetch is the browser API you use to call a REST API.

Do these work in Node.js?

Some do — fetch and URL exist in modern Node. Anything about the page, storage or permissions does not, because there is no browser.

How do I know if an API is widely supported?

Check a browser-support reference before relying on anything recent, and feature-detect regardless.

Where to go next#

Next lessonJavaScript Fetch API explained

Keep reading

Keep going — pick your next guide

The fastest way to improve is to read one guide, then build the thing it describes. Start with the basics, or jump straight to a project.

Ask a question or share what worked

Your email address will not be published. Required fields are marked *