How to: share content across surfaces
You want to render content somewhere other than its own JSX/template position — a toast, an overlay — and need to know which mechanism applies.
Same surface: createPortal (React) / Teleport (Vue)
Section titled “Same surface: createPortal (React) / Teleport (Vue)”Both move content to an already-mounted node within the same mounted surface as the call site:
// Reactconst [overlay, setOverlay] = useState<IHostInstance | null>(null);// ...<View ref={setOverlay} />{overlay ? createPortal(<Text>ported in</Text>, overlay) : null}<!-- Vue --><Teleport v-if="toastVisible && overlayHost" :to="overlayHost"> <Text>Ported via Teleport</Text></Teleport><View ref="overlayHost" />Use a state/ref callback (useState, not useRef, on React) so the target
resolves once it actually commits — a plain ref is null on the entire first
render.
Cross surface: createTunnel
Section titled “Cross surface: createTunnel”For content that must reach a genuinely different, separately-mounted
surface, use createTunnel() instead — a shared store, not a node reference:
// React — module-level singleton, importable from any surfaceexport const overlayTunnel = createTunnel();
// wherever it should paint:<overlayTunnel.Out />// wherever the content originates, any surface:<overlayTunnel.In><ToastCard /></overlayTunnel.In><!-- Vue --><tunnel.Out /><tunnel.In><Text>Ported via createTunnel</Text></tunnel.In>In/Out are components, not hooks/composables — an earlier hook-based
React version caused a genuine infinite render loop (the shared store’s
notify() re-rendering the same component that also called the write side).
As separate components, Out’s forced re-render never bounces back into
In, even when they’re siblings.
Picking one
Section titled “Picking one”- Overlay host lives in the same tree you’re already rendering →
createPortal/Teleport. - Content needs to reach a different
mount()root entirely (split-screen, an always-on-top system surface) →createTunnel.
Import both from your adapter’s package (@symbiote-native/react, @symbiote-native/vue,
@symbiote-native/angular). Full design rationale and the Angular directive-based
twins (*portal, *tunnelIn, <tunnel-out>):
react-adapter-portal,
vue-adapter-directives,
and
angular-adapter-portal.