---
title: "Portal Communication"
description: "Communicating between host and portal browsing contexts. Practical notes and code examples on Portal Communication by in JS."
url: "https://h3manth.com/scribe/portal-communication/"
canonical_url: "https://h3manth.com/scribe/portal-communication/"
markdown_url: "https://h3manth.com/scribe/blog/portal-communication.md"
publishDate: "2019-05-12T00:00:00.000Z"
author: "Hemanth HM"
category: "web"
tags: ["javascript","web-api","portals"]
word_count: 242
reading_time_minutes: 2
x_markdown_tokens: 542
content_signal: "ai-train=yes, search=yes, ai-input=yes"
---

# Portal Communication

> Communicating between host and portal browsing contexts. Practical notes and code examples on Portal Communication by in JS.

[Portals](https://wicg.github.io/portals) takes the best from SPA and MPA to provide users with a top level portal browsing context which can be embedded in an HTML document.

A portal is similar to an iframe, in that it allows another browsing context to be embedded. However, the portal browsing context hosted by a portal is part of a separate unit of related browsing contexts. The user agent is thus free to use a separate event loop for the browsing contexts, even if they are same origin-domain.

## Communicating with Portals

At times we would want to communicate with the initial host and the portal and vice versa.

### In the Host

```javascript
const portal = document.querySelector('portal');

portal.activate({data: {foo: "bar"}}).then(() => {
  window.portalHost.onmessage = evn => {
    console.log(e.data); // data from the portal
  }
});
```

We can also get other information from the event:

```javascript
{
  origin: evn.origin,
  data: evn.data,
  sourceIsPortalHost: evn.source === window.portalHost,
  gotUserActivation: !!evn.userActivation,
  userActivation: {
    isActive: evn.userActivation && evn.userActivation.isActive,
    hasBeenActive: evn.userActivation && evn.userActivation.hasBeenActive
  }
};

### In the Portal
javascript
window.addEventListener('portalactivate', (evt) => {
  let predecessor = evt.adoptPredecessor();
  evt.data
  predecessor.postMessage("data", "*");
  // ^ predecessor would be an instanceof HTMLPortalElement
});
```

With `portal.activate` we can basically pass the `{data}` to the portal on activation and the portal shall receive this data in the event object of the `portalactivate` callback.

`evt.adoptPredecessor()` will provide context to the originator of the portal and `portalHost` is exposed if the `window` has a portal browsing context.
