Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

To connect to a nearby Bluetooth Low Energy (BLE) peripheral from a web page, run navigator.bluetooth.requestDevice() from a user action on a secure (HTTPS) page, select a device with the correct service permissions, connect to its GATT server, and then read, write, or subscribe to characteristics. The example below uses the standard Battery Service; replace its service and characteristic UUIDs with those exposed by your hardware.

Complete Web Bluetooth example

This page connects to a device that exposes the standard Battery Service and reads its battery percentage. Save it as index.html, serve it from HTTPS (or a browser-supported local development origin), and open it in a browser that implements Web Bluetooth.

<!doctype html>
<html lang="en">
<meta charset="utf-8">
<title>Web Bluetooth battery example</title>
<button id="connect" type="button">Connect Bluetooth device</button>
<output id="status" role="status">Disconnected</output>
<script>
const button = document.querySelector('#connect');
const status = document.querySelector('#status');

function setStatus(message) {
  status.textContent = message;
}

async function connectToDevice() {
  if (!window.isSecureContext) {
    throw new Error('Web Bluetooth requires a secure context (HTTPS).');
  }
  if (!navigator.bluetooth) {
    throw new Error('Web Bluetooth is unavailable in this browser.');
  }

  // This call must happen directly from the button click.
  const device = await navigator.bluetooth.requestDevice({
    filters: [{ services: ['battery_service'] }]
  });

  device.addEventListener('gattserverdisconnected', () => {
    setStatus('Device disconnected');
  });

  setStatus(`Connecting to ${device.name || 'device'}…`);
  const server = await device.gatt.connect();
  const service = await server.getPrimaryService('battery_service');
  const characteristic = await service.getCharacteristic('battery_level');
  const value = await characteristic.readValue();
  const percent = value.getUint8(0);

  setStatus(`Battery: ${percent}%`);
  return { device, server, characteristic, percent };
}

button.addEventListener('click', async () => {
  button.disabled = true;
  setStatus('Choose a device…');
  try {
    await connectToDevice();
  } catch (error) {
    setStatus(`${error.name || 'Error'}: ${error.message}`);
    console.error(error);
  } finally {
    button.disabled = false;
  }
});
</script>
</html>

battery_service and battery_level work only when the selected peripheral actually implements those standard UUIDs. For a custom board, use the service and characteristic UUIDs documented by its firmware.

How the connection flow works

1. Check the execution environment

Web Bluetooth is restricted to secure contexts. Deploy the page over HTTPS. A browser may also expose navigator.bluetooth while a later policy, hardware, or permission check still prevents a connection, so feature detection is only the first guard.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
#1 Best Overall
Sale
TP-Link USB Bluetooth Adapter for PC - Bluetooth 5.4 USB Dongle Receiver
  • Bluetooth 5.4 + Broad Compatibility - Provides Bluetooth 5.4 plus EDR technology and is backward compatible with Bluetooth V5.3/5.0/4.2/4.0/3.0/2.1/2.0/1.1.
  • Faster Speed, Extended Range - Get up to 2x faster data transfer and 4x broader coverage compared to Bluetooth 4.0 — perfect for smooth audio streaming and stable connections.
  • EDR and BLE Technology - This Bluetooth dongle is quipped with enhanced data rate and Bluetooth low energy, UB500 has greatly improved data transfer speed and operates at the optimal rate of power consumption
  • Nano-Sized - A sleek, ultra-small design means you can insert the Nano Bluetooth receiver into any USB port and simply keep it there regardless of whether you are traveling or at home
  • Plug & Play with Free Driver Support - Plug and play for Windows 8.1/10/11 (internet required). Supports Win7 (driver required and can be downloaded from website for free). Download the latest driver from TP-Link website to utilize Bluetooth 5.4

2. Request a device after a user gesture

requestDevice() opens the browser’s chooser and requires transient user activation, normally a button click or similar direct interaction. Do not call it automatically during page load or from a timer. The promise rejects if the user cancels, denies permission, or no matching device can be selected.

3. Choose filters and authorize services

A service filter is the safest usual choice because it limits the chooser to peripherals advertising a service you need:

