Updates
A little over a year ago we announced our plans to reduce the granularity of information available from the User-Agent string, which is sent by default for every HTTP request. Shortly after, we made the decision to put this effort on pause so as not to create an additional migration burden on the web ecosystem in the early days of the COVID-19 pandemic. Since then, we’ve spent a lot of time gathering valuable feedback from the ecosystem, proposing ergonomic improvements to the User-Agent Client Hints API (UA-CH)—our proposed replacement for content negotiation and detection—as well as making web compatibility fixes.
UA-CH is now shipping by default in Chrome (since M89). We’ve also started the roll-out of both Client Hints Reliability mechanisms (Critical-CH & ACCEPT_CH) to address use cases where hints are needed on the first request. While we don’t yet have exact dates and milestones to announce for the planned User-Agent string reduction changes, we’re ready to resume our efforts on this front.
That said, we feel it's important to proceed in a way that gives the ecosystem and developers sufficient time to test use cases, provide feedback, and migrate to UA-CH where appropriate, which is why no User-Agent string changes will be coming to the stable channel of Chrome in 2021. Our intent with this post is to provide transparency into our thinking and roadmap early on so you can plan to adapt accordingly.
We plan to gradually reduce, in a phased manner, the granularity of available information in the User-Agent header field, as well as the navigator.userAgent, navigator.appVersion, and navigator.platform JS APIs.
Once this is complete, you will still be able to reliably get the browser major version, platform name, and distinguish between desktop and mobile (or tablet), solely from the User-Agent string. For more advanced use cases, you should migrate to the User Agent Client Hints API.
Note: We have no plans to change the User-Agent string on Android WebView or Chrome for iOS at this time, but will make public updates if and when that changes.
Our current high-level plan is as follows:
We plan to roll out these changes slowly and incrementally in 7 Phases—pending Origin Trial feedback—and plan to publish an update soon on the proposed timing and milestones beyond Phase 1.
Phase 1: Warn about accessing navigator.userAgent, navigator.appVersion, and navigator.platform in DevTools, beginning in M92.
Phase 2: Launch an Origin Trial for sites to opt into the final reduced UA string for testing and feedback, for at least 6 months.
Phase 3: Launch a reverse Origin Trial, for instances where a site may need more time for migration, for at least 6 months.
Phase 4: Ship reduced Chrome MINOR.BUILD.PATCH version numbers (“0.0.0”). Once rolled-out, the reduced UA string would apply to all page loads on desktop and mobile OSes that do not opt into the reverse Origin Trial.
Phase 5: Begin roll-out of reduced Desktop UA string and related JS APIs (navigator.userAgent, navigator.appVersion, navigator.platform). Once rolled-out, the reduced UA string would apply to all page loads on desktop OSes that do not opt into the reverse Origin Trial.
Phase 6: Begin roll-out of reduced Android Mobile (and Tablet) UA string and related JS APIs. Once rolled-out, the reduced UA string would apply to all page loads on Android that do not opt into the reverse Origin Trial.
Phase 7: reverse Origin Trial ends and all page loads receive the reduced UA string and related JS APIs.
See the companion Reduced User Agent string updates page for more details and example User Agent strings at each of these phases.
Our plan was designed with backwards compatibility in mind, and while any changes to the User Agent string need to be managed carefully, we expect minimal friction for developers as we roll this out (i.e., existing parsers should continue to operate as expected).
If your site, service, library or application relies on certain bits of information being present in the User Agent string such as Chrome minor version, OS version number, or Android device model, you will need to begin the migration to use the User Agent Client Hints API instead.
If you don’t require any of these, then no changes are required and things should continue to operate as they have to date.
As noted in the User Agent Client Hints explainer, the User Agent string presents challenges for two reasons. Firstly, it passively exposes quite a lot of information about the browser for every HTTP request that may be used for fingerprinting. Secondly, it has grown in length and complexity over the years and encourages error-prone string parsing. We believe the User Agent Client Hints API solves both of these problems in a more developer- and user-friendly manner.
In some ways Chrome is playing catch up on this front: Safari was the first to cap the macOS version number in the UA string and Firefox has followed suit. Firefox has also capped the Windows version number to 10.
Back in February, we announced that cross-origin isolation will be required on all platforms in order to access APIs like SharedArrayBuffer and performance.measureUserAgentSpecificMemory() starting in Chrome 91. Based on your feedback and issues reported, we've decided to adjust the timeline for SharedArrayBuffer usage in none cross-origin isolated sites to be restricted in Chrome 92.
Your feedback is important and we are listening.
Unless otherwise noted, changes described below apply to the newest Chrome beta channel release for Android, Chrome OS, Linux, macOS, and Windows. Learn more about the features listed here through the provided links or from the list on ChromeStatus.com. Chrome 91 is beta as of April 22, 2021.
This version of Chrome introduces the origin trials described below. Origin trials allow you to try new features and give feedback on usability, practicality, and effectiveness to the web standards community. To register for any of the origin trials currently supported in Chrome, including the ones described below, visit the Chrome Origin Trials dashboard. To learn more about origin trials in Chrome, visit the Origin Trials Guide for Web Developers. Microsoft Edge runs its own origin trials separate from Chrome. To learn more, see the Microsoft Edge Origin Trials Developer Console.
The new Web App Manifest member called capture_links controls what happens when the user navigates to a page within scope of an installed web app. It allows sites to automatically open a new PWA window when the user clicks a link to their app or to have a single window mode like mobile apps. Sign up for the origin trial and learn more on the origin trial dashboard.
capture_links
WebTransport is a protocol framework that enables clients constrained by the Web security model to communicate with a remote server using a secure multiplexed transport.
Currently, Web application developers have two APIs for bidirectional communications with a remote server: WebSockets and RTCDataChannel. WebSockets are TCP-based, thus having all of the drawbacks of TCP (head of line blocking, lack of support for unreliable data transport) that make it a poor fit for latency-sensitive applications. RTCDataChannel is based on the Stream Control Transmission Protocol (SCTP), which does not have these drawbacks; however, it is designed to be used in a peer-to-peer context, which causes its use in client-server settings to be fairly low. WebTransport provides a client-server API that supports bidirectional transfer of both unreliable and reliable data, using UDP-like datagrams and cancellable streams. WebTransport calls are visible in the Network panel of DevTools and identified as such in the Type column.
WebSockets
RTCDataChannel
WebTransport
For more information, see Experimenting with WebTransport. Sign up for the origin trial and learn more on the origin trial dashboard.
WebXR applications can now retrieve data about planes (flat surfaces) in the user's environment, allowing better user experiences with less processing power. Without this feature plane detection requires custom computer vision algorithms using data from MediaDevices.getUserMedia(). These solutions usually fall short of quality and accuracy expectations for AR experiences and don't support world scale. Sign up for the origin trial and learn more on the dashboard.
MediaDevices.getUserMedia()
The following features, previously in a Chrome origin trial, are now enabled by default.
WebAssembly SIMD exposes hardware SIMD instructions to WebAssembly applications in a platform-independent way. This introduces a new 128-bit type that can represent different types of packed data, and several vector operations that work on packed data. SIMD can boost performance by exploiting data level parallelism and is also useful when compiling native code to WebAssembly. For more information, see the V8 feature explainer for WebAssembly SIMD.
Coarsening of performance.now() and related timestamps based on site isolation status is now consistent across platforms. This decreases the resolution on desktop from 5 microseconds to 100 microseconds in non-isolated contexts. It also increases their resolution on Android from 100 microseconds to 5 microseconds in cross-origin isolated contexts, where it's safe to do so.
performance.now()
On desktop, apps can now read files from the clipboard (but not write files to the clipboard). For files on the clipboard, apps have read-only access.
async function onPaste(e) { let file = e.clipboardData.files[0]; let contents = await file.text(); }
The CSS @counter-style rule allows web authors to specify and use custom counter styles in list markers and CSS counters. This helps internationalization. This change implements all of the features in CSS Counter Styles Level 3 except:
@counter-style
speak-as
symbols()
The :host() and :host-context() pseudo-classes now accept a single <compound-selector> in addition to a <compound-selector-list>.
:host()
:host-context()
<compound-selector>
<compound-selector-list>
Form controls have a new, refreshed appearance, with better accessibility and touch support. This was a collaboration between Microsoft and Google, and if you'd like additional information, you can view a past CDS talk or the Microsoft's blog post.
In this release, we have brought the same form controls UX to Android as already launched on other platforms. The new form controls include automatically darkening form controls and scrollbars when in dark mode.
Dark mode is an accessibility feature that allows web authors to enable their web pages to be viewed in dark mode. When enabled, users are able to view dark mode supported websites by toggling the dark mode settings on their Android devices. dark mode is easier on the eyes in a low light environment and lowers battery consumption.
The GravitySensor interface provides a three-axis reading of the gravity force. It's already possible to derive readings close to those provided by this interface removing the LinerAccelerometer reading from the Accelerometer reading.
GravitySensor
LinerAccelerometer
Accelerometer
When using the File System Access API, web apps can now suggest the name and location of a file or directory that is being created or loaded. This provides a better user experience and brings web apps closer to the behavior of system apps. For more about the File System Access API, see The File System Access API: simplifying access to local files.
The WebOTP API is now usable in cross-origin iframes when enabled by a permission policy. The WebOTP API gives developers the ability to programmatically read one time codes from specially-formatted SMS messages addressed to their origin to reduce user friction. Many sites embed iframes that handle authentication.
Chrome supports WebSockets over HTTP/2 in Chromium as specified in RFC 8441. This is only used for secure WebSockets requests, and only when there is already an HTTP/2 connection where the server has already advertised support for WebSockets over HTTP/2 via the HTTP/2 SETTINGS parameter defined in the specification.
Since 2015 developers have used Digital Asset Links (DALs) to associate Android apps with websites to assist users with logging in. If you employ multiple domains that share the same account management backend, you can now also associate them with one another to enable users to save credentials once and have the Chrome password manager suggest them to any of the affiliated websites. For more information, see Enable Chrome to share login credentials across affiliated sites.
This version of Chrome incorporates version 9.1 of the V8 JavaScript engine. It specifically includes the changes listed below. You can find a complete list of recent features in the V8 release notes.
JavaScript now supports modules in service workers. Setting 'module' type by the constructor's type attribute, worker scripts are loaded as ES modules and the import statement is available on worker contexts. With this feature, web developers can more easily write programs in a composable way and share them among a page and workers.
'module'
import
Developers can now test for the existence of private fields in an object using the syntax #foo in obj.
#foo in obj
This version of Chrome introduces the deprecation listed below. Visit ChromeStatus.com for lists of previous removals.
Chrome allows iframes to trigger Javascript dialogs. For example it shows “<URL> says ...” when the iframe is the same origin as the top frame, and “An embedded page on this page says...” when the iframe is cross-origin. This is confusing, and has led to spoofs where sites pretend the message comes from Chrome or a different website.
Chrome 91 deprecates this ability. Removing support for cross origin iframes’ ability to call alert(), confirm(), and prompt() will prevent this kind of spoofing, and unblock further UI simplifications. For example, this means notexample.com will no longer be able to call window.alert(), window.prompt(), or window.confirm() if embedded in an iframe on example.com.
alert()
confirm()
prompt()
window.alert()
window.prompt()
window.confirm()
RegEnumValueWStub
base::win::RegistryValueIterator::Read()
gfx::`anonymous namespace\'::CachedFontLinkSettings::GetLinkedFonts
gfx::internal::LinkedFontsIterator::GetLinkedFonts()
gfx::internal::LinkedFontsIterator::NextFont(gfx::Font *)
gfx::GetFallbackFonts(gfx::Font const &)
gfx::RenderTextHarfBuzz::ShapeRuns(...)
gfx::RenderTextHarfBuzz::ItemizeAndShapeText(...)
gfx::RenderTextHarfBuzz::EnsureLayoutRunList()
gfx::RenderTextHarfBuzz::EnsureLayout()
gfx::RenderTextHarfBuzz::GetStringSizeF()
gfx::RenderTextHarfBuzz::GetStringSize()
OmniboxTextView::CalculatePreferredSize()
OmniboxTextView::ReapplyStyling()
OmniboxTextView::SetText...)
OmniboxResultView::Invalidate()
OmniboxResultView::SetMatch(AutocompleteMatch const &)
OmniboxPopupContentsView::UpdatePopupAppearance()
OmniboxPopupModel::OnResultChanged()
OmniboxEditModel::OnCurrentMatchChanged()
OmniboxController::OnResultChanged(bool)
AutocompleteController::UpdateResult(bool,bool)
AutocompleteController::Start(AutocompleteInput const &)
(...)
Chrome can generate a new password, automatically fill saved passwords, sync them and warn users when passwords are compromised. This means users do not need to maintain passwords themselves. However, if you employ multiple domains (for example, top-level domains such as https://www.example.com and https://www.example.co.uk) that share the same account management backend, Chrome may not offer to fill passwords across them. This can result in two entries for the same password in different domains, which may get out of sync.
Starting in version 91, Chrome will offer to fill passwords saved to domains associated with Digital Asset Links (DALs). DALs have been adopted since 2015, which allow you to link Android apps and websites. In Chrome 91, when you set up DALs between sites, Chrome can assist users with logging in across those sites. To make a DAL association, developers need to put a JSON file that follows the DAL syntax at /.well-known/assetlinks.json on both domains.
To learn more about how to set up a DAL association, enable Chrome to share login credentials across affiliated sites.
Here's a closer look at memory usage in the browser process for Windows as the M89 release began rolling out in early March:
Before: 458 ms (432 ms of which were in Lock/Unlock/KiPageFault)After: 27 ms
Before: 30 allocations per second of 1.32 MB (one per frame, running at 30 fps - a higher framerate would mean more allocations), totalling 396 MB over 10 secondsAfter: 0 allocations
Before: 36 msAfter: 0 ms
Starting in version 90, Chrome’s address bar will use https:// by default, improving privacy and even loading speed for users visiting websites that support HTTPS. Chrome users who navigate to websites by manually typing a URL often don’t include “http://” or “https://”. For example, users often type “example.com” instead of “https://example.com” in the address bar. In this case, if it was a user’s first visit to a website, Chrome would previously choose http:// as the default protocol1. This was a practical default in the past, when much of the web did not support HTTPS.
Chrome will now default to HTTPS for most typed navigations that don’t specify a protocol2. HTTPS is the more secure and most widely used scheme in Chrome on all major platforms. In addition to being a clear security and privacy improvement, this change improves the initial loading speed of sites that support HTTPS, since Chrome will connect directly to the HTTPS endpoint without needing to be redirected from http:// to https://. For sites that don’t yet support HTTPS, Chrome will fall back to HTTP when the HTTPS attempt fails (including when there are certificate errors, such as name mismatch or untrusted self-signed certificate, or connection errors, such as DNS resolution failure). This change is rolling out initially on Chrome Desktop and Chrome for Android in version 90, with a release for Chrome on iOS following soon after.
HTTPS protects users by encrypting traffic sent over the network, so that sensitive information users enter on websites cannot be intercepted or modified by attackers or eavesdroppers. Chrome is invested in ensuring that HTTPS is the default protocol for the web, and this change is one more step towards ensuring Chrome always uses secure connections by default.
1 One notable exception to this is any site in the HSTS preload list, which Chrome will always default to HTTPS. 2 IP addresses, single label domains, and reserved hostnames such as test/ or localhost/ will continue defaulting to HTTP.
The web platform relies on the origin as a fundamental security boundary, and browsers do a pretty good job at preventing explicit leakage of data from one origin to another. Attacks like Spectre, however, show that we still have work to do to mitigate implicit data leakage. The side-channels exploited through these attacks prove that attackers can read any data which enters a process hosting that attackers' code. These attacks are quite practical today, and pose a real risk to users.
Our goal must be to ensure that sensitive data doesn't unexpectedly enter an attacker's process. Browsers shoulder a large chunk of this responsibility: Chromium's Site Isolation can separate the sites you visit into distinct OS-level processes, cross-origin read blocking prevents attackers from loading a subset of otherwise-vulnerable cross-origin resources, and APIs that substantially increase attackers' bandwidth (like SharedArrayBuffer) are being locked to cross-origin isolated contexts. This last mechanism, however, points in the direction of work that browsers can't do on their own.
Web developers know their applications intimately, and can make informed decisions about each page's and resource's risk of exposure. To defend users' data against exfiltration, web developers must step in, evaluate resources they host, and instruct browsers to isolate those resources accordingly. At a high-level, this defense consists of:
Together, these various defenses help all browsers offer some degree of process-level protection for users' data, whether or not Site Isolation is available.
To find out more about employing these defenses, check out Post-Spectre Web Development. It includes practical examples that explain in more detail how the security primitives discussed above apply to resources you might have on your sites.
These are useful steps you can take today to protect your origin against implicit data leaks. Looking forward, we hope to help the web shift to safer defaults which protect users against these attacks without requiring developer action.
Unless otherwise noted, changes described below apply to the newest Chrome beta channel release for Android, Chrome OS, Linux, macOS, and Windows. Learn more about the features listed here through the provided links or from the list on ChromeStatus.com. Chrome 90 is beta as of March 11, 2021.
An AV1 encoder is shipping in Chrome desktop that is specifically optimized for video conferencing with WebRTC integration. The benefits of AV1 include:
This is an important addition to WebRTC especially since it recently became an official W3C and IETF standard.
The mediaDevices.getCurrentBrowsingContextMedia() method allows capturing a MediaStream with the current tab's video (and potentially audio), similar to getDisplayMedia(). Unlike getDisplayMedia(), calling this new method will eventually present the user with a simple accept/reject dialog box. If the user accepts, the current tab is captured. However, this will require some additional security measures which are still being finalized. Until then, or if the call is made with these measures absent, a dialog is displayed to the user that allows the selection of any source, but highlights the option of the current tab (whereas normally getDisplayMedia highlights the option of entire-screen).
An API for manipulating raw media carried by MediaStreamTracks such as the output of a camera, microphone, screen capture, or the decoder part of a codec and the input to the decoder part of a codec. It uses WebCodecs interfaces to represent raw media frames and exposes them using streams, similar to the way the WebRTC Insertable Streams API exposes encoded data from RTCPeerConnections. This is intended to support use cases such as:
This origin trial is expected to run through Chrome 92.
Subresource loading with Web Bundles provides a new approach to loading a large number of resources efficiently using a format that allows multiple resources to be bundled., e.g. Web Bundles.
The output of JavaScript bundlers (e.g. webpack) doesn't interact well with browsers. They are good tools but:
This origin trial also allows a bundle to include the source for an opaque-origin iframe as urn:uuid: resources. The scheme for these resources is expected to change in Chrome 91.
urn:uuid:
WebAssembly now provides exception handling support. Exception handling allows code to break control flow when an exception is thrown. The exception can be any that is known by the WebAssembly module, or it may be an unknown exception that was thrown by a called imported function. This origin trial is expected to run through Chrome 94.
Lighting estimation allows sites to query for estimates of the environmental lighting conditions within WebXR sessions. This exposes both spherical harmonics representing the ambient lighting, as well as a cubemap texture representing "reflections". Adding Lighting Estimation can make your models feel more natural and like they "fit" better with the user's environment.
The aspect-ratio property allows for automatically computing the other dimension if only one of width or height is specified on any element. This property was originally launched as non-interpolable (meaning that it would snap to the target value) when animated. This feature provides smooth interpolation from one aspect ratio to another.
aspect-ratio
Custom elements now expose their states via the state CSS pseudo class. Built-in elements have states that can change over time depending on user interaction and other factors, which are exposed to web authors through pseudo classes. For example, some form controls have the "invalid" state, which is exposed through the :invalid pseudo class. Since custom elements also have states it makes sense to expose their states in a manner similar to built-in elements.
The default values of CSS property appearance and -webkit-appearance for the following form controls are changed to 'auto'.
appearance
-webkit-appearance
'auto'
<input type=color>
<select>
<input type=date>
<input type=datetime-local>
<input type=month>
<input type=time>
<input type=week>
Note that the default rendering of these controls are not changed.
The clip value for overflow results in a box's content being clipped to the box's overflow clip edge. In addition, no scrolling interface is provided, and the content cannot be scrolled by the user or programmatically. Additionally the box is not considered a scroll container, and does not start a new formatting context. As a result, this value has better performance than overflow: hidden.
clip
overflow
overflow: hidden
The overflow-clip-margin property enables specifying how far outside the bounds an element is allowed to paint before being clipped. It also allows the developer to expand the clip border. This is particularly useful for cases where there is ink overflow that should be visible.
overflow-clip-margin
The Permissions-Policy HTTP header replaces the existing Feature-Policy header for controlling delegation of permissions and powerful features. The header allows sites to more tightly restrict which origins can be granted access to features.
Permissions-Policy
Feature-Policy
The Feature Policy API, introduced in Chrome 74, was recently renamed to "Permissions Policy", and the HTTP header has been renamed along with it. At the same time, the community has settled on a new syntax, based on structured field values for HTTP.
Protect application/x-protobuffer from speculative execution attacks by adding it to the list of never sniffed MIME types used by Cross-Origin-Read-Blocking. application/x-protobuf is already protected as a never sniffed mime type. application/x-protobuffer is another commonly used MIME type that is defined as an "ALT_CONTENT_TYPE" by the protobuf library.
application/x-protobuffer
Cross-Origin-Read-Blocking
application/x-protobuf
"ALT_CONTENT_TYPE"
When data is passed to FileSystemWritableFileStream.write() that would extend past the end of the file, the file is now extended by writing 0x00 (NUL). This enables creating sparse files and greatly simplifies saving content to a file when the data to be written is received out of order. Without this functionality, applications that receive file contents out of order (for example, BiTtorrent downloads) would have to manually resize the file either ahead of time or when needed during writing.
FileSystemWritableFileStream.write()
0x00
NUL
Currently, Range is the only constructible range type available to web authors. However, Range objects are "live" and maintaining them can be expensive. For every tree change, all affected Range objects need to be updated. The new StaticRange objects are not live and represent a lightweight range type that is not subject to the same maintenance cost as Range. Making StaticRange constructible allows web authors to use them for ranges that do not need to be updated on every DOM tree change.
Range
StaticRange
The <source> element now supports width and height properties when used inside a <picture> element. This allows Chrome to compute an aspect ratio for <picture> elements. This matches similar behavior for <img>, <canvas> and <video> elements.
<source>
width
height
<picture>
<img>
<canvas>
<video>
It is no longer possible to set periodicWave to null when creating a new OscillatorNode object. This value is set on the options object passed to the OscillatorNode() constructor. The WebAudio spec doesn't allow setting this value to null. Chrome now matches both the spec and Firefox.
OscillatorNode
OscillatorNode()
This version of Chrome incorporates version 9.0 of the V8 JavaScript engine. It specifically includes the changes listed below. You can find a complete list of recent features in the V8 release notes.
Array, String, and TypedArray now support the at() method, which supports relative indexing with negative numbers. For example, the code below returns the last item in the given array.
at()
let arr = [1,2,3,4]; arr.at(-1);
This version of Chrome introduces the deprecations and removals listed below. Visit ChromeStatus.com for lists of current deprecations and previous removals.
The 'plugin-types' directive allows developers to restrict which types of plugin can be loaded via <embed> or <object> html elements. This allowed developers to block Flash in their pages. Since Flash support has been discontinued, there is no longer any need for this policy directive.
<embed>
<object>
Chrome has removed support for the non-standard RTP data channels in WebRTC. Users should use the standard SCTP-based data channels instead.
Chrome now returns empty for navigator.plugins and navigator.mimeTypes. With the removal of Flash, there is no longer the need to return anything for these properties.
navigator.plugins
navigator.mimeTypes