![Pete LePage](https://web.dev/images/authors/petelepage.jpg) Pete LePage [X](https://twitter.com/petele) [GitHub](https://github.com/petele) [Mastodon](https://techhub.social/@petele) [Homepage](https://petelepage.com/)

<br />

[Video](https://www.youtube.com/watch?v=Io5d28IETrg)

Here are the highlights in Chrome 124:

- There are two new APIs that allow the [declarative shadow DOM](https://developer.chrome.com/blog/new-in-chrome-124.md.txt#dsd) to be used from JavaScript.
- You can use [streams in Web Sockets](https://developer.chrome.com/blog/new-in-chrome-124.md.txt#streams-in-sockets).
- [View Transitions](https://developer.chrome.com/blog/new-in-chrome-124.md.txt#view-transitions) get a little better.
- And there's plenty [more](https://developer.chrome.com/blog/new-in-chrome-124.md.txt#more).

Want the full run down? Check out the
[Chrome 124 Release Notes](https://developer.chrome.com/release-notes/124.md.txt).

## Use declarative shadow DOM in JavaScript

There are two new APIs that allow the declarative shadow DOM to be used from
JavaScript.

`setHTMLUnsafe()` is similar to `innerHTML`, and lets you set the inner HTML of
an element to the string provided. This helps when you have some
HTML that includes a declarative shadow DOM, like this.

```html
<my-custom-element>
  <template shadowrootmode="open">
    <style>
      :host {
        display: block;
        color: yellow;
      }
    </style>
    Hello, <slot></slot>
  </template>
</my-custom-element>
```

If you just use `innerHTML`, the browser won't parse it properly, and there's
no shadow DOM. But with `setHTMLUnsafe()`, your shadow DOM is created, and the
element is parsed as you'd expect.

```javascript
const section = document.createElement("section");
section.setHTMLUnsafe(`<my-custom-element>...</my-custom-element>`);
```

The other API is `parseHTMLUnsafe()`, and it works similarly to
`DOMParser.parseFromString()`.

Both of these APIs are **unsafe**, which means they don't do any input
sanitization. So you'll want to make sure that whatever you feed them, is safe.
In an upcoming release, we expect see a version that does provide sanitization
of the input.

Finally, both of these APIs are already supported in the latest version of
Firefox and Safari!

## WebSocket Stream API

WebSockets are a great way to send data back and forth between the user's
browser and the server without having to rely on polling. This is great for
things like chat apps, where you want to deal with information as soon as it
comes in.

But what if the data arrives faster than you can handle?

That's called back pressure, and can cause some serious headaches for you.
Unfortunately, the WebSocket API doesn't have a nice way to deal with back
pressure.

The [WebSocket Stream API](https://developer.chrome.com/docs/capabilities/web-apis/websocketstream.md.txt) gives
you the power of streams, and web sockets, which means back pressure can be
applied without any extra cost.

Start by constructing a new `WebSocketStream` and passing it the URL of the
WebSocket server.

```javascript
const wss = new WebSocketStream(WSS_URL);
const {readable, writable} = await wss.opened;
const reader = readable.getReader();
const writer = writable.getWriter();

while (true) {
  const {value, done} = await reader.read();
  if (done) {
    break;
  }
  const result = await process(value);
  await writer.write(result);
}
```

Next, you wait for the connection to be opened, which results
in a `ReadableStream` and a `WritableStream`. By calling the
`ReadableStream.getReader()` method, you get a `ReadableStreamDefaultReader`
which you can then `read()` data from until the stream is done.

To write data, call the `WritableStream.getWriter()` method, which gives you a
`WritableStreamDefaultWriter`, that you can then `write()` data to.

## View transitions improvements

I'm excited about the View Transitions features, and there are two new features
in Chrome 124 designed to make view transitions easier.

The `pageswap` event is fired on a document's window object when a navigation
will replace the document with a new document.

```javascript
document.addEventListener("pageswap", event => {
  if (!event.viewTransition) {
     return;
  }
});
```

And document render-blocking which lets you block rendering of a document
until the critical content has been parsed, ensuring a consistent first paint
across all browsers.

## And more!

Of course there's plenty more.

- [`disallowReturnToOpener`](https://developer.chrome.com/docs/web-platform/document-picture-in-picture.md.txt#hide_the_back_to_tab_button_of_the_picture-in-picture_window)
  hints to the browser that it shouldn't show a button in the picture-in-picture
  window that allows the user to go back to the opener tab.

- [Keyboard-focusable scroll containers](https://developer.chrome.com/blog/keyboard-focusable-scrollers.md.txt)
  improves accessibility by making scroll containers focusable using sequential
  focus navigation.

- And universal install allows users to install any page, even those not
  meeting the [current PWA criteria](https://web.dev/articles/install-criteria).

## Further reading

This covers only some key highlights. Check the following links for
additional changes in Chrome 124.

- [Chrome 124 Release Notes](https://developer.chrome.com/release-notes/124.md.txt)
- [What's new in Chrome DevTools (124)](https://developer.chrome.com/blog/new-in-devtools-124.md.txt)
- [ChromeStatus.com updates for Chrome 124](https://chromestatus.com/features#milestone%3D124)
- [Chromium source repository change list](https://chromium.googlesource.com/chromium/src/+log/123.0.6312.129..124.0.6367.66)
- [Chrome release calendar](https://chromiumdash.appspot.com/schedule)

## Subscribe

To stay up to date, [subscribe](https://goo.gl/6FP1a5) to the
[Chrome Developers YouTube channel](https://www.youtube.com/user/ChromeDevelopers/),
and you'll get an email notification whenever we launch a new video.

I'm Pete LePage, and as soon as Chrome 125 is released, we'll be right here to
tell you what's new in Chrome!