const device = await navigator.bluetooth.requestDevice({
  filters: [
    { services: ['battery_service'] },
    { namePrefix: 'Sensor-' , services: ['0000180f-0000-1000-8000-00805f9b34fb'] }
  ]
});

Every service you will access after selection must be represented by a filter or by optionalServices. A name-only filter therefore needs optional service authorization:

const device = await navigator.bluetooth.requestDevice({
  filters: [{ namePrefix: 'Sensor-' }],
  optionalServices: ['battery_service', 'device_information']
});

If you genuinely cannot identify a service in advance, acceptAllDevices: true shows any discoverable device, but you still must list every service you plan to access in optionalServices:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
const device = await navigator.bluetooth.requestDevice({
  acceptAllDevices: true,
  optionalServices: ['battery_service']
});

Do not combine acceptAllDevices with filters; the request options must choose one strategy.

Rank #2
COMSOON Bluetooth Receiver for Car, 3.5mm AUX Bluetooth Car Adapter
  • 【Enjoy Wireless Streaming Music】This car Bluetooth adapter can be connected to non-Bluetooth car audio systems, home stereos, speakers, wired headphones via the 3.5mm AUX adapter; And equipped with a Bluetooth 5.0 chip for stable connection / fast transmission / wide signal range. Just pair it with your phone and start listening to your favorite music!
  • 【Intelligent Noise Reduction Tech】Our Bluetooth audio receiver adopts the latest CVC8.0 Noise Cancellation and Digital Signal Processor (DSP) technologies, which can eliminate echo and block out intrusive background noise (such as wind, traffic, or crowds), providing you with crystal-clear calling sounds.
  • 【Up to 16 Hours of Battery Life】The working time of this aux Bluetooth adapter is up to 16 hours when making calls or playing music. And it takes only 2.5 hours to fully charge the device by using a Type-C fast charging cable (Included in the package). In addition, this Bluetooth music adapter can be used while charging, which is very convenient.
  • 【Hands-free Calling & Navigation】A built-in microphone and one “MFB” button to answer / redial / hang up / reject calls, help you make hands-free calls. And the Bluetooth audio adapter supports broadcasting voice notification from existed navigation App. You don’t have to look down the phone on the move. Make sure you drive safely!
  • 【Dual Connection】The portable Bluetooth stereo adapter can be paired with 2 devices at the same time. You can enjoy your music and never worry about missing any calls. Once paired, the car receiver will automatically reconnect to your last paired Bluetooth devices, as long as they are within the wireless range.

4. Connect to GATT and obtain a characteristic

The selected device exposes a GATT server. Connect, retrieve the primary service, and then retrieve the characteristic by its assigned name or UUID:

const server = await device.gatt.connect();
const service = await server.getPrimaryService('battery_service');
const level = await service.getCharacteristic('battery_level');

Connection is asynchronous and can fail after the chooser succeeds. Keep the resulting device object so you can respond to disconnects or reconnect after an interruption.

Reading, writing, and notifications

Read a value

readValue() returns a DataView. Decode it according to the peripheral’s protocol, including byte order and field length:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
const value = await characteristic.readValue();
const firstByte = value.getUint8(0);
const littleEndianNumber = value.getUint16(0, true);

Write a command

A writable characteristic accepts a Uint8Array. The device’s documentation must define the command bytes; the following is only a transport pattern:

const command = new Uint8Array([0x01, 0x00]);
await characteristic.writeValue(command);

Some devices distinguish write-with-response from write-without-response. Use the method supported by the characteristic and firmware, and keep payloads within the device’s permitted size.

Rank #3
Sale
Esinkin Bluetooth Audio Adapter for Music Streaming Sound System
  • Listen music wireless: Connect with computer speakers, home stereo systems or other speaker systems via the 3.5 mm or RCA cable, then pair with the Bluetooth audio devices such as smartphones or tablet for streaming music.
  • Easy setup and automatic reconnect: There is a big bluetooth symbol button in bluetooth receiver middle. Pair your bluetooth device to this adapter with a single button press. Click once means Bluetooth Connect/Disconnect. Hold the botton 3 second mean ON/OFF. It can reconnect automatically with the previously paired device.
  • Wireless range: Indoors(without obstacles) connect rang up 30-40 ft (10-12 m).
  • Works with most device: Bluetooth enabled device including smartphones, tablets, computers, laptops upon and any powered PC speakers, home stereo systems and A/V receivers.
  • NOTE: This adapter doesn't have built-in battery, power by AC to DC power adapter or USB cable. This product is a bluetooth receiver ONLY, not a bluetooth transmitter. Only to give Bluetooth capabilities to an existing stereo / powered speaker / PA. If you have any problems, please contact us at any time by Amazon Order, and we will speed up the process to resolve the issue.

