mitt
mitt copied to clipboard
Is it possible to use mitt across two different tabs? Or via an iframe?
I have an odd requirement with a new project which requires me to establish communication between a component running inside of an iframe, although this could be a separate tab, and my main application. I'm using Vue and I know that my vuex store allows me to communicate between the two. Meaning if I have watcher on a store state and I make a change to that state via the 2nd tab / iframe, then the main app will see that change.
It seems though that with my event bus, it does not listen/catch emits from the other tab / iframe.
I'm wondering if maybe there's a way to enable this?
Many thanks
Following up.. at least for my iframe scenario, it seems that simply using parent
does the trick.
So I can do window.Bus = mitt();
on the main app and then inside the Vue instance loaded inside the iframe, I can simply do parent.Bus.emit('something')
and that works. I suppose with a bit of tinkering I'll be able to do the inverse too if needed.
This doesn't solve how to use mitt() to communicate between two browser tabs though, if that's even possible.
@vesper8 Communicating between different tabs is something possible with the SharedWorker
web api, from my understanding it is basically a web worker which can share memory across different threads (browser tabs).
Though keep in mind, that the browser support for the SharedWorker api is not that good. https://developer.mozilla.org/en-US/docs/Web/API/SharedWorker#browser_compatibility
If you come across any other way for communicating accross different tabs (without a browser extension) do share here too!
I was able to get a working implementation to get my event bus to work between the parent app and an iframe by passing the event bus itself to the parent's event bus, which then has a reference to the iframe's event bus. I then store this bus in my store state so it can be easily references anywhere in my app. Bit hacky but works just fine.
As for communicating between two different tabs, I'm using my store state again for this, I was able to achieve this by installing vuex-shared-mutations
which makes the store state accessible across tabs. This is more of a proof of concept as I don't actually need interaction between two tabs, my main goal was to facilitate interaction between an iframe and its parent (both hosted on the same domain). But since I am now able to create watchers on my store's state in different tabs, then I could use that to trigger bus events between tabs.
Hello, you are using the cross-document communication API: window.postmessage (), I wonder if this will solve your problem
I did something similar a decade ago using localStorage events. See https://developer.mozilla.org/en-US/docs/Web/API/Window/storage_event
@DVSoftware That's the right way to go! Closing since IMO the "storagechange"
event is the best option here (and you can wire it up to mitt if you need).
@vesper8 - did you ever manage to figure out the inverse direction as you noted on 5/16?
I have a wrapper around a vue app (so it can be embedded as a shim inside another web app) and need to emit an event from the parent window (straight html/JS, nothing special), into the vue app frame.
Everything works fine in the vue app frame, but I can't seem to reference anything regarding the emitter in the parent context to even try to emit to the child vue app.
The documentation for Mitt says: You can find the library on window.mitt. but that doesn't seem to be true in my case.
@mbcbus from inside the child iframe try window.parent.mitt
- assuming you're using mitt in the parent iframe
Do note that window.mitt
or window.parent.mitt
will only work for UMD bundles which are imported via script tags.
If you're using ESM or CJS, you will have to manually set the emitter on the window object
@mbcbus from inside the child iframe try
window.parent.mitt
- assuming you're using mitt in the parent iframeDo note that
window.mitt
orwindow.parent.mitt
will only work for UMD bundles which are imported via script tags. If you're using ESM or CJS, you will have to manually set the emitter on the window object
I need to go the opposite direction though (sending model updates from the parent, which is not vue, into the child, which is a vue app).
Following up.. at least for my iframe scenario, it seems that simply using
parent
does the trick.So I can do
window.Bus = mitt();
on the main app and then inside the Vue instance loaded inside the iframe, I can simply doparent.Bus.emit('something')
and that works. I suppose with a bit of tinkering I'll be able to do the inverse too if needed.This doesn't solve how to use mitt() to communicate between two browser tabs though, if that's even possible.
I can't get parent.Bus
, maybe my iframe have a different origin with parent origin.