https://github.com/evilkiwi/embed
  
  
    Vue 3 cross-origin iFrame IPC 
    https://github.com/evilkiwi/embed
  
hooks iframe ipc postmessage vue
        Last synced: 3 days ago 
        JSON representation
    
Vue 3 cross-origin iFrame IPC
- Host: GitHub
- URL: https://github.com/evilkiwi/embed
- Owner: evilkiwi
- License: gpl-3.0
- Created: 2021-07-09T10:00:51.000Z (over 4 years ago)
- Default Branch: master
- Last Pushed: 2023-11-11T09:11:48.000Z (almost 2 years ago)
- Last Synced: 2025-03-31T11:01:43.832Z (7 months ago)
- Topics: hooks, iframe, ipc, postmessage, vue
- Language: TypeScript
- Homepage: https://evil.kiwi
- Size: 262 KB
- Stars: 44
- Watchers: 3
- Forks: 2
- Open Issues: 0
- 
            Metadata Files:
            - Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- Funding: .github/FUNDING.yml
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
 
Awesome Lists containing this project
- awesome-vue-3 - @casthub/embed - iFrame Hook with cross-origin (a)synchronous IPC (Packages)
README
          
`@evilkiwi/embed` provides a single Vue 3 hook which can be used to communicate between an iFrame and its parent via `postMessage` IPC.
- `sync`/`async` messaging/responses
- Configurable timeouts
- Bi-directional communication
- Cross-origin support
- Same usage/API for both Host & Client
- Support for enforcing origins for increased security
- No limit to number of instances you can use/create at any given time
- TypeScript
- Tiny (1.73kb)
## Installation
This package is available via NPM:
```bash
yarn add @evilkiwi/embed
# or
npm install @evilkiwi/embed
```
## Usage
For this example, we'll assume the `host` is a webpage (`example.com`) and the `client` is a webpage embedded in an iFrame
(`frame.example.com`). The only difference between a `host` and a `client` is that the `host` requires an iFrame `ref` for binding and
sending the messages.
```vue
/** * Host */
  
import { useEmbed } from '@evilkiwi/embed';
import { onMounted, ref } from 'vue';
const iframe = ref<InstanceType<typeof HTMLIFrame>>();
const { send, events } = useEmbed('host', {
  id: 'shared-id',
  iframe,
  remote: 'https://frame.example.com',
});
// Listen for any synchronous events being emitted over IPC
events.on('yay', payload => {
  console.log(payload);
});
onMounted(async () => {
  // Send an event to the iFrame and wait for a response.
  const response = await send('hello-world', {
    hello: 'world',
  });
});
/** * Client */
  Click me!
import { useEmbed } from '@evilkiwi/embed';
const { handle, post } = useEmbed('client', {
  id: 'shared-id',
  remote: 'https://example.com',
});
// Resolves incoming (a)synchronous operations.
handle('hello-world', async payload => {
  if (payload.hello === 'world') {
    return 'hey';
  }
  return 'go away';
});
const submit = () => {
  // Send a synchronous event to the host
  post('yay', { test: 123 });
};
```
This example shows:
- Initializing the Host and Client
- Sending and waiting for asynchronous events
- Sending and receiving synchronous events
Since communication is bi-directional, you can use **any of the methods on either Host or Client**. For example, asynchronous operations
aren't limited to Host -> Client, the Client can also call asynchronous operations and the Host can register handlers/resolvers.
| **Option** | **Default**             | **Type**                               | **Description**                                                                           |
| ---------- | ----------------------- | -------------------------------------- | ----------------------------------------------------------------------------------------- |
| `id`       | **[Required]**          | `string`                               | The Host and Client that you want to talk to each other should share the \_same\_ ID.     |
| `timeout`  | `15000`                 | `number`                               | Configures the global timeout for all asynchronous operations against this ID pair.       |
| `iframe`   | **[Required for Host]** | `Ref>` | A Vue 3 `ref` for a Template reference.                                                   |
| `remote`   | `*`                     | `string`                               | A remote URL to limit who can recieve/process Events over this Host/Client pair.          |
| `debug`    | `false`                 | `boolean`                              | Whether to print Debug messages to the console, providing an overview of the IPC process. |
### Security Note
By default, if you don't supply a `remote`, the library will process **all** incoming messages and send events that **any** party can
recieve. By setting this to a URL (See above example), you can limit this and hugely reduce the impact it has on security.
## To-do
- Add a test suite