Subscribe to notifications

For streaming sensor data, start notifications and decode each incoming DataView:

await characteristic.startNotifications();
characteristic.addEventListener('characteristicvaluechanged', event => {
  const value = event.target.value;
  console.log('Received byte:', value.getUint8(0));
});

Call stopNotifications() when the page no longer needs updates. Notifications are not a substitute for reconnect logic: a disconnect ends the GATT session.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Handle disconnects and reconnects

device.addEventListener('gattserverdisconnected', async () => {
  console.log('Disconnected');
  // Reconnect only in response to an appropriate application action or policy.
  try {
    const server = await device.gatt.connect();
    console.log('Reconnected', server.connected);
  } catch (error) {
    console.error('Reconnect failed', error);
  }
});

Always treat a reconnect as a new session: reacquire services and characteristics and restart notifications.

Availability, permissions, and iframes

getAvailability() is only a hint

if (navigator.bluetooth?.getAvailability) {
  const possiblyAvailable = await navigator.bluetooth.getAvailability();
  console.log('Bluetooth may be available:', possiblyAvailable);
}

A false result can reflect adapter state, browser settings, or policy. A true result does not guarantee that the adapter is powered, a peripheral is discoverable, the chooser will return a device, or GATT operations will succeed. Handle errors from the real request and connection path.

Permissions Policy

The bluetooth Permissions Policy defaults to self. A top-level page normally needs no extra markup. A cross-origin iframe needs both a response policy that authorizes the frame’s origin and an iframe attribute such as:

Rank #4
UGREEN USB Bluetooth 5.3 Adapter for PC Bluetooth Dongle Receiver
  • Upgraded Bluetooth 5.3 Adapter: This bluetooth adapter for pc uses the latest upgraded Bluetooth 5.3 BR+EDR technology, greatly improves the stability of the connection data transfer speed, reduces the possibility of signal interruption and power consumption.
  • Up to 5 Devices Sync Connected: UGREEN Bluetooth dongle for PC supports up to 5 different types of Bluetooth devices to be connected at the same time without interfering with each other, such as Bluetooth mouse/keyboard/mobile phone/headphones, etc. If Bluetooth audio devices of the same type (such as speakers/headphones) are connected, only one device can play music.
  • Plug and Play: The Bluetooth adapter is developed for Windows systems only and does not support other systems. No driver installation is required under Windows 11/10/8.1. NOTE: Win 7, Linux and MacOS System are NOT supported.
  • Mini Size: An extremely compact Bluetooth stick that you can leave on your laptop or PC without removing it.The compact size does not interfere with other USB ports. Convenient to carry, no space occupation.
  • What Can I do if the Bluetooth adapter can not work?: Ensure there are no other Bluetooth devices installed on the computer. If there are, disable all existing Bluetooth devices in "Device Manager", then insert the adapter and try again. (For detailed information please read the user manual)
<iframe src="https://app.example" allow="bluetooth"></iframe>

Without both permissions, requestDevice() can fail even when the browser and hardware otherwise support Web Bluetooth.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Browser support and deployment checklist

MDN classifies Web Bluetooth as experimental and not Baseline because it is unavailable in some widely used browsers. Support differs by browser, operating system, device adapter, and enterprise policy. Check the live compatibility table for your exact deployment target instead of promising universal support.

  • Serve the page from HTTPS and verify window.isSecureContext.
  • Test in the browser and operating system your users actually run.
  • Use a real BLE peripheral advertising the required service.
  • Trigger requestDevice() directly from a visible user action.
  • Document the service and characteristic UUIDs, permissions, payload format, and notification behavior.
  • Provide a non-Bluetooth fallback when your application must work in unsupported browsers.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Why requestDevice() fails: troubleshooting

