CINXE.COM

Access USB Devices on the Web  |  Capabilities  |  Chrome for Developers

<!doctype html> <html lang="en" dir="ltr"> <head> <meta name="google-signin-client-id" content="157101835696-ooapojlodmuabs2do2vuhhnf90bccmoi.apps.googleusercontent.com"> <meta name="google-signin-scope" content="profile email https://www.googleapis.com/auth/developerprofiles https://www.googleapis.com/auth/developerprofiles.award"> <meta property="og:site_name" content="Chrome for Developers"> <meta property="og:type" content="website"><meta name="theme-color" content="#1a73e8"><meta charset="utf-8"> <meta content="IE=Edge" http-equiv="X-UA-Compatible"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="manifest" href="/_pwa/chrome/manifest.json" crossorigin="use-credentials"> <link rel="preconnect" href="//www.gstatic.com" crossorigin> <link rel="preconnect" href="//fonts.gstatic.com" crossorigin> <link rel="preconnect" href="//fonts.googleapis.com" crossorigin> <link rel="preconnect" href="//apis.google.com" crossorigin> <link rel="preconnect" href="//www.google-analytics.com" crossorigin><link rel="stylesheet" href="//fonts.googleapis.com/css?family=Google+Sans:400,500|Roboto:400,400italic,500,500italic,700,700italic|Roboto+Mono:400,500,700&display=swap"> <link rel="stylesheet" href="//fonts.googleapis.com/css2?family=Material+Icons&family=Material+Symbols+Outlined&display=block"><link rel="stylesheet" href="https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/chrome/css/app.css"> <link rel="stylesheet" href="https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/chrome/css/dark-theme.css" disabled> <link rel="shortcut icon" href="https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/chrome/images/favicon.png"> <link rel="apple-touch-icon" href="https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/chrome/images/touchicon-180.png"><link rel="canonical" href="https://developer.chrome.com/docs/capabilities/usb"><link rel="search" type="application/opensearchdescription+xml" title="Chrome for Developers" href="https://developer.chrome.com/s/opensearch.xml"> <link rel="alternate" hreflang="en" href="https://developer.chrome.com/docs/capabilities/usb" /><link rel="alternate" hreflang="x-default" href="https://developer.chrome.com/docs/capabilities/usb" /><link rel="alternate" hreflang="ar" href="https://developer.chrome.com/docs/capabilities/usb?hl=ar" /><link rel="alternate" hreflang="bn" href="https://developer.chrome.com/docs/capabilities/usb?hl=bn" /><link rel="alternate" hreflang="zh-Hans" href="https://developer.chrome.com/docs/capabilities/usb?hl=zh-cn" /><link rel="alternate" hreflang="zh-Hant" href="https://developer.chrome.com/docs/capabilities/usb?hl=zh-tw" /><link rel="alternate" hreflang="nl" href="https://developer.chrome.com/docs/capabilities/usb?hl=nl" /><link rel="alternate" hreflang="fa" href="https://developer.chrome.com/docs/capabilities/usb?hl=fa" /><link rel="alternate" hreflang="fr" href="https://developer.chrome.com/docs/capabilities/usb?hl=fr" /><link rel="alternate" hreflang="de" href="https://developer.chrome.com/docs/capabilities/usb?hl=de" /><link rel="alternate" hreflang="he" href="https://developer.chrome.com/docs/capabilities/usb?hl=he" /><link rel="alternate" hreflang="hi" href="https://developer.chrome.com/docs/capabilities/usb?hl=hi" /><link rel="alternate" hreflang="id" href="https://developer.chrome.com/docs/capabilities/usb?hl=id" /><link rel="alternate" hreflang="it" href="https://developer.chrome.com/docs/capabilities/usb?hl=it" /><link rel="alternate" hreflang="ja" href="https://developer.chrome.com/docs/capabilities/usb?hl=ja" /><link rel="alternate" hreflang="ko" href="https://developer.chrome.com/docs/capabilities/usb?hl=ko" /><link rel="alternate" hreflang="pl" href="https://developer.chrome.com/docs/capabilities/usb?hl=pl" /><link rel="alternate" hreflang="pt-BR" href="https://developer.chrome.com/docs/capabilities/usb?hl=pt-br" /><link rel="alternate" hreflang="ru" href="https://developer.chrome.com/docs/capabilities/usb?hl=ru" /><link rel="alternate" hreflang="es-419" href="https://developer.chrome.com/docs/capabilities/usb?hl=es-419" /><link rel="alternate" hreflang="th" href="https://developer.chrome.com/docs/capabilities/usb?hl=th" /><link rel="alternate" hreflang="tr" href="https://developer.chrome.com/docs/capabilities/usb?hl=tr" /><link rel="alternate" hreflang="vi" href="https://developer.chrome.com/docs/capabilities/usb?hl=vi" /><link rel="alternate" hreflang="en-cn" href="https://developer.chrome.google.cn/docs/capabilities/usb" /><link rel="alternate" hreflang="x-default" href="https://developer.chrome.google.cn/docs/capabilities/usb" /><link rel="alternate" hreflang="ar-cn" href="https://developer.chrome.google.cn/docs/capabilities/usb?hl=ar" /><link rel="alternate" hreflang="bn-cn" href="https://developer.chrome.google.cn/docs/capabilities/usb?hl=bn" /><link rel="alternate" hreflang="zh-Hans-cn" href="https://developer.chrome.google.cn/docs/capabilities/usb?hl=zh-cn" /><link rel="alternate" hreflang="zh-Hant-cn" href="https://developer.chrome.google.cn/docs/capabilities/usb?hl=zh-tw" /><link rel="alternate" hreflang="nl-cn" href="https://developer.chrome.google.cn/docs/capabilities/usb?hl=nl" /><link rel="alternate" hreflang="fa-cn" href="https://developer.chrome.google.cn/docs/capabilities/usb?hl=fa" /><link rel="alternate" hreflang="fr-cn" href="https://developer.chrome.google.cn/docs/capabilities/usb?hl=fr" /><link rel="alternate" hreflang="de-cn" href="https://developer.chrome.google.cn/docs/capabilities/usb?hl=de" /><link rel="alternate" hreflang="he-cn" href="https://developer.chrome.google.cn/docs/capabilities/usb?hl=he" /><link rel="alternate" hreflang="hi-cn" href="https://developer.chrome.google.cn/docs/capabilities/usb?hl=hi" /><link rel="alternate" hreflang="id-cn" href="https://developer.chrome.google.cn/docs/capabilities/usb?hl=id" /><link rel="alternate" hreflang="it-cn" href="https://developer.chrome.google.cn/docs/capabilities/usb?hl=it" /><link rel="alternate" hreflang="ja-cn" href="https://developer.chrome.google.cn/docs/capabilities/usb?hl=ja" /><link rel="alternate" hreflang="ko-cn" href="https://developer.chrome.google.cn/docs/capabilities/usb?hl=ko" /><link rel="alternate" hreflang="pl-cn" href="https://developer.chrome.google.cn/docs/capabilities/usb?hl=pl" /><link rel="alternate" hreflang="pt-BR-cn" href="https://developer.chrome.google.cn/docs/capabilities/usb?hl=pt-br" /><link rel="alternate" hreflang="ru-cn" href="https://developer.chrome.google.cn/docs/capabilities/usb?hl=ru" /><link rel="alternate" hreflang="es-419-cn" href="https://developer.chrome.google.cn/docs/capabilities/usb?hl=es-419" /><link rel="alternate" hreflang="th-cn" href="https://developer.chrome.google.cn/docs/capabilities/usb?hl=th" /><link rel="alternate" hreflang="tr-cn" href="https://developer.chrome.google.cn/docs/capabilities/usb?hl=tr" /><link rel="alternate" hreflang="vi-cn" href="https://developer.chrome.google.cn/docs/capabilities/usb?hl=vi" /><title>Access USB Devices on the Web &nbsp;|&nbsp; Capabilities &nbsp;|&nbsp; Chrome for Developers</title> <meta property="og:title" content="Access USB Devices on the Web &nbsp;|&nbsp; Capabilities &nbsp;|&nbsp; Chrome for Developers"><meta name="description" content="The WebUSB API makes USB safer and easier to use by bringing it to the Web."> <meta property="og:description" content="The WebUSB API makes USB safer and easier to use by bringing it to the Web."><meta property="og:url" content="https://developer.chrome.com/docs/capabilities/usb"><meta property="og:image" content="https://developer.chrome.com/static/docs/capabilities/usb/image/thumbnail.jpg"> <meta property="og:image:width" content="1200"> <meta property="og:image:height" content="675"><meta property="og:locale" content="en"><meta name="twitter:card" content="summary_large_image"><script type="application/ld+json"> { "@context": "https://schema.org", "@type": "Article", "dateModified": "2016-03-30", "headline": "Access USB Devices on the Web" } </script><script type="application/ld+json"> { "@context": "https://schema.org", "@type": "BreadcrumbList", "itemListElement": [{ "@type": "ListItem", "position": 1, "name": "Docs", "item": "https://developer.chrome.com/docs" },{ "@type": "ListItem", "position": 2, "name": "Capabilities", "item": "https://developer.chrome.com/docs/capabilities" },{ "@type": "ListItem", "position": 3, "name": "Access USB Devices on the Web", "item": "https://developer.chrome.com/docs/capabilities/usb" }] } </script> <link rel="stylesheet" href="/extras.css"></head> <body class="" template="page" theme="chrome-theme" type="article" appearance layout="docs" display-toc pending> <devsite-progress type="indeterminate" id="app-progress"></devsite-progress> <section class="devsite-wrapper"> <devsite-cookie-notification-bar></devsite-cookie-notification-bar><devsite-header role="banner"> <div class="devsite-header--inner nocontent"> <div class="devsite-top-logo-row-wrapper-wrapper"> <div class="devsite-top-logo-row-wrapper"> <div class="devsite-top-logo-row"> <button type="button" id="devsite-hamburger-menu" class="devsite-header-icon-button button-flat material-icons gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Navigation menu button" visually-hidden aria-label="Open menu"> </button> <div class="devsite-product-name-wrapper"> <a href="/" class="devsite-site-logo-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Site logo" track-type="globalNav" track-name="chromeForDevelopers" track-metadata-position="nav" track-metadata-eventDetail="nav"> <picture> <source srcset="https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/chrome/images/lockup-dark-theme.svg" media="(prefers-color-scheme: dark)" class="devsite-dark-theme" alt="Chrome for Developers"> <img src="https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/chrome/images/lockup.svg" class="devsite-site-logo" alt="Chrome for Developers"> </picture> </a> <span class="devsite-product-name"> <ul class="devsite-breadcrumb-list" > <li class="devsite-breadcrumb-item "> </li> </ul> </span> </div> <div class="devsite-top-logo-row-middle"> <div class="devsite-header-upper-tabs"> <devsite-tabs class="upper-tabs"> <nav class="devsite-tabs-wrapper" aria-label="Upper tabs"> <tab > <a href="https://developer.chrome.com/case-studies" track-metadata-eventdetail="https://developer.chrome.com/case-studies" class="devsite-tabs-content gc-analytics-event " track-type="nav" track-metadata-position="nav - get inspired" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: Get inspired" track-name="get inspired" > Get inspired </a> </tab> <tab > <a href="https://developer.chrome.com/blog" track-metadata-eventdetail="https://developer.chrome.com/blog" class="devsite-tabs-content gc-analytics-event " track-type="nav" track-metadata-position="nav - blog" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: Blog" track-name="blog" > Blog </a> </tab> <tab class="devsite-dropdown devsite-dropdown-full devsite-active "> <a href="https://developer.chrome.com/docs" track-metadata-eventdetail="https://developer.chrome.com/docs" class="devsite-tabs-content gc-analytics-event " track-type="nav" track-metadata-position="nav - docs" track-metadata-module="primary nav" aria-label="Docs, selected" data-category="Site-Wide Custom Events" data-label="Tab: Docs" track-name="docs" > Docs </a> <a href="#" role="button" aria-haspopup="true" aria-expanded="false" aria-label="Dropdown menu for Docs" track-type="nav" track-metadata-eventdetail="https://developer.chrome.com/docs" track-metadata-position="nav - docs" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: Docs" track-name="docs" class="devsite-tabs-dropdown-toggle devsite-icon devsite-icon-arrow-drop-down"></a> <div class="devsite-tabs-dropdown" aria-label="submenu" hidden> <div class="devsite-tabs-dropdown-content"> <div class="devsite-tabs-dropdown-column "> <ul class="devsite-tabs-dropdown-section build-icon dcc-subnav"> <li class="devsite-nav-title" role="heading" tooltip>Build with Chrome</li> <li class="devsite-nav-description">Learn how Chrome works, participate in origin trials, and build with Chrome everywhere. </li> <li class="devsite-nav-item"> <a href="https://developer.chrome.com/docs/web-platform" track-type="nav" track-metadata-eventdetail="https://developer.chrome.com/docs/web-platform" track-metadata-position="nav - docs" track-metadata-module="tertiary nav" track-metadata-module_headline="build with chrome" tooltip > <div class="devsite-nav-item-title"> Web Platform </div> </a> </li> <li class="devsite-nav-item"> <a href="https://developer.chrome.com/docs/capabilities" track-type="nav" track-metadata-eventdetail="https://developer.chrome.com/docs/capabilities" track-metadata-position="nav - docs" track-metadata-module="tertiary nav" track-metadata-module_headline="build with chrome" tooltip > <div class="devsite-nav-item-title"> Capabilities </div> </a> </li> <li class="devsite-nav-item"> <a href="https://developer.chrome.com/docs/chromedriver" track-type="nav" track-metadata-eventdetail="https://developer.chrome.com/docs/chromedriver" track-metadata-position="nav - docs" track-metadata-module="tertiary nav" track-metadata-module_headline="build with chrome" tooltip > <div class="devsite-nav-item-title"> ChromeDriver </div> </a> </li> <li class="devsite-nav-item"> <a href="https://developer.chrome.com/docs/extensions" track-type="nav" track-metadata-eventdetail="https://developer.chrome.com/docs/extensions" track-metadata-position="nav - docs" track-metadata-module="tertiary nav" track-metadata-module_headline="build with chrome" tooltip > <div class="devsite-nav-item-title"> Extensions </div> </a> </li> <li class="devsite-nav-item"> <a href="https://developer.chrome.com/docs/webstore" track-type="nav" track-metadata-eventdetail="https://developer.chrome.com/docs/webstore" track-metadata-position="nav - docs" track-metadata-module="tertiary nav" track-metadata-module_headline="build with chrome" tooltip > <div class="devsite-nav-item-title"> Chrome Web Store </div> </a> </li> <li class="devsite-nav-item"> <a href="https://developer.chrome.com/docs/chromium" track-type="nav" track-metadata-eventdetail="https://developer.chrome.com/docs/chromium" track-metadata-position="nav - docs" track-metadata-module="tertiary nav" track-metadata-module_headline="build with chrome" tooltip > <div class="devsite-nav-item-title"> Chromium </div> </a> </li> <li class="devsite-nav-item"> <a href="https://developer.chrome.com/docs/aurora" track-type="nav" track-metadata-eventdetail="https://developer.chrome.com/docs/aurora" track-metadata-position="nav - docs" track-metadata-module="tertiary nav" track-metadata-module_headline="build with chrome" tooltip > <div class="devsite-nav-item-title"> Aurora </div> </a> </li> <li class="devsite-nav-item"> <a href="https://developer.chrome.com/docs/android" track-type="nav" track-metadata-eventdetail="https://developer.chrome.com/docs/android" track-metadata-position="nav - docs" track-metadata-module="tertiary nav" track-metadata-module_headline="build with chrome" tooltip > <div class="devsite-nav-item-title"> Web on Android </div> </a> </li> <li class="devsite-nav-item"> <a href="https://developer.chrome.com/origintrials/" track-type="nav" track-metadata-eventdetail="https://developer.chrome.com/origintrials/" track-metadata-position="nav - docs" track-metadata-module="tertiary nav" track-metadata-module_headline="build with chrome" tooltip > <div class="devsite-nav-item-title"> Origin trials </div> </a> </li> <li class="devsite-nav-item"> <a href="https://developer.chrome.com/release-notes" track-type="nav" track-metadata-eventdetail="https://developer.chrome.com/release-notes" track-metadata-position="nav - docs" track-metadata-module="tertiary nav" track-metadata-module_headline="build with chrome" tooltip > <div class="devsite-nav-item-title"> Release notes </div> </a> </li> </ul> </div> <div class="devsite-tabs-dropdown-column "> <ul class="devsite-tabs-dropdown-section productivity-icon dcc-subnav"> <li class="devsite-nav-title" role="heading" tooltip>Productivity</li> <li class="devsite-nav-description">Create the best experience for your users with the web&#39;s best tools.</li> <li class="devsite-nav-item"> <a href="https://developer.chrome.com/docs/devtools" track-type="nav" track-metadata-eventdetail="https://developer.chrome.com/docs/devtools" track-metadata-position="nav - docs" track-metadata-module="tertiary nav" track-metadata-module_headline="productivity" tooltip > <div class="devsite-nav-item-title"> DevTools </div> </a> </li> <li class="devsite-nav-item"> <a href="https://developer.chrome.com/docs/lighthouse" track-type="nav" track-metadata-eventdetail="https://developer.chrome.com/docs/lighthouse" track-metadata-position="nav - docs" track-metadata-module="tertiary nav" track-metadata-module_headline="productivity" tooltip > <div class="devsite-nav-item-title"> Lighthouse </div> </a> </li> <li class="devsite-nav-item"> <a href="https://developer.chrome.com/docs/crux" track-type="nav" track-metadata-eventdetail="https://developer.chrome.com/docs/crux" track-metadata-position="nav - docs" track-metadata-module="tertiary nav" track-metadata-module_headline="productivity" tooltip > <div class="devsite-nav-item-title"> Chrome UX Report </div> </a> </li> <li class="devsite-nav-item"> <a href="https://developer.chrome.com/docs/accessibility" track-type="nav" track-metadata-eventdetail="https://developer.chrome.com/docs/accessibility" track-metadata-position="nav - docs" track-metadata-module="tertiary nav" track-metadata-module_headline="productivity" tooltip > <div class="devsite-nav-item-title"> Accessibility </div> </a> </li> </ul> <ul class="devsite-tabs-dropdown-section dcc-subnav second-column-list"> <li class="devsite-nav-description">Get things done quicker and neater, with our ready-made libraries. </li> <li class="devsite-nav-item"> <a href="https://developer.chrome.com/docs/workbox" track-type="nav" track-metadata-eventdetail="https://developer.chrome.com/docs/workbox" track-metadata-position="nav - docs" track-metadata-module="tertiary nav" track-metadata-module_headline="productivity" tooltip > <div class="devsite-nav-item-title"> Workbox </div> </a> </li> <li class="devsite-nav-item"> <a href="https://developer.chrome.com/docs/puppeteer" track-type="nav" track-metadata-eventdetail="https://developer.chrome.com/docs/puppeteer" track-metadata-position="nav - docs" track-metadata-module="tertiary nav" track-metadata-module_headline="productivity" tooltip > <div class="devsite-nav-item-title"> Puppeteer </div> </a> </li> </ul> </div> <div class="devsite-tabs-dropdown-column "> <ul class="devsite-tabs-dropdown-section experience-icon dcc-subnav"> <li class="devsite-nav-title" role="heading" tooltip>Experience</li> <li class="devsite-nav-description">Design a beautiful and performant web with Chrome. </li> <li class="devsite-nav-item"> <a href="https://developer.chrome.com/docs/ai" track-type="nav" track-metadata-eventdetail="https://developer.chrome.com/docs/ai" track-metadata-position="nav - docs" track-metadata-module="tertiary nav" track-metadata-module_headline="experience" tooltip > <div class="devsite-nav-item-title"> AI </div> </a> </li> <li class="devsite-nav-item"> <a href="https://developer.chrome.com/docs/performance" track-type="nav" track-metadata-eventdetail="https://developer.chrome.com/docs/performance" track-metadata-position="nav - docs" track-metadata-module="tertiary nav" track-metadata-module_headline="experience" tooltip > <div class="devsite-nav-item-title"> Performance </div> </a> </li> <li class="devsite-nav-item"> <a href="https://developer.chrome.com/docs/css-ui" track-type="nav" track-metadata-eventdetail="https://developer.chrome.com/docs/css-ui" track-metadata-position="nav - docs" track-metadata-module="tertiary nav" track-metadata-module_headline="experience" tooltip > <div class="devsite-nav-item-title"> CSS and UI </div> </a> </li> <li class="devsite-nav-item"> <a href="https://developer.chrome.com/docs/identity" track-type="nav" track-metadata-eventdetail="https://developer.chrome.com/docs/identity" track-metadata-position="nav - docs" track-metadata-module="tertiary nav" track-metadata-module_headline="experience" tooltip > <div class="devsite-nav-item-title"> Identity </div> </a> </li> <li class="devsite-nav-item"> <a href="https://developer.chrome.com/docs/payments" track-type="nav" track-metadata-eventdetail="https://developer.chrome.com/docs/payments" track-metadata-position="nav - docs" track-metadata-module="tertiary nav" track-metadata-module_headline="experience" tooltip > <div class="devsite-nav-item-title"> Payments </div> </a> </li> <li class="devsite-nav-item"> <a href="https://developer.chrome.com/docs/privacy-security" track-type="nav" track-metadata-eventdetail="https://developer.chrome.com/docs/privacy-security" track-metadata-position="nav - docs" track-metadata-module="tertiary nav" track-metadata-module_headline="experience" tooltip > <div class="devsite-nav-item-title"> Privacy and security </div> </a> </li> </ul> </div> <div class="devsite-tabs-dropdown-column "> <ul class="devsite-tabs-dropdown-section resources-icon dcc-subnav"> <li class="devsite-nav-title" role="heading" tooltip>Resources</li> <li class="devsite-nav-description">More from the Chrome team. </li> <li class="devsite-nav-item"> <a href="https://developer.chrome.com/docs" track-type="nav" track-metadata-eventdetail="https://developer.chrome.com/docs" track-metadata-position="nav - docs" track-metadata-module="tertiary nav" track-metadata-module_headline="resources" tooltip > <div class="devsite-nav-item-title"> All documentation </div> </a> </li> <li class="devsite-nav-item"> <a href="https://web.dev/baseline" track-type="nav" track-metadata-eventdetail="https://web.dev/baseline" track-metadata-position="nav - docs" track-metadata-module="tertiary nav" track-metadata-module_headline="resources" tooltip > <div class="devsite-nav-item-title"> Baseline </div> </a> </li> <li class="devsite-nav-item"> <a href="https://web.dev" track-type="nav" track-metadata-eventdetail="https://web.dev" track-metadata-position="nav - docs" track-metadata-module="tertiary nav" track-metadata-module_headline="resources" tooltip > <div class="devsite-nav-item-title"> web.dev </div> </a> </li> </ul> </div> </div> </div> </tab> <tab > <a href="https://developer.chrome.com/new" track-metadata-eventdetail="https://developer.chrome.com/new" class="devsite-tabs-content gc-analytics-event " track-type="nav" track-metadata-position="nav - new in chrome" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: New in Chrome" track-name="new in chrome" > New in Chrome </a> </tab> </nav> </devsite-tabs> </div> <devsite-search enable-signin enable-search enable-suggestions enable-query-completion project-name="Capabilities" tenant-name="Chrome for Developers" > <form class="devsite-search-form" action="https://developer.chrome.com/s/results" method="GET"> <div class="devsite-search-container"> <button type="button" search-open class="devsite-search-button devsite-header-icon-button button-flat material-icons" aria-label="Open search"></button> <div class="devsite-searchbox"> <input aria-activedescendant="" aria-autocomplete="list" aria-label="Search" aria-expanded="false" aria-haspopup="listbox" autocomplete="off" class="devsite-search-field devsite-search-query" name="q" placeholder="Search" role="combobox" type="text" value="" > <div class="devsite-search-image material-icons" aria-hidden="true"> </div> <div class="devsite-search-shortcut-icon-container" aria-hidden="true"> <kbd class="devsite-search-shortcut-icon">/</kbd> </div> </div> </div> </form> <button type="button" search-close class="devsite-search-button devsite-header-icon-button button-flat material-icons" aria-label="Close search"></button> </devsite-search> </div> <devsite-appearance-selector></devsite-appearance-selector> <devsite-language-selector> <ul role="presentation"> <li role="presentation"> <a role="menuitem" lang="en" >English</a> </li> <li role="presentation"> <a role="menuitem" lang="de" >Deutsch</a> </li> <li role="presentation"> <a role="menuitem" lang="es_419" >Español – América Latina</a> </li> <li role="presentation"> <a role="menuitem" lang="fr" >Français</a> </li> <li role="presentation"> <a role="menuitem" lang="id" >Indonesia</a> </li> <li role="presentation"> <a role="menuitem" lang="it" >Italiano</a> </li> <li role="presentation"> <a role="menuitem" lang="nl" >Nederlands</a> </li> <li role="presentation"> <a role="menuitem" lang="pl" >Polski</a> </li> <li role="presentation"> <a role="menuitem" lang="pt_br" >Português – Brasil</a> </li> <li role="presentation"> <a role="menuitem" lang="vi" >Tiếng Việt</a> </li> <li role="presentation"> <a role="menuitem" lang="tr" >Türkçe</a> </li> <li role="presentation"> <a role="menuitem" lang="ru" >Русский</a> </li> <li role="presentation"> <a role="menuitem" lang="he" >עברית</a> </li> <li role="presentation"> <a role="menuitem" lang="ar" >العربيّة</a> </li> <li role="presentation"> <a role="menuitem" lang="fa" >فارسی</a> </li> <li role="presentation"> <a role="menuitem" lang="hi" >हिंदी</a> </li> <li role="presentation"> <a role="menuitem" lang="bn" >বাংলা</a> </li> <li role="presentation"> <a role="menuitem" lang="th" >ภาษาไทย</a> </li> <li role="presentation"> <a role="menuitem" lang="zh_cn" >中文 – 简体</a> </li> <li role="presentation"> <a role="menuitem" lang="zh_tw" >中文 – 繁體</a> </li> <li role="presentation"> <a role="menuitem" lang="ja" >日本語</a> </li> <li role="presentation"> <a role="menuitem" lang="ko" >한국어</a> </li> </ul> </devsite-language-selector> <devsite-user enable-profiles id="devsite-user"> <span class="button devsite-top-button" aria-hidden="true" visually-hidden>Sign in</span> </devsite-user> </div> </div> </div> <div class="devsite-collapsible-section "> <div class="devsite-header-background"> <div class="devsite-product-id-row" > <div class="devsite-product-description-row"> <ul class="devsite-breadcrumb-list" > <li class="devsite-breadcrumb-item "> <a href="https://developer.chrome.com/docs/capabilities" class="devsite-breadcrumb-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Lower Header" data-value="1" track-type="globalNav" track-name="breadcrumb" track-metadata-position="1" track-metadata-eventdetail="Capabilities" > Capabilities </a> </li> </ul> </div> </div> <div class="devsite-doc-set-nav-row"> <devsite-tabs class="lower-tabs"> <nav class="devsite-tabs-wrapper" aria-label="Lower tabs"> <tab class="devsite-active"> <a href="https://developer.chrome.com/docs/capabilities" track-metadata-eventdetail="https://developer.chrome.com/docs/capabilities" class="devsite-tabs-content gc-analytics-event " track-type="nav" track-metadata-position="nav - capabilities" track-metadata-module="primary nav" aria-label="Capabilities, selected" data-category="Site-Wide Custom Events" data-label="Tab: Capabilities" track-name="capabilities" > Capabilities </a> </tab> <tab > <a href="https://developer.chrome.com/docs/capabilities/fugu-showcase" track-metadata-eventdetail="https://developer.chrome.com/docs/capabilities/fugu-showcase" class="devsite-tabs-content gc-analytics-event " track-type="nav" track-metadata-position="nav - fugu showcase" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: Fugu showcase" track-name="fugu showcase" > Fugu showcase </a> </tab> <tab > <a href="https://developer.chrome.com/docs/chromedriver" track-metadata-eventdetail="https://developer.chrome.com/docs/chromedriver" class="devsite-tabs-content gc-analytics-event " track-type="nav" track-metadata-position="nav - chromedriver" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: ChromeDriver" track-name="chromedriver" > ChromeDriver </a> </tab> </nav> </devsite-tabs> </div> </div> </div> </div> </devsite-header> <devsite-book-nav scrollbars > <div class="devsite-book-nav-filter" hidden> <span class="filter-list-icon material-icons" aria-hidden="true"></span> <input type="text" placeholder="Filter" aria-label="Type to filter" role="searchbox"> <span class="filter-clear-button hidden" data-title="Clear filter" aria-label="Clear filter" role="button" tabindex="0"></span> </div> <nav class="devsite-book-nav devsite-nav nocontent" aria-label="Side menu"> <div class="devsite-mobile-header"> <button type="button" id="devsite-close-nav" class="devsite-header-icon-button button-flat material-icons gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Close navigation" aria-label="Close navigation"> </button> <div class="devsite-product-name-wrapper"> <a href="/" class="devsite-site-logo-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Site logo" track-type="globalNav" track-name="chromeForDevelopers" track-metadata-position="nav" track-metadata-eventDetail="nav"> <picture> <source srcset="https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/chrome/images/lockup-dark-theme.svg" media="(prefers-color-scheme: dark)" class="devsite-dark-theme" alt="Chrome for Developers"> <img src="https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/chrome/images/lockup.svg" class="devsite-site-logo" alt="Chrome for Developers"> </picture> </a> <span class="devsite-product-name"> <ul class="devsite-breadcrumb-list" > <li class="devsite-breadcrumb-item "> </li> </ul> </span> </div> </div> <div class="devsite-book-nav-wrapper"> <div class="devsite-mobile-nav-top"> <ul class="devsite-nav-list"> <li class="devsite-nav-item"> <a href="/case-studies" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Tab: Get inspired" track-name="get inspired" data-category="Site-Wide Custom Events" data-label="Responsive Tab: Get inspired" track-type="globalNav" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Get inspired </span> </a> </li> <li class="devsite-nav-item"> <a href="/blog" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Tab: Blog" track-name="blog" data-category="Site-Wide Custom Events" data-label="Responsive Tab: Blog" track-type="globalNav" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Blog </span> </a> </li> <li class="devsite-nav-item"> <a href="/docs" class="devsite-nav-title gc-analytics-event devsite-nav-active" data-category="Site-Wide Custom Events" data-label="Tab: Docs" track-name="docs" data-category="Site-Wide Custom Events" data-label="Responsive Tab: Docs" track-type="globalNav" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Docs </span> </a> <ul class="devsite-nav-responsive-tabs devsite-nav-has-menu "> <li class="devsite-nav-item"> <span class="devsite-nav-title" tooltip data-category="Site-Wide Custom Events" data-label="Tab: Docs" track-name="docs" > <span class="devsite-nav-text" tooltip menu="Docs"> More </span> <span class="devsite-nav-icon material-icons" data-icon="forward" menu="Docs"> </span> </span> </li> </ul> <ul class="devsite-nav-responsive-tabs"> <li class="devsite-nav-item"> <a href="/docs/capabilities" class="devsite-nav-title gc-analytics-event devsite-nav-has-children devsite-nav-active" data-category="Site-Wide Custom Events" data-label="Tab: Capabilities" track-name="capabilities" data-category="Site-Wide Custom Events" data-label="Responsive Tab: Capabilities" track-type="globalNav" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip menu="_book"> Capabilities </span> <span class="devsite-nav-icon material-icons" data-icon="forward" menu="_book"> </span> </a> </li> <li class="devsite-nav-item"> <a href="/docs/capabilities/fugu-showcase" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Tab: Fugu showcase" track-name="fugu showcase" data-category="Site-Wide Custom Events" data-label="Responsive Tab: Fugu showcase" track-type="globalNav" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Fugu showcase </span> </a> </li> <li class="devsite-nav-item"> <a href="/docs/chromedriver" class="devsite-nav-title gc-analytics-event devsite-nav-has-children " data-category="Site-Wide Custom Events" data-label="Tab: ChromeDriver" track-name="chromedriver" data-category="Site-Wide Custom Events" data-label="Responsive Tab: ChromeDriver" track-type="globalNav" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > ChromeDriver </span> <span class="devsite-nav-icon material-icons" data-icon="forward" > </span> </a> </li> </ul> </li> <li class="devsite-nav-item"> <a href="/new" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Tab: New in Chrome" track-name="new in chrome" data-category="Site-Wide Custom Events" data-label="Responsive Tab: New in Chrome" track-type="globalNav" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > New in Chrome </span> </a> </li> </ul> </div> <div class="devsite-mobile-nav-bottom"> <ul class="devsite-nav-list" menu="_book"> <li class="devsite-nav-item"><a href="/docs/capabilities/status" class="devsite-nav-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Book nav link, pathname: /docs/capabilities/status" track-type="bookNav" track-name="click" track-metadata-eventdetail="/docs/capabilities/status" ><span class="devsite-nav-text" tooltip>Latest updates</span></a></li> <li class="devsite-nav-item"><a href="/docs/capabilities/fugu-showcase" class="devsite-nav-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Book nav link, pathname: /docs/capabilities/fugu-showcase" track-type="bookNav" track-name="click" track-metadata-eventdetail="/docs/capabilities/fugu-showcase" ><span class="devsite-nav-text" tooltip>Showcase</span></a></li> <li class="devsite-nav-item devsite-nav-heading"><div class="devsite-nav-title devsite-nav-title-no-path"> <span class="devsite-nav-text" tooltip>Hardware APIs</span> </div></li> <li class="devsite-nav-item"><a href="/docs/capabilities/hid" class="devsite-nav-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Book nav link, pathname: /docs/capabilities/hid" track-type="bookNav" track-name="click" track-metadata-eventdetail="/docs/capabilities/hid" ><span class="devsite-nav-text" tooltip>Connect to uncommon HID devices</span></a></li> <li class="devsite-nav-item"><a href="/docs/capabilities/bluetooth" class="devsite-nav-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Book nav link, pathname: /docs/capabilities/bluetooth" track-type="bookNav" track-name="click" track-metadata-eventdetail="/docs/capabilities/bluetooth" ><span class="devsite-nav-text" tooltip>Communicate with Bluetooth devices over JavaScript</span></a></li> <li class="devsite-nav-item"><a href="/docs/capabilities/serial" class="devsite-nav-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Book nav link, pathname: /docs/capabilities/serial" track-type="bookNav" track-name="click" track-metadata-eventdetail="/docs/capabilities/serial" ><span class="devsite-nav-text" tooltip>Read from and write to a serial port</span></a></li> <li class="devsite-nav-item"><a href="/docs/capabilities/usb" class="devsite-nav-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Book nav link, pathname: /docs/capabilities/usb" track-type="bookNav" track-name="click" track-metadata-eventdetail="/docs/capabilities/usb" ><span class="devsite-nav-text" tooltip>Access USB Devices on the Web</span></a></li> <li class="devsite-nav-item"><a href="/docs/capabilities/build-for-webusb" class="devsite-nav-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Book nav link, pathname: /docs/capabilities/build-for-webusb" track-type="bookNav" track-name="click" track-metadata-eventdetail="/docs/capabilities/build-for-webusb" ><span class="devsite-nav-text" tooltip>Building a device for WebUSB</span></a></li> <li class="devsite-nav-item"><a href="/docs/capabilities/nfc" class="devsite-nav-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Book nav link, pathname: /docs/capabilities/nfc" track-type="bookNav" track-name="click" track-metadata-eventdetail="/docs/capabilities/nfc" ><span class="devsite-nav-text" tooltip>Interact with NFC devices on Chrome for Android</span></a></li> <li class="devsite-nav-item devsite-nav-heading"><div class="devsite-nav-title devsite-nav-title-no-path"> <span class="devsite-nav-text" tooltip>Web APIs</span> </div></li> <li class="devsite-nav-item"><a href="/docs/capabilities/web-apis/file-system-access" class="devsite-nav-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Book nav link, pathname: /docs/capabilities/web-apis/file-system-access" track-type="bookNav" track-name="click" track-metadata-eventdetail="/docs/capabilities/web-apis/file-system-access" ><span class="devsite-nav-text" tooltip>File System Access API</span></a></li> <li class="devsite-nav-item"><a href="/docs/capabilities/web-apis/badging-api" class="devsite-nav-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Book nav link, pathname: /docs/capabilities/web-apis/badging-api" track-type="bookNav" track-name="click" track-metadata-eventdetail="/docs/capabilities/web-apis/badging-api" ><span class="devsite-nav-text" tooltip>Badging for app icons</span></a></li> <li class="devsite-nav-item"><a href="/docs/capabilities/web-apis/local-fonts" class="devsite-nav-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Book nav link, pathname: /docs/capabilities/web-apis/local-fonts" track-type="bookNav" track-name="click" track-metadata-eventdetail="/docs/capabilities/web-apis/local-fonts" ><span class="devsite-nav-text" tooltip>Advanced typography with local fonts</span></a></li> <li class="devsite-nav-item"><a href="/docs/capabilities/web-apis/window-management" class="devsite-nav-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Book nav link, pathname: /docs/capabilities/web-apis/window-management" track-type="bookNav" track-name="click" track-metadata-eventdetail="/docs/capabilities/web-apis/window-management" ><span class="devsite-nav-text" tooltip>Manage several displays with the Multi-Screen Window Placement API</span></a></li> <li class="devsite-nav-item"><a href="/blog/web-custom-formats-for-the-async-clipboard-api" class="devsite-nav-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Book nav link, pathname: /blog/web-custom-formats-for-the-async-clipboard-api" track-type="bookNav" track-name="click" track-metadata-eventdetail="/blog/web-custom-formats-for-the-async-clipboard-api" ><span class="devsite-nav-text" tooltip>Web custom formats for the Async Clipboard API</span></a></li> <li class="devsite-nav-item devsite-nav-heading"><div class="devsite-nav-title devsite-nav-title-no-path"> <span class="devsite-nav-text" tooltip>Resources</span> </div></li> <li class="devsite-nav-item devsite-nav-external"><a href="//www.chromium.org/teams/web-capabilities-fugu" class="devsite-nav-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Book nav link, pathname: //www.chromium.org/teams/web-capabilities-fugu" track-type="bookNav" track-name="click" track-metadata-eventdetail="//www.chromium.org/teams/web-capabilities-fugu" ><span class="devsite-nav-text" tooltip>Project Fugu on Chromium</span><span class="devsite-nav-icon material-icons" data-icon="external" data-title="External" aria-hidden="true"></span></a></li> <li class="devsite-nav-item devsite-nav-external"><a href="//web.dev/learn/pwa/capabilities" class="devsite-nav-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Book nav link, pathname: //web.dev/learn/pwa/capabilities" track-type="bookNav" track-name="click" track-metadata-eventdetail="//web.dev/learn/pwa/capabilities" ><span class="devsite-nav-text" tooltip>Learn PWA: Capabilities</span><span class="devsite-nav-icon material-icons" data-icon="external" data-title="External" aria-hidden="true"></span></a></li> <li class="devsite-nav-item devsite-nav-external"><a href="//developer.mozilla.org/docs/Web/API" class="devsite-nav-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Book nav link, pathname: //developer.mozilla.org/docs/Web/API" track-type="bookNav" track-name="click" track-metadata-eventdetail="//developer.mozilla.org/docs/Web/API" ><span class="devsite-nav-text" tooltip>MDN Web APIs</span><span class="devsite-nav-icon material-icons" data-icon="external" data-title="External" aria-hidden="true"></span></a></li> </ul> <ul class="devsite-nav-list" menu="Docs" aria-label="Side menu" hidden> <li class="devsite-nav-item devsite-nav-heading"> <span class="devsite-nav-title" tooltip > <span class="devsite-nav-text" tooltip > Build with Chrome </span> </span> </li> <li class="devsite-nav-item"> <a href="/docs/web-platform" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Web Platform" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Web Platform </span> </a> </li> <li class="devsite-nav-item"> <a href="/docs/capabilities" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Capabilities" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Capabilities </span> </a> </li> <li class="devsite-nav-item"> <a href="/docs/chromedriver" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: ChromeDriver" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > ChromeDriver </span> </a> </li> <li class="devsite-nav-item"> <a href="/docs/extensions" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Extensions" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Extensions </span> </a> </li> <li class="devsite-nav-item"> <a href="/docs/webstore" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Chrome Web Store" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Chrome Web Store </span> </a> </li> <li class="devsite-nav-item"> <a href="/docs/chromium" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Chromium" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Chromium </span> </a> </li> <li class="devsite-nav-item"> <a href="/docs/aurora" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Aurora" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Aurora </span> </a> </li> <li class="devsite-nav-item"> <a href="/docs/android" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Web on Android" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Web on Android </span> </a> </li> <li class="devsite-nav-item"> <a href="https://developer.chrome.com/origintrials/" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Origin trials" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Origin trials </span> </a> </li> <li class="devsite-nav-item"> <a href="/release-notes" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Release notes" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Release notes </span> </a> </li> <li class="devsite-nav-item devsite-nav-heading"> <span class="devsite-nav-title" tooltip > <span class="devsite-nav-text" tooltip > Productivity </span> </span> </li> <li class="devsite-nav-item"> <a href="/docs/devtools" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: DevTools" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > DevTools </span> </a> </li> <li class="devsite-nav-item"> <a href="/docs/lighthouse" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Lighthouse" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Lighthouse </span> </a> </li> <li class="devsite-nav-item"> <a href="/docs/crux" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Chrome UX Report" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Chrome UX Report </span> </a> </li> <li class="devsite-nav-item"> <a href="/docs/accessibility" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Accessibility" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Accessibility </span> </a> </li> <li class="devsite-nav-item"> <a href="/docs/workbox" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Workbox" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Workbox </span> </a> </li> <li class="devsite-nav-item"> <a href="/docs/puppeteer" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Puppeteer" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Puppeteer </span> </a> </li> <li class="devsite-nav-item devsite-nav-heading"> <span class="devsite-nav-title" tooltip > <span class="devsite-nav-text" tooltip > Experience </span> </span> </li> <li class="devsite-nav-item"> <a href="/docs/ai" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: AI" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > AI </span> </a> </li> <li class="devsite-nav-item"> <a href="/docs/performance" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Performance" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Performance </span> </a> </li> <li class="devsite-nav-item"> <a href="/docs/css-ui" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: CSS and UI" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > CSS and UI </span> </a> </li> <li class="devsite-nav-item"> <a href="/docs/identity" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Identity" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Identity </span> </a> </li> <li class="devsite-nav-item"> <a href="/docs/payments" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Payments" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Payments </span> </a> </li> <li class="devsite-nav-item"> <a href="/docs/privacy-security" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Privacy and security" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Privacy and security </span> </a> </li> <li class="devsite-nav-item devsite-nav-heading"> <span class="devsite-nav-title" tooltip > <span class="devsite-nav-text" tooltip > Resources </span> </span> </li> <li class="devsite-nav-item"> <a href="/docs" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: All documentation" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > All documentation </span> </a> </li> <li class="devsite-nav-item"> <a href="https://web.dev/baseline" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Baseline" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Baseline </span> </a> </li> <li class="devsite-nav-item"> <a href="https://web.dev" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: web.dev" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > web.dev </span> </a> </li> </ul> </div> </div> </nav> </devsite-book-nav> <section id="gc-wrapper"> <main role="main" class="devsite-main-content" has-book-nav has-sidebar > <div class="devsite-sidebar"> <div class="devsite-sidebar-content"> <devsite-toc class="devsite-nav" role="navigation" aria-label="On this page" depth="2" scrollbars ></devsite-toc> <devsite-recommendations-sidebar class="nocontent devsite-nav"> </devsite-recommendations-sidebar> </div> </div> <devsite-content> <article class="devsite-article"> <div class="devsite-article-meta nocontent" role="navigation"> <ul class="devsite-breadcrumb-list" aria-label="Breadcrumb"> <li class="devsite-breadcrumb-item "> <a href="https://developer.chrome.com/" class="devsite-breadcrumb-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Breadcrumbs" data-value="1" track-type="globalNav" track-name="breadcrumb" track-metadata-position="1" track-metadata-eventdetail="" > Home </a> </li> <li class="devsite-breadcrumb-item "> <div class="devsite-breadcrumb-guillemet material-icons" aria-hidden="true"></div> <a href="https://developer.chrome.com/docs" class="devsite-breadcrumb-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Breadcrumbs" data-value="2" track-type="globalNav" track-name="breadcrumb" track-metadata-position="2" track-metadata-eventdetail="Docs" > Docs </a> </li> <li class="devsite-breadcrumb-item "> <div class="devsite-breadcrumb-guillemet material-icons" aria-hidden="true"></div> <a href="https://developer.chrome.com/docs/capabilities" class="devsite-breadcrumb-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Breadcrumbs" data-value="3" track-type="globalNav" track-name="breadcrumb" track-metadata-position="3" track-metadata-eventdetail="Capabilities" > Capabilities </a> </li> </ul> <devsite-thumb-rating position="header"> </devsite-thumb-rating> </div> <h1 class="devsite-page-title" tabindex="-1"> Access USB Devices on the Web </h1> <devsite-feature-tooltip ack-key="AckCollectionsBookmarkTooltipDismiss" analytics-category="Site-Wide Custom Events" analytics-action-show="Callout Profile displayed" analytics-action-close="Callout Profile dismissed" analytics-label="Create Collection Callout" class="devsite-page-bookmark-tooltip nocontent" dismiss-button="true" id="devsite-collections-dropdown" dismiss-button-text="Dismiss" close-button-text="Got it"> <devsite-bookmark></devsite-bookmark> <span slot="popout-heading"> Stay organized with collections </span> <span slot="popout-contents"> Save and categorize content based on your preferences. </span> </devsite-feature-tooltip> <div class="devsite-page-title-meta"><devsite-view-release-notes></devsite-view-release-notes></div> <devsite-toc class="devsite-nav" depth="2" devsite-toc-embedded > </devsite-toc> <div class="devsite-article-body clearfix "> <p>The WebUSB API makes USB safer and easier to use by bringing it to the Web.</p> <p><style> .wd-authors { --avatar-size: 65px; display: flex; gap: 2em; } .wd-author { display: flex; flex-wrap: wrap; gap: 1em; line-height: calc(var(--avatar-size) / 2); } .wd-author img { border-radius: 50%; height: var(--avatar-size, 65px); width: var(--avatar-size, 65px); } .dcc-authors { --avatar-size: 65px; display: flex; gap: 2em; } .dcc-author { display: flex; flex-wrap: wrap; gap: 1em; line-height: calc(var(--avatar-size) / 2); } .dcc-author img { border-radius: 50%; height: var(--avatar-size, 65px); width: var(--avatar-size, 65px); } .dcc-author__links a { margin-inline-end: 6px; } .dcc-author__links a:last-of-type { margin-inline-end: 0; } </style> <div class="dcc-authors" translate="no"> <div class="dcc-author"> <img class="devsite-landing-row-item-icon" alt="François Beaufort" src="https://web.dev/images/authors/beaufortfrancois.jpg" decoding="async" height="64" loading="lazy" width="64"> <div> <span> François Beaufort </span> <div class="dcc-author__links"> <a href="https://github.com/beaufortfrancois" aria-label="François Beaufort on GitHub" rel="me"> <svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 32.6 31.8"> <title>GitHub</title> <path d="M16.3 0C7.3 0 0 7.3 0 16.3c0 7.2 4.7 13.3 11.1 15.5.8.1 1.1-.4 1.1-.8v-2.8c-4.5 1-5.5-2.2-5.5-2.2-.7-1.9-1.8-2.4-1.8-2.4-1.5-1 .1-1 .1-1 1.6.1 2.5 1.7 2.5 1.7 1.5 2.5 3.8 1.8 4.7 1.4.1-1.1.6-1.8 1-2.2-3.6-.4-7.4-1.8-7.4-8.1 0-1.8.6-3.2 1.7-4.4-.1-.3-.7-2 .2-4.2 0 0 1.4-.4 4.5 1.7 1.3-.4 2.7-.5 4.1-.5 1.4 0 2.8.2 4.1.5 3.1-2.1 4.5-1.7 4.5-1.7.9 2.2.3 3.9.2 4.3 1 1.1 1.7 2.6 1.7 4.4 0 6.3-3.8 7.6-7.4 8 .6.5 1.1 1.5 1.1 3V31c0 .4.3.9 1.1.8 6.5-2.2 11.1-8.3 11.1-15.5C32.6 7.3 25.3 0 16.3 0z" fill-rule="evenodd" clip-rule="evenodd" fill="currentColor" /> </svg></a> </div> </div> </div> </div></p> <p>If I said plainly and simply &quot;USB&quot;, there is a good chance that you will immediately think of keyboards, mice, audio, video, and storage devices. You&#39;re right, but you&#39;ll find other kinds of Universal Serial Bus (USB) devices out there.</p> <p>These non-standardized USB devices require hardware vendors to write platform-specific drivers and SDKs in order for you (the developer) to take advantage of them. Sadly this platform-specific code has historically prevented these devices from being used by the Web. And that&#39;s one of the reasons the WebUSB API has been created: to provide a way to expose USB device services to the Web. With this API, hardware manufacturers will be able to build cross-platform JavaScript SDKs for their devices.</p> <p>But most importantly this will <strong>make USB safer and easier to use by bringing it to the Web</strong>.</p> <p>Let&#39;s see the behavior you could expect with the WebUSB API:</p> <ol> <li>Buy a USB device.</li> <li>Plug it into your computer. A notification appears right away, with the right website to go to for this device.</li> <li>Click the notification. The website is there and ready to use!</li> <li>Click to connect and a USB device chooser shows up in Chrome where you can pick your device.</li> </ol> <p>Tada!</p> <p>What would this procedure be like without the WebUSB API?</p> <ol> <li>Install a platform-specific application.</li> <li>If it&#39;s even supported on my operating system, verify that I&#39;ve downloaded the right thing.</li> <li>Install the thing. If you&#39;re lucky, you&#39;ll get no scary OS prompts or popups warning you about installing drivers/applications from the internet. If you&#39;re unlucky, the installed drivers or applications malfunction and harm your computer. (Remember, the web is built to <a href="https://www.youtube.com/watch?v=29e0CtgXZSI">contain malfunctioning websites</a>).</li> <li>If you only use the feature once, the code stays on your computer until you think to remove it. (On the Web, the space for unused is eventually reclaimed.)</li> </ol> <h2 id="before_i_start" data-text="Before I start" tabindex="-1">Before I start</h2> <p>This article assumes you have some basic knowledge of how USB works. If not, I recommend reading <a href="http://www.beyondlogic.org/usbnutshell">USB in a NutShell</a>. For background information about USB, check out the <a href="https://www.usb.org/">official USB specifications</a>.</p> <p>The <a href="https://wicg.github.io/webusb/">WebUSB API</a> is available in Chrome 61.</p> <h3 id="available_for_origin_trials" data-text="Available for origin trials" tabindex="-1">Available for origin trials</h3> <p>In order to get as much feedback as possible from developers using the WebUSB API in the field, we&#39;ve previously added this feature in Chrome 54 and Chrome 57 as an <a href="https://github.com/GoogleChrome/OriginTrials/blob/gh-pages/developer-guide.md">origin trial</a>.</p> <p>The latest trial has successfully ended in September 2017.</p> <h2 id="privacy_and_security" data-text="Privacy and security" tabindex="-1">Privacy and security</h2> <h3 id="https_only" data-text="HTTPS only" tabindex="-1">HTTPS only</h3> <p>Because of this feature&#39;s power, it only works on <a href="https://w3c.github.io/webappsec/specs/powerfulfeatures/#intro">secure contexts</a>. This means you&#39;ll need to build with <a href="https://en.wikipedia.org/wiki/Transport_Layer_Security">TLS</a> in mind.</p> <h3 id="user_gesture_required" data-text="User gesture required" tabindex="-1">User gesture required</h3> <p>As a security precaution, <code translate="no" dir="ltr">navigator.usb.requestDevice()</code> may only be called through a user gesture such as a touch or mouse click.</p> <h3 id="permissions_policy" data-text="Permissions Policy" tabindex="-1">Permissions Policy</h3> <p>A <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Permissions_Policy">Permissions Policy</a> is a mechanism that allows developers to selectively enable and disable various browser features and APIs. It can be defined via an HTTP header and/or an iframe &quot;allow&quot; attribute.</p> <p>You can define a Permissions Policy that controls whether the <code translate="no" dir="ltr">usb</code> attribute is exposed on the Navigator object, or in other words if you allow WebUSB.</p> <p>Below is an example of a header policy where WebUSB is not allowed:</p> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="Bash Session"><code translate="no" dir="ltr"><span class="devsite-syntax-go">Feature-Policy: fullscreen "*"; usb "none"; payment "self" https://payment.example.com</span> </code></pre></devsite-code> <p>Below is another example of a container policy where USB is allowed:</p> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="HTML"><code translate="no" dir="ltr">&lt;iframe allowpaymentrequest allow="usb; fullscreen"&gt;&lt;/iframe&gt; </code></pre></devsite-code> <h2 id="lets_start_coding" data-text="Let's start coding" tabindex="-1">Let's start coding</h2> <p>The WebUSB API relies heavily on JavaScript <a href="https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise">Promises</a>. If you&#39;re not familiar with them, check out this great <a href="https://web.dev/promises">Promises tutorial</a>. One more thing, <code translate="no" dir="ltr">() =&gt; {}</code> are simply ECMAScript 2015 <a href="https://developer.mozilla.org/docs/Web/JavaScript/Reference/Functions/Arrow_functions">Arrow functions</a>.</p> <h3 id="get_access_to_usb_devices" data-text="Get access to USB devices" tabindex="-1">Get access to USB devices</h3> <p>You can either prompt the user to select a single connected USB device using <code translate="no" dir="ltr">navigator.usb.requestDevice()</code> or call <code translate="no" dir="ltr">navigator.usb.getDevices()</code> to get a list of all connected USB devices the website has been granted access to.</p> <p>The <code translate="no" dir="ltr">navigator.usb.requestDevice()</code> function takes a mandatory JavaScript object that defines <code translate="no" dir="ltr">filters</code>. These filters are used to match any USB device with the given vendor (<code translate="no" dir="ltr">vendorId</code>) and, optionally, product (<code translate="no" dir="ltr">productId</code>) identifiers. The <code translate="no" dir="ltr">classCode</code>, <code translate="no" dir="ltr">protocolCode</code>, <code translate="no" dir="ltr">serialNumber</code>, and <code translate="no" dir="ltr">subclassCode</code> keys can also be defined there as well.</p> <figure> <img src="/static/docs/capabilities/usb/image/screenshot-the-usb-devic-25e524dd3ed2b.png" alt="Screenshot of the USB device user prompt in Chrome" width="800" height="533" srcset="https://developer.chrome.com/static/docs/capabilities/usb/image/screenshot-the-usb-devic-25e524dd3ed2b_36.png 36w,https://developer.chrome.com/static/docs/capabilities/usb/image/screenshot-the-usb-devic-25e524dd3ed2b_48.png 48w,https://developer.chrome.com/static/docs/capabilities/usb/image/screenshot-the-usb-devic-25e524dd3ed2b_72.png 72w,https://developer.chrome.com/static/docs/capabilities/usb/image/screenshot-the-usb-devic-25e524dd3ed2b_96.png 96w,https://developer.chrome.com/static/docs/capabilities/usb/image/screenshot-the-usb-devic-25e524dd3ed2b_480.png 480w,https://developer.chrome.com/static/docs/capabilities/usb/image/screenshot-the-usb-devic-25e524dd3ed2b_720.png 720w,https://developer.chrome.com/static/docs/capabilities/usb/image/screenshot-the-usb-devic-25e524dd3ed2b_856.png 856w,https://developer.chrome.com/static/docs/capabilities/usb/image/screenshot-the-usb-devic-25e524dd3ed2b_960.png 960w,https://developer.chrome.com/static/docs/capabilities/usb/image/screenshot-the-usb-devic-25e524dd3ed2b_1440.png 1440w,https://developer.chrome.com/static/docs/capabilities/usb/image/screenshot-the-usb-devic-25e524dd3ed2b_1920.png 1920w,https://developer.chrome.com/static/docs/capabilities/usb/image/screenshot-the-usb-devic-25e524dd3ed2b_2880.png 2880w" sizes="(max-width: 840px) 100vw, 856px"> <figcaption class="dcc-caption">USB device user prompt.</figcaption> </figure> <p>For instance, here&#39;s how to get access to a connected Arduino device configured to allow the origin.</p> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="JavaScript"><code translate="no" dir="ltr"><span class="devsite-syntax-nx">navigator</span><span class="devsite-syntax-p">.</span><span class="devsite-syntax-nx">usb</span><span class="devsite-syntax-p">.</span><span class="devsite-syntax-nx">requestDevice</span><span class="devsite-syntax-p">({</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nx">filters</span><span class="devsite-syntax-o">:</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">[{</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nx">vendorId</span><span class="devsite-syntax-o">:</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-mh">0x2341</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">}]</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">})</span> <span class="devsite-syntax-p">.</span><span class="devsite-syntax-nx">then</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-nx">device</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-o">=</span>&gt;<span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">{</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-nx">console</span><span class="devsite-syntax-p">.</span><span class="devsite-syntax-nx">log</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-nx">device</span><span class="devsite-syntax-p">.</span><span class="devsite-syntax-nx">productName</span><span class="devsite-syntax-p">);</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-c1">// "Arduino Micro"</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-nx">console</span><span class="devsite-syntax-p">.</span><span class="devsite-syntax-nx">log</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-nx">device</span><span class="devsite-syntax-p">.</span><span class="devsite-syntax-nx">manufacturerName</span><span class="devsite-syntax-p">);</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-c1">// "Arduino LLC"</span> <span class="devsite-syntax-p">})</span> <span class="devsite-syntax-p">.</span><span class="devsite-syntax-k">catch</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-nx">error</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-o">=</span>&gt;<span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">{</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nx">console</span><span class="devsite-syntax-p">.</span><span class="devsite-syntax-nx">error</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-nx">error</span><span class="devsite-syntax-p">);</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">});</span> </code></pre></devsite-code> <p>Before you ask, I didn&#39;t magically come up with this <code translate="no" dir="ltr">0x2341</code> hexadecimal number. I simply searched for the word &quot;Arduino&quot; in this <a href="http://www.linux-usb.org/usb.ids">List of USB ID&#39;s</a>.</p> <p>The USB <code translate="no" dir="ltr">device</code> returned in the fulfilled promise above has some basic, yet important information about the device such as the supported USB version, maximum packet size, vendor, and product IDs, the number of possible configurations the device can have. Basically it contains all fields in the <a href="http://www.beyondlogic.org/usbnutshell/usb5.shtml#DeviceDescriptors">device USB Descriptor</a>.</p> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="JavaScript"><code translate="no" dir="ltr"><span class="devsite-syntax-c1">// Get all connected USB devices the website has been granted access to.</span> <span class="devsite-syntax-nx">navigator</span><span class="devsite-syntax-p">.</span><span class="devsite-syntax-nx">usb</span><span class="devsite-syntax-p">.</span><span class="devsite-syntax-nx">getDevices</span><span class="devsite-syntax-p">().</span><span class="devsite-syntax-nx">then</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-nx">devices</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-o">=</span>&gt;<span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">{</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-nx">devices</span><span class="devsite-syntax-p">.</span><span class="devsite-syntax-nx">forEach</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-nx">device</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-o">=</span>&gt;<span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">{</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-nx">console</span><span class="devsite-syntax-p">.</span><span class="devsite-syntax-nx">log</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-nx">device</span><span class="devsite-syntax-p">.</span><span class="devsite-syntax-nx">productName</span><span class="devsite-syntax-p">);</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-c1">// "Arduino Micro"</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-nx">console</span><span class="devsite-syntax-p">.</span><span class="devsite-syntax-nx">log</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-nx">device</span><span class="devsite-syntax-p">.</span><span class="devsite-syntax-nx">manufacturerName</span><span class="devsite-syntax-p">);</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-c1">// "Arduino LLC"</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">});</span> <span class="devsite-syntax-p">})</span> </code></pre></devsite-code> <p>By the way, if a USB device announces its <a href="https://wicg.github.io/webusb/#webusb-platform-capability-descriptor">support for WebUSB</a>, as well as defining a landing page URL, Chrome will show a persistent notification when the USB device is plugged in. Clicking this notification will open the landing page.</p> <figure> <img src="/static/docs/capabilities/usb/image/screenshot-the-webusb-no-3e19033df3385.png" alt="Screenshot of the WebUSB notification in Chrome" width="800" height="450" srcset="https://developer.chrome.com/static/docs/capabilities/usb/image/screenshot-the-webusb-no-3e19033df3385_36.png 36w,https://developer.chrome.com/static/docs/capabilities/usb/image/screenshot-the-webusb-no-3e19033df3385_48.png 48w,https://developer.chrome.com/static/docs/capabilities/usb/image/screenshot-the-webusb-no-3e19033df3385_72.png 72w,https://developer.chrome.com/static/docs/capabilities/usb/image/screenshot-the-webusb-no-3e19033df3385_96.png 96w,https://developer.chrome.com/static/docs/capabilities/usb/image/screenshot-the-webusb-no-3e19033df3385_480.png 480w,https://developer.chrome.com/static/docs/capabilities/usb/image/screenshot-the-webusb-no-3e19033df3385_720.png 720w,https://developer.chrome.com/static/docs/capabilities/usb/image/screenshot-the-webusb-no-3e19033df3385_856.png 856w,https://developer.chrome.com/static/docs/capabilities/usb/image/screenshot-the-webusb-no-3e19033df3385_960.png 960w,https://developer.chrome.com/static/docs/capabilities/usb/image/screenshot-the-webusb-no-3e19033df3385_1440.png 1440w,https://developer.chrome.com/static/docs/capabilities/usb/image/screenshot-the-webusb-no-3e19033df3385_1920.png 1920w,https://developer.chrome.com/static/docs/capabilities/usb/image/screenshot-the-webusb-no-3e19033df3385_2880.png 2880w" sizes="(max-width: 840px) 100vw, 856px"> <figcaption class="dcc-caption">WebUSB notification.</figcaption> </figure> <h3 id="talk_to_an_arduino_usb_board" data-text="Talk to an Arduino USB board" tabindex="-1">Talk to an Arduino USB board</h3> <p>Okay, now let&#39;s see how easy it is to communicate from a WebUSB compatible Arduino board over the USB port. Check out instructions at <a href="https://github.com/webusb/arduino">https://github.com/webusb/arduino</a> to WebUSB-enable your <a href="http://www.arduino.cc/en/Tutorial/Sketch">sketches</a>.</p> <p>Don&#39;t worry, I&#39;ll cover all the WebUSB device methods mentioned below later in this article.</p> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="JavaScript"><code translate="no" dir="ltr"><span class="devsite-syntax-kd">let</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nx">device</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-nx">navigator</span><span class="devsite-syntax-p">.</span><span class="devsite-syntax-nx">usb</span><span class="devsite-syntax-p">.</span><span class="devsite-syntax-nx">requestDevice</span><span class="devsite-syntax-p">({</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nx">filters</span><span class="devsite-syntax-o">:</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">[{</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nx">vendorId</span><span class="devsite-syntax-o">:</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-mh">0x2341</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">}]</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">})</span> <span class="devsite-syntax-p">.</span><span class="devsite-syntax-nx">then</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-nx">selectedDevice</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-o">=</span>&gt;<span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">{</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-nx">device</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-o">=</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nx">selectedDevice</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-k">return</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nx">device</span><span class="devsite-syntax-p">.</span><span class="devsite-syntax-nx">open</span><span class="devsite-syntax-p">();</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-c1">// Begin a session.</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">})</span> <span class="devsite-syntax-p">.</span><span class="devsite-syntax-nx">then</span><span class="devsite-syntax-p">(()</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-o">=</span>&gt;<span class="devsite-syntax-w"> </span><span class="devsite-syntax-nx">device</span><span class="devsite-syntax-p">.</span><span class="devsite-syntax-nx">selectConfiguration</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-mf">1</span><span class="devsite-syntax-p">))</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-c1">// Select configuration #1 for the device.</span> <span class="devsite-syntax-p">.</span><span class="devsite-syntax-nx">then</span><span class="devsite-syntax-p">(()</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-o">=</span>&gt;<span class="devsite-syntax-w"> </span><span class="devsite-syntax-nx">device</span><span class="devsite-syntax-p">.</span><span class="devsite-syntax-nx">claimInterface</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-mf">2</span><span class="devsite-syntax-p">))</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-c1">// Request exclusive control over interface #2.</span> <span class="devsite-syntax-p">.</span><span class="devsite-syntax-nx">then</span><span class="devsite-syntax-p">(()</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-o">=</span>&gt;<span class="devsite-syntax-w"> </span><span class="devsite-syntax-nx">device</span><span class="devsite-syntax-p">.</span><span class="devsite-syntax-nx">controlTransferOut</span><span class="devsite-syntax-p">({</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-nx">requestType</span><span class="devsite-syntax-o">:</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-s1">'class'</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-nx">recipient</span><span class="devsite-syntax-o">:</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-s1">'interface'</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-nx">request</span><span class="devsite-syntax-o">:</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-mh">0x22</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-nx">value</span><span class="devsite-syntax-o">:</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-mh">0x01</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-nx">index</span><span class="devsite-syntax-o">:</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-mh">0x02</span><span class="devsite-syntax-p">}))</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-c1">// Ready to receive data</span> <span class="devsite-syntax-p">.</span><span class="devsite-syntax-nx">then</span><span class="devsite-syntax-p">(()</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-o">=</span>&gt;<span class="devsite-syntax-w"> </span><span class="devsite-syntax-nx">device</span><span class="devsite-syntax-p">.</span><span class="devsite-syntax-nx">transferIn</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-mf">5</span><span class="devsite-syntax-p">,</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-mf">64</span><span class="devsite-syntax-p">))</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-c1">// Waiting for 64 bytes of data from endpoint #5.</span> <span class="devsite-syntax-p">.</span><span class="devsite-syntax-nx">then</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-nx">result</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-o">=</span>&gt;<span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">{</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-kd">const</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nx">decoder</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-o">=</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-ow">new</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nx">TextDecoder</span><span class="devsite-syntax-p">();</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-nx">console</span><span class="devsite-syntax-p">.</span><span class="devsite-syntax-nx">log</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-s1">'Received: '</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-o">+</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nx">decoder</span><span class="devsite-syntax-p">.</span><span class="devsite-syntax-nx">decode</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-nx">result</span><span class="devsite-syntax-p">.</span><span class="devsite-syntax-nx">data</span><span class="devsite-syntax-p">));</span> <span class="devsite-syntax-p">})</span> <span class="devsite-syntax-p">.</span><span class="devsite-syntax-k">catch</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-nx">error</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-o">=</span>&gt;<span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">{</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nx">console</span><span class="devsite-syntax-p">.</span><span class="devsite-syntax-nx">error</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-nx">error</span><span class="devsite-syntax-p">);</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">});</span> </code></pre></devsite-code> <p>Keep in mind that the WebUSB library I&#39;m using is just implementing one example protocol (based on the standard USB serial protocol) and that manufacturers can create any set and types of endpoints they wish. Control transfers are especially nice for small configuration commands as they get bus priority and have a well defined structure.</p> <p>And here&#39;s the sketch that has been uploaded to the Arduino board.</p> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="Arduino"><code translate="no" dir="ltr"><span class="devsite-syntax-c1">// Third-party WebUSB Arduino library</span> <span class="devsite-syntax-cp">#include &lt;WebUSB.h&gt;</span> <span class="devsite-syntax-n">WebUSB</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-n">WebUSBSerial</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-mi">1</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-cm">/* https:// */</span><span class="devsite-syntax-p">,</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-s">"webusb.github.io/arduino/demos"</span><span class="devsite-syntax-p">);</span> <span class="devsite-syntax-cp">#define Serial WebUSBSerial</span> <span class="devsite-syntax-kr">void</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nb">setup</span><span class="devsite-syntax-p">()</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">{</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-nf">Serial</span><span class="devsite-syntax-p">.</span><span class="devsite-syntax-nf">begin</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-mi">9600</span><span class="devsite-syntax-p">);</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-k">while</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-o">!</span><span class="devsite-syntax-nf">Serial</span><span class="devsite-syntax-p">)</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">{</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">;</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-c1">// Wait for serial port to connect.</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">}</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-nf">Serial</span><span class="devsite-syntax-p">.</span><span class="devsite-syntax-nf">write</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-s">"WebUSB FTW!"</span><span class="devsite-syntax-p">);</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-nf">Serial</span><span class="devsite-syntax-p">.</span><span class="devsite-syntax-nf">flush</span><span class="devsite-syntax-p">();</span> <span class="devsite-syntax-p">}</span> <span class="devsite-syntax-kr">void</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nb">loop</span><span class="devsite-syntax-p">()</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">{</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-c1">// Nothing here for now.</span> <span class="devsite-syntax-p">}</span> </code></pre></devsite-code> <p>The third-party <a href="https://github.com/webusb/arduino/tree/gh-pages/library/WebUSB">WebUSB Arduino library</a> used in the sample code above does basically two things:</p> <ul> <li>The device acts as a WebUSB device enabling Chrome to read the <a href="https://wicg.github.io/webusb/#webusb-platform-capability-descriptor">landing page URL</a>.</li> <li>It exposes a WebUSB Serial API that you may use to override the default one.</li> </ul> <p>Look at the JavaScript code again. Once I get the <code translate="no" dir="ltr">device</code> picked by the user, <code translate="no" dir="ltr">device.open()</code> runs all platform-specific steps to start a session with the USB device. Then, I have to select an available USB Configuration with <code translate="no" dir="ltr">device.selectConfiguration()</code>. Remember that a configuration specifies how the device is powered, its maximum power consumption and its number of interfaces. Speaking of interfaces, I also need to request exclusive access with <code translate="no" dir="ltr">device.claimInterface()</code> since data can only be transferred to an interface or associated endpoints when the interface is claimed. Finally calling <code translate="no" dir="ltr">device.controlTransferOut()</code> is needed to set up the Arduino device with the appropriate commands to communicate through the WebUSB Serial API.</p> <p>From there, <code translate="no" dir="ltr">device.transferIn()</code> performs a bulk transfer onto the device to inform it that the host is ready to receive bulk data. Then, the promise is fulfilled with a <code translate="no" dir="ltr">result</code> object containing a <a href="https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/DataView">DataView</a> <code translate="no" dir="ltr">data</code> that has to be parsed appropriately.</p> <p>If you&#39;re familiar with USB, all of this should look pretty familiar.</p> <h3 id="i_want_more" data-text="I want more" tabindex="-1">I want more</h3> <p>The WebUSB API lets you interact with the all USB transfer/endpoint types:</p> <ul> <li>CONTROL transfers, used to send or receive configuration or command parameters to a USB device, are handled with <code translate="no" dir="ltr">controlTransferIn(setup, length)</code> and <code translate="no" dir="ltr">controlTransferOut(setup, data)</code>.</li> <li>INTERRUPT transfers, used for a small amount of time sensitive data, are handled with the same methods as BULK transfers with <code translate="no" dir="ltr">transferIn(endpointNumber, length)</code> and <code translate="no" dir="ltr">transferOut(endpointNumber, data)</code>.</li> <li>ISOCHRONOUS transfers, used for streams of data like video and sound, are handled with <code translate="no" dir="ltr">isochronousTransferIn(endpointNumber, packetLengths)</code> and <code translate="no" dir="ltr">isochronousTransferOut(endpointNumber, data, packetLengths)</code>.</li> <li>BULK transfers, used to transfer a large amount of non-time-sensitive data in a reliable way, are handled with <code translate="no" dir="ltr">transferIn(endpointNumber, length)</code> and <code translate="no" dir="ltr">transferOut(endpointNumber, data)</code>.</li> </ul> <p>You may also want to have a look at Mike Tsao&#39;s <a href="https://github.com/sowbug/weblight">WebLight project</a> which provides a ground-up example of building a USB-controlled LED device designed for the WebUSB API (not using an Arduino here). You&#39;ll find hardware, software, and firmware.</p> <h3 id="revoke-access" data-text="Revoke access to a USB device" tabindex="-1">Revoke access to a USB device</h3> <p>The website can clean up permissions to access a USB device it no longer needs by calling <code translate="no" dir="ltr">forget()</code> on the <code translate="no" dir="ltr">USBDevice</code> instance. For example, for an educational web application used on a shared computer with many devices, a large number of accumulated user-generated permissions creates a poor user experience.</p> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="JavaScript"><code translate="no" dir="ltr"><span class="devsite-syntax-c1">// Voluntarily revoke access to this USB device.</span> <span class="devsite-syntax-k">await</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nx">device</span><span class="devsite-syntax-p">.</span><span class="devsite-syntax-nx">forget</span><span class="devsite-syntax-p">();</span> </code></pre></devsite-code> <p>As <code translate="no" dir="ltr">forget()</code> is available in Chrome 101 or later, check if this feature is supported with the following:</p> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="JavaScript"><code translate="no" dir="ltr"><span class="devsite-syntax-k">if</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-s2">"usb"</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-ow">in</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nx">navigator</span><span class="devsite-syntax-w"> &amp;&amp; </span><span class="devsite-syntax-s2">"forget"</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-ow">in</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nx">USBDevice</span><span class="devsite-syntax-p">.</span><span class="devsite-syntax-nx">prototype</span><span class="devsite-syntax-p">)</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">{</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-c1">// forget() is supported.</span> <span class="devsite-syntax-p">}</span> </code></pre></devsite-code> <h3 id="limits_on_transfer_size" data-text="Limits on transfer size" tabindex="-1">Limits on transfer size</h3> <p>Some operating systems impose limits on how much data can be part of pending USB transactions. Splitting your data into smaller transactions and only submitting a few at a time helps avoid those limitations. It also reduces the amount of memory used and allows your application to report progress as the transfers complete.</p> <p>Because multiple transfers submitted to an endpoint always execute in order, it is possible to improve throughput by submitting multiple queued chunks to avoid latency between USB transfers. Every time a chunk is fully transmitted it will notify your code that it should provide more data as documented in the helper function example below.</p> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="JavaScript"><code translate="no" dir="ltr"><span class="devsite-syntax-kd">const</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nx">BULK_TRANSFER_SIZE</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-o">=</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-mf">16</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-o">*</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-mf">1024</span><span class="devsite-syntax-p">;</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-c1">// 16KB</span> <span class="devsite-syntax-kd">const</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nx">MAX_NUMBER_TRANSFERS</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-o">=</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-mf">3</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-k">async</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-kd">function</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nx">sendRawPayload</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-nx">device</span><span class="devsite-syntax-p">,</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nx">endpointNumber</span><span class="devsite-syntax-p">,</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nx">data</span><span class="devsite-syntax-p">)</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">{</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-kd">let</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nx">i</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-o">=</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-mf">0</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-kd">let</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nx">pendingTransfers</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-o">=</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">[];</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-kd">let</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nx">remainingBytes</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-o">=</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nx">data</span><span class="devsite-syntax-p">.</span><span class="devsite-syntax-nx">byteLength</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-k">while</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-nx">remainingBytes</span><span class="devsite-syntax-w"> &gt; </span><span class="devsite-syntax-mf">0</span><span class="devsite-syntax-p">)</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">{</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-kd">const</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nx">chunk</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-o">=</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nx">data</span><span class="devsite-syntax-p">.</span><span class="devsite-syntax-nx">subarray</span><span class="devsite-syntax-p">(</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-nx">i</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-o">*</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nx">BULK_TRANSFER_SIZE</span><span class="devsite-syntax-p">,</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-nx">i</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-o">+</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-mf">1</span><span class="devsite-syntax-p">)</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-o">*</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nx">BULK_TRANSFER_SIZE</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">);</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-c1">// If we've reached max number of transfers, let's wait.</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-k">if</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-nx">pendingTransfers</span><span class="devsite-syntax-p">.</span><span class="devsite-syntax-nx">length</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-o">==</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nx">MAX_NUMBER_TRANSFERS</span><span class="devsite-syntax-p">)</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">{</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-k">await</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nx">pendingTransfers</span><span class="devsite-syntax-p">.</span><span class="devsite-syntax-nx">shift</span><span class="devsite-syntax-p">();</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">}</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-c1">// Submit transfers that will be executed in order.</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-nx">pendingTransfers</span><span class="devsite-syntax-p">.</span><span class="devsite-syntax-nx">push</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-nx">device</span><span class="devsite-syntax-p">.</span><span class="devsite-syntax-nx">transferOut</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-nx">endpointNumber</span><span class="devsite-syntax-p">,</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nx">chunk</span><span class="devsite-syntax-p">));</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-nx">remainingBytes</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-o">-=</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nx">chunk</span><span class="devsite-syntax-p">.</span><span class="devsite-syntax-nx">byteLength</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-nx">i</span><span class="devsite-syntax-o">++</span><span class="devsite-syntax-p">;</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-p">}</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-c1">// And wait for last remaining transfers to complete.</span> <span class="devsite-syntax-w"> </span><span class="devsite-syntax-k">await</span><span class="devsite-syntax-w"> </span><span class="devsite-syntax-nb">Promise</span><span class="devsite-syntax-p">.</span><span class="devsite-syntax-nx">all</span><span class="devsite-syntax-p">(</span><span class="devsite-syntax-nx">pendingTransfers</span><span class="devsite-syntax-p">);</span> <span class="devsite-syntax-p">}</span> </code></pre></devsite-code> <h2 id="tips" data-text="Tips" tabindex="-1">Tips</h2> <p>Debugging USB in Chrome is easier with the internal page <code translate="no" dir="ltr">about://device-log</code> where you can see all USB device related events in one single place.</p> <figure> <img src="/static/docs/capabilities/usb/image/screenshot-the-device-lo-5e45db14a43c3.png" alt="Screenshot of the device log page to debug WebUSB in Chrome" width="800" height="442" srcset="https://developer.chrome.com/static/docs/capabilities/usb/image/screenshot-the-device-lo-5e45db14a43c3_36.png 36w,https://developer.chrome.com/static/docs/capabilities/usb/image/screenshot-the-device-lo-5e45db14a43c3_48.png 48w,https://developer.chrome.com/static/docs/capabilities/usb/image/screenshot-the-device-lo-5e45db14a43c3_72.png 72w,https://developer.chrome.com/static/docs/capabilities/usb/image/screenshot-the-device-lo-5e45db14a43c3_96.png 96w,https://developer.chrome.com/static/docs/capabilities/usb/image/screenshot-the-device-lo-5e45db14a43c3_480.png 480w,https://developer.chrome.com/static/docs/capabilities/usb/image/screenshot-the-device-lo-5e45db14a43c3_720.png 720w,https://developer.chrome.com/static/docs/capabilities/usb/image/screenshot-the-device-lo-5e45db14a43c3_856.png 856w,https://developer.chrome.com/static/docs/capabilities/usb/image/screenshot-the-device-lo-5e45db14a43c3_960.png 960w,https://developer.chrome.com/static/docs/capabilities/usb/image/screenshot-the-device-lo-5e45db14a43c3_1440.png 1440w,https://developer.chrome.com/static/docs/capabilities/usb/image/screenshot-the-device-lo-5e45db14a43c3_1920.png 1920w,https://developer.chrome.com/static/docs/capabilities/usb/image/screenshot-the-device-lo-5e45db14a43c3_2880.png 2880w" sizes="(max-width: 840px) 100vw, 856px"> <figcaption class="dcc-caption">Device log page in Chrome for debugging the WebUSB API.</figcaption> </figure> <p>The internal page <code translate="no" dir="ltr">about://usb-internals</code> also comes in handy and allows you to simulate connection and disconnection of virtual WebUSB devices. This is be useful for doing UI testing without for real hardware.</p> <figure> <img src="/static/docs/capabilities/usb/image/screenshot-the-internal-3f26665cde1c.png" alt="Screenshot of the internal page to debug WebUSB in Chrome" width="800" height="294" srcset="https://developer.chrome.com/static/docs/capabilities/usb/image/screenshot-the-internal-3f26665cde1c_36.png 36w,https://developer.chrome.com/static/docs/capabilities/usb/image/screenshot-the-internal-3f26665cde1c_48.png 48w,https://developer.chrome.com/static/docs/capabilities/usb/image/screenshot-the-internal-3f26665cde1c_72.png 72w,https://developer.chrome.com/static/docs/capabilities/usb/image/screenshot-the-internal-3f26665cde1c_96.png 96w,https://developer.chrome.com/static/docs/capabilities/usb/image/screenshot-the-internal-3f26665cde1c_480.png 480w,https://developer.chrome.com/static/docs/capabilities/usb/image/screenshot-the-internal-3f26665cde1c_720.png 720w,https://developer.chrome.com/static/docs/capabilities/usb/image/screenshot-the-internal-3f26665cde1c_856.png 856w,https://developer.chrome.com/static/docs/capabilities/usb/image/screenshot-the-internal-3f26665cde1c_960.png 960w,https://developer.chrome.com/static/docs/capabilities/usb/image/screenshot-the-internal-3f26665cde1c_1440.png 1440w,https://developer.chrome.com/static/docs/capabilities/usb/image/screenshot-the-internal-3f26665cde1c_1920.png 1920w,https://developer.chrome.com/static/docs/capabilities/usb/image/screenshot-the-internal-3f26665cde1c_2880.png 2880w" sizes="(max-width: 840px) 100vw, 856px"> <figcaption class="dcc-caption">Internal page in Chrome for debugging the WebUSB API.</figcaption> </figure> <p>On most Linux systems, USB devices are mapped with read-only permissions by default. To allow Chrome to open a USB device, you will need to add a new <a href="https://www.freedesktop.org/software/systemd/man/udev.html">udev rule</a>. Create a file at <code translate="no" dir="ltr">/etc/udev/rules.d/50-yourdevicename.rules</code> with the following content:</p> <div></div><devsite-code><pre class="devsite-click-to-copy" translate="no" dir="ltr" is-upgraded syntax="VimL"><code translate="no" dir="ltr">SUBSYSTEM<span class="devsite-syntax-p">==</span><span class="devsite-syntax-s2">"usb"</span><span class="devsite-syntax-p">,</span> ATTR{idVendor}<span class="devsite-syntax-p">==</span><span class="devsite-syntax-s2">"[yourdevicevendor]"</span><span class="devsite-syntax-p">,</span> MODE<span class="devsite-syntax-p">=</span><span class="devsite-syntax-s2">"0664"</span><span class="devsite-syntax-p">,</span> GROUP<span class="devsite-syntax-p">=</span><span class="devsite-syntax-s2">"plugdev"</span> </code></pre></devsite-code> <p>where <code translate="no" dir="ltr">[yourdevicevendor]</code> is <code translate="no" dir="ltr">2341</code> if your device is an Arduino for instance. <code translate="no" dir="ltr">ATTR{idProduct}</code> can also be added for a more specific rule. Make sure your <code translate="no" dir="ltr">user</code> is a <a href="https://wiki.debian.org/SystemGroups">member</a> of the <code translate="no" dir="ltr">plugdev</code> group. Then, just reconnect your device.</p> <aside class="note"><b>Note:</b> Microsoft OS 2.0 Descriptors used by the Arduino examples only work on Windows 8.1 and later. Without that Windows support still requires manual installation of an INF file.</aside> <h2 id="resources" data-text="Resources" tabindex="-1">Resources</h2> <ul> <li>Stack Overflow: <a href="https://stackoverflow.com/questions/tagged/webusb">https://stackoverflow.com/questions/tagged/webusb</a></li> <li>WebUSB API Spec: <a href="https://wicg.github.io/webusb/">http://wicg.github.io/webusb/</a></li> <li>Chrome Feature Status: <a href="https://www.chromestatus.com/feature/5651917954875392">https://www.chromestatus.com/feature/5651917954875392</a></li> <li>Spec Issues: <a href="https://github.com/WICG/webusb/issues">https://github.com/WICG/webusb/issues</a></li> <li>Implementation Bugs: <a href="http://crbug.com?q=component:Blink%3EUSB">http://crbug.com?q=component:Blink&gt;USB</a></li> <li>WebUSB ❤ ️Arduino: <a href="https://github.com/webusb/arduino">https://github.com/webusb/arduino</a></li> <li>IRC: <a href="irc://irc.w3.org:6665/#webusb">#webusb</a> on W3C&#39;s IRC</li> <li>WICG Mailing list: <a href="https://lists.w3.org/Archives/Public/public-wicg/">https://lists.w3.org/Archives/Public/public-wicg/</a></li> <li>WebLight project: <a href="https://github.com/sowbug/weblight">https://github.com/sowbug/weblight</a></li> </ul> <p>Send a tweet to <a href="https://twitter.com/chromiumdev">@ChromiumDev</a> using the hashtag <a href="https://twitter.com/search?q=%23WebUSB&amp;src=typed_query&amp;f=live"><code translate="no" dir="ltr">#WebUSB</code></a> and let us know where and how you&#39;re using it.</p> <h2 id="acknowledgements" data-text="Acknowledgements" tabindex="-1">Acknowledgements</h2> <p>Thanks to <a href="https://github.com/jpmedley">Joe Medley</a> for reviewing this article.</p> </div> <devsite-thumb-rating position="footer"> </devsite-thumb-rating> <div class="devsite-floating-action-buttons"> </div> </article> <devsite-content-footer class="nocontent"> <p>Except as otherwise noted, the content of this page is licensed under the <a href="https://creativecommons.org/licenses/by/4.0/">Creative Commons Attribution 4.0 License</a>, and code samples are licensed under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache 2.0 License</a>. For details, see the <a href="https://developers.google.com/site-policies">Google Developers Site Policies</a>. Java is a registered trademark of Oracle and/or its affiliates.</p> <p>Last updated 2016-03-30 UTC.</p> </devsite-content-footer> <devsite-notification > </devsite-notification> <div class="devsite-content-data"> <template class="devsite-content-data-template"> [[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Missing the information I need","missingTheInformationINeed","thumb-down"],["Too complicated / too many steps","tooComplicatedTooManySteps","thumb-down"],["Out of date","outOfDate","thumb-down"],["Samples / code issue","samplesCodeIssue","thumb-down"],["Other","otherDown","thumb-down"]],["Last updated 2016-03-30 UTC."],[],[]] </template> </div> </devsite-content> </main> <devsite-footer-promos class="devsite-footer"> </devsite-footer-promos> <devsite-footer-linkboxes class="devsite-footer"> <nav class="devsite-footer-linkboxes nocontent" aria-label="Footer links"> <ul class="devsite-footer-linkboxes-list"> <li class="devsite-footer-linkbox "> <h3 class="devsite-footer-linkbox-heading no-link">Contribute</h3> <ul class="devsite-footer-linkbox-list"> <li class="devsite-footer-linkbox-item"> <a href="https://issuetracker.google.com/issues/new?component=1400036&amp;template=1897236" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 1)" > File a bug </a> </li> <li class="devsite-footer-linkbox-item"> <a href="https://issuetracker.google.com/issues?q=status:open%20componentid:1400036&amp;s=created_time:desc" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 2)" > See open issues </a> </li> </ul> </li> <li class="devsite-footer-linkbox "> <h3 class="devsite-footer-linkbox-heading no-link">Related content</h3> <ul class="devsite-footer-linkbox-list"> <li class="devsite-footer-linkbox-item"> <a href="https://blog.chromium.org/" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 1)" > Chromium updates </a> </li> <li class="devsite-footer-linkbox-item"> <a href="/case-studies" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 2)" > Case studies </a> </li> <li class="devsite-footer-linkbox-item"> <a href="/deprecated" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 3)" > Archive </a> </li> <li class="devsite-footer-linkbox-item"> <a href="https://web.dev/shows" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 4)" > Podcasts &amp; shows </a> </li> </ul> </li> <li class="devsite-footer-linkbox "> <h3 class="devsite-footer-linkbox-heading no-link">Follow</h3> <ul class="devsite-footer-linkbox-list"> <li class="devsite-footer-linkbox-item"> <a href="https://twitter.com/ChromiumDev" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 1)" > @ChromiumDev on X </a> </li> <li class="devsite-footer-linkbox-item"> <a href="https://www.youtube.com/user/ChromeDevelopers" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 2)" > YouTube </a> </li> <li class="devsite-footer-linkbox-item"> <a href="https://www.linkedin.com/showcase/chrome-for-developers" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 3)" > Chrome for Developers on LinkedIn </a> </li> <li class="devsite-footer-linkbox-item"> <a href="/static/blog/feed.xml" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 4)" > RSS </a> </li> </ul> </li> </ul> </nav> </devsite-footer-linkboxes> <devsite-footer-utility class="devsite-footer"> <div class="devsite-footer-utility nocontent"> <nav class="devsite-footer-utility-links" aria-label="Utility links"> <ul class="devsite-footer-utility-list"> <li class="devsite-footer-utility-item "> <a class="devsite-footer-utility-link gc-analytics-event" href="//policies.google.com/terms" data-category="Site-Wide Custom Events" data-label="Footer Terms link" > Terms </a> </li> <li class="devsite-footer-utility-item "> <a class="devsite-footer-utility-link gc-analytics-event" href="//policies.google.com/privacy" data-category="Site-Wide Custom Events" data-label="Footer Privacy link" > Privacy </a> </li> <li class="devsite-footer-utility-item glue-cookie-notification-bar-control"> <a class="devsite-footer-utility-link gc-analytics-event" href="#" data-category="Site-Wide Custom Events" data-label="Footer Manage cookies link" aria-hidden="true" > Manage cookies </a> </li> </ul> <devsite-language-selector> <ul role="presentation"> <li role="presentation"> <a role="menuitem" lang="en" >English</a> </li> <li role="presentation"> <a role="menuitem" lang="de" >Deutsch</a> </li> <li role="presentation"> <a role="menuitem" lang="es_419" >Español – América Latina</a> </li> <li role="presentation"> <a role="menuitem" lang="fr" >Français</a> </li> <li role="presentation"> <a role="menuitem" lang="id" >Indonesia</a> </li> <li role="presentation"> <a role="menuitem" lang="it" >Italiano</a> </li> <li role="presentation"> <a role="menuitem" lang="nl" >Nederlands</a> </li> <li role="presentation"> <a role="menuitem" lang="pl" >Polski</a> </li> <li role="presentation"> <a role="menuitem" lang="pt_br" >Português – Brasil</a> </li> <li role="presentation"> <a role="menuitem" lang="vi" >Tiếng Việt</a> </li> <li role="presentation"> <a role="menuitem" lang="tr" >Türkçe</a> </li> <li role="presentation"> <a role="menuitem" lang="ru" >Русский</a> </li> <li role="presentation"> <a role="menuitem" lang="he" >עברית</a> </li> <li role="presentation"> <a role="menuitem" lang="ar" >العربيّة</a> </li> <li role="presentation"> <a role="menuitem" lang="fa" >فارسی</a> </li> <li role="presentation"> <a role="menuitem" lang="hi" >हिंदी</a> </li> <li role="presentation"> <a role="menuitem" lang="bn" >বাংলা</a> </li> <li role="presentation"> <a role="menuitem" lang="th" >ภาษาไทย</a> </li> <li role="presentation"> <a role="menuitem" lang="zh_cn" >中文 – 简体</a> </li> <li role="presentation"> <a role="menuitem" lang="zh_tw" >中文 – 繁體</a> </li> <li role="presentation"> <a role="menuitem" lang="ja" >日本語</a> </li> <li role="presentation"> <a role="menuitem" lang="ko" >한국어</a> </li> </ul> </devsite-language-selector> </nav> </div> </devsite-footer-utility> <devsite-panel></devsite-panel> </section></section> <devsite-sitemask></devsite-sitemask> <devsite-snackbar></devsite-snackbar> <devsite-tooltip ></devsite-tooltip> <devsite-heading-link></devsite-heading-link> <devsite-analytics> <script type="application/json" analytics>[]</script> <script type="application/json" tag-management>{&#34;at&#34;: &#34;True&#34;, &#34;ga4&#34;: [], &#34;ga4p&#34;: [], &#34;gtm&#34;: [{&#34;id&#34;: &#34;GTM-5QF3RT2&#34;, &#34;purpose&#34;: 0}], &#34;parameters&#34;: {&#34;internalUser&#34;: &#34;False&#34;, &#34;language&#34;: {&#34;machineTranslated&#34;: &#34;False&#34;, &#34;requested&#34;: &#34;en&#34;, &#34;served&#34;: &#34;en&#34;}, &#34;pageType&#34;: &#34;article&#34;, &#34;projectName&#34;: &#34;Capabilities&#34;, &#34;signedIn&#34;: &#34;False&#34;, &#34;tenant&#34;: &#34;chrome&#34;, &#34;recommendations&#34;: {&#34;sourcePage&#34;: &#34;&#34;, &#34;sourceType&#34;: 0, &#34;sourceRank&#34;: 0, &#34;sourceIdenticalDescriptions&#34;: 0, &#34;sourceTitleWords&#34;: 0, &#34;sourceDescriptionWords&#34;: 0, &#34;experiment&#34;: &#34;&#34;}, &#34;experiment&#34;: {&#34;ids&#34;: &#34;&#34;}}}</script> </devsite-analytics> <devsite-badger></devsite-badger> <script nonce="LQKvFQAd6yqOXyfQBO/ELezVzfeMyk"> (function(d,e,v,s,i,t,E){d['GoogleDevelopersObject']=i; t=e.createElement(v);t.async=1;t.src=s;E=e.getElementsByTagName(v)[0]; E.parentNode.insertBefore(t,E);})(window, document, 'script', 'https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/chrome/js/app_loader.js', '[53,"en",null,"/js/devsite_app_module.js","https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625","https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/chrome","https://chrome-dot-devsite-v2-prod-3p.appspot.com",1,null,["/_pwa/chrome/manifest.json","https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/images/video-placeholder.svg","https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/chrome/images/favicon.png","https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/chrome/images/lockup.svg","https://fonts.googleapis.com/css?family=Google+Sans:400,500|Roboto:400,400italic,500,500italic,700,700italic|Roboto+Mono:400,500,700&display=swap"],1,null,[1,6,8,12,14,17,21,25,50,52,63,70,75,76,80,87,91,92,93,97,98,100,101,102,103,104,105,107,108,109,110,112,113,116,117,118,120,122,124,125,126,127,129,130,131,132,133,134,135,136,138,140,141,147,148,149,151,152,156,157,158,159,161,163,164,168,169,170,179,180,182,183,186,191,193,196],"AIzaSyCNm9YxQumEXwGJgTDjxoxXK6m1F-9720Q","AIzaSyCc76DZePGtoyUjqKrLdsMGk_ry7sljLbY","developer.chrome.com","AIzaSyB9bqgQ2t11WJsOX8qNsCQ6U-w91mmqF-I","AIzaSyAdYnStPdzjcJJtQ0mvIaeaMKj7_t6J_Fg",null,null,null,["Profiles__enable_developer_profiles_callout","Profiles__enable_profile_collections","Profiles__enable_recognition_badges","Cloud__enable_cloudx_experiment_ids","OnSwitch__enable","TpcFeatures__enable_required_headers","BookNav__enable_tenant_cache_key","MiscFeatureFlags__enable_variable_operator","Cloud__enable_cloud_shell_fte_user_flow","MiscFeatureFlags__emergency_css","Analytics__enable_clearcut_logging","CloudShell__cloud_code_overflow_menu","MiscFeatureFlags__enable_firebase_utm","Search__enable_ai_eligibility_checks","Profiles__enable_public_developer_profiles","Cloud__enable_legacy_calculator_redirect","Search__enable_suggestions_from_borg","DevPro__enable_cloud_innovators_plus","Profiles__enable_dashboard_curated_recommendations","Cloud__enable_llm_concierge_chat","Profiles__enable_awarding_url","CloudShell__cloud_shell_button","Profiles__enable_complete_playlist_endpoint","Profiles__enable_release_notes_notifications","EngEduTelemetry__enable_engedu_telemetry","Cloud__enable_free_trial_server_call","MiscFeatureFlags__enable_project_variables","MiscFeatureFlags__developers_footer_image","Profiles__enable_completecodelab_endpoint","TpcFeatures__enable_mirror_tenant_redirects","Experiments__reqs_query_experiments","MiscFeatureFlags__developers_footer_dark_image","MiscFeatureFlags__enable_explain_this_code","Search__enable_dynamic_content_confidential_banner","Profiles__enable_page_saving","Profiles__require_profile_eligibility_for_signin","Search__enable_page_map","Cloud__enable_cloudx_ping","MiscFeatureFlags__enable_view_transitions","Cloud__enable_cloud_shell","Cloud__enable_cloud_dlp_service","DevPro__enable_developer_subscriptions","Concierge__enable_pushui","Cloud__enable_cloud_facet_chat"],null,null,"AIzaSyA58TaKli1DculwmAmbpzLVGuWc8eCQgQc","https://developerscontentserving-pa.googleapis.com","AIzaSyDWBU60w0P9hEkr29kkksYs8Z7gvZ8u_wc","https://developerscontentsearch-pa.googleapis.com",2,4,null,"https://developerprofiles-pa.googleapis.com",[53,"chrome","Chrome for Developers","developer.chrome.com",null,"chrome-dot-devsite-v2-prod-3p.appspot.com",null,null,[null,null,null,null,null,null,null,null,null,null,null,[1],null,null,null,null,null,null,[1],null,null,null,null,[1,null,1],[1,1,null,1,1]],null,[69,null,null,null,null,null,"/images/lockup.svg","/images/touchicon-180.png",null,null,null,1,1,null,null,null,null,null,null,null,null,2,null,null,null,"/images/lockup-dark-theme.svg",[]],[],null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,[[],[1,1]],[[null,null,null,null,null,["GTM-5QF3RT2"],null,null,null,null,null,[["GTM-5QF3RT2",1]],1]],null,4]]') </script> <devsite-a11y-announce></devsite-a11y-announce> </body> </html>

Pages: 1 2 3 4 5 6 7 8 9 10