“Web Bluetooth is unavailable”

The browser may not implement the API, the page may not be secure, or an embedded context may be blocked. Check navigator.bluetooth, load the page over HTTPS, and verify the target browser’s current compatibility data.

“User activation is required”

The call was detached from a user gesture. Move requestDevice() into the click or tap handler; do not await unrelated work before invoking it.

The chooser is empty

Your filters may not match what the peripheral advertises, the device may not be discoverable, or the adapter may be off. Confirm the advertised service UUID and temporarily use a narrow name-plus-service filter rather than broad assumptions. acceptAllDevices can help diagnose discovery, but still requires optionalServices for later access.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Best Value
Sale
Amazon Basics Bluetooth 5.4 USB Adapter Dongle for PC, USB Receiver for Bluetooth Mouse, Keyboard, Laptop, Works with Windows 11/10/8.1
  • INSTANT BLUETOOTH ACCESS: Bluetooth dongle adapter receiver for PCs converts non-Bluetooth devices into Bluetooth-capable with simple USB connection
  • WIDE COMPATIBILITY: Supports Bluetooth 5.4 and is backwards compatible with Bluetooth 5.3/5.2/5.1/5.0/V4.2/4.0/3.0/2.1/2.0/1.1; ONLY works with Windows 8.1, 10, and 11
  • MULTI-DEVICE CONNECTION: Connect up to 6 devices simultaneously; Not compatible with all other operation systems e.g. Mac, Linux, Chrome, Unix, Playstation(PS), Windows 7 and below; Nano bluetooth receiver can be plugged in via any standard USB port
  • ENHANCED PERFORMANCE: EDR and BLE technology offers enhanced data rate/transfer speed and low energy consumption
  • SYSTEM REQUIREMENTS: Not compatible with all other operation systems e.g. Mac, Linux, Chrome, Unix, Playstation(PS), Windows 7 and below; Disable any built-in Bluetooth of the device before use this product, refer to the user manual for detail

“Origin is not allowed” or a policy error

Check the top-level response’s Permissions Policy and, for an iframe, add allow="bluetooth" and authorize the iframe origin. A cross-origin frame cannot grant itself permission.

“Service not found” or “Characteristic not found”

The UUID is wrong, the firmware does not expose that service, or the service was not authorized in filters or optionalServices. Inspect the peripheral’s GATT definition and reacquire objects after reconnecting.

The device disconnects during a read or write

Radio range, power management, peripheral firmware, and concurrent connections can interrupt GATT. Listen for gattserverdisconnected, show a recoverable status, reconnect, and repeat service discovery rather than reusing stale characteristic objects.

Or skip the browser setup

If your goal is a rendered image of a web page rather than communication with a BLE peripheral, ScreenshotNeo provides a single screenshot API call. It removes cookie banners, newsletter popups, and chat widgets before capture; bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing result. Its MCP server lets Claude, Cursor, and other MCP clients call take_screenshot, get_page_info, and capture_pdf.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

See the ScreenshotNeo API documentation for the other 63 options, including full-page and element capture, device presets, custom CSS and JavaScript, waits, headers, cookies, geolocation, PDF output, caching, signed links, webhooks, and bulk jobs.

The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots. Create a free ScreenshotNeo account.

Frequently Asked Questions

Can Web Bluetooth connect to classic Bluetooth devices?

No. The Web Bluetooth API is designed for Bluetooth Low Energy peripherals that expose GATT services and characteristics; a classic Bluetooth profile is not automatically accessible through this API.

Can a page reconnect to a previously authorized device without showing the chooser?

A page can work with a previously obtained device object in supported implementations, but connection can still fail because of adapter state, range, permissions, or device availability. Build explicit reconnect and error handling rather than assuming persistence.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Should I use a service UUID or acceptAllDevices?

Prefer a service-based filter when you know the required service. It narrows discovery and documents the capability you need. Use acceptAllDevices only when you cannot identify a service ahead of time, and authorize access with optionalServices.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.