React Host
This page covers embedding Myop components in a host React app using
@myop/react. If you want to author a Myop component, see the
CLI guide instead.
Looking for the API reference?
@myop/reactreference ยท Single-file SDK reference
Installationโ
npm install @myop/react @myop/sdk
@myop/sdk is a peer dependency. Requires React 18+.
Minimal exampleโ
import { MyopComponent } from "@myop/react";
export function App() {
return (
<MyopComponent
componentId="your-component-id"
data={{ title: "Hello", items: ["a", "b"] }}
onItemSelected={(payload) => console.log(payload)}
style={{ width: 400, height: 300 }}
/>
);
}
That's the whole contract. componentId is a UUID from the
Myop dashboard. Everything else is optional.
CTA actions emitted by the component show up as on<PascalCase> props on the
host โ see Receiving events below.
Always use <MyopComponent>. Never hand-roll an <iframe> pointing at a
Myop component โ the SDK handles iframe lifecycle, messaging, sizing,
caching, and error recovery for you.
Passing data inโ
The data prop is delivered to the component's myop_init_interface. It's
reactive โ updates trigger a re-init inside the iframe:
const [count, setCount] = useState(0);
<MyopComponent
componentId="counter"
data={{ count }}
/>
data can be any JSON-serializable value. Functions are not transferred.
Receiving events (CTA handlers)โ
Components emit CTA events via myop_cta_handler(action, payload). The host
receives them through typed per-action props โ kebab-case actions become
onPascalCase props. This is the canonical form; use it in new code.
<MyopComponent
componentId="task-list"
data={{ tasks }}
onTaskToggled={({ taskId, completed }) => {
setTasks((prev) =>
prev.map((t) => (t.id === taskId ? { ...t, completed } : t))
);
}}
onTaskDeleted={({ taskId }) => {
setTasks((prev) => prev.filter((t) => t.id !== taskId));
}}
/>
| Component CTA action | React prop |
|---|---|
item-selected | onItemSelected |
form-submitted | onFormSubmitted |
task-toggled | onTaskToggled |
Fallback: generic handlerโ
For dynamically named actions or quick experiments, a generic on prop
receives every event. Use this only when the typed form doesn't fit:
<MyopComponent
componentId="task-list"
data={{ tasks }}
on={(action, payload) => {
if (action === "task-toggled") setTasks(/* ... */);
}}
/>
Don't mix on with on<Action> props for the same action โ pick one per
component instance.
Propsโ
| Prop | Type | Description |
|---|---|---|
componentId | string | Myop component UUID |
data | TData | Passed to myop_init_interface; reactive |
on | (action, payload) => void | Generic CTA handler |
on[ActionName] | (payload) => void | Typed handler for one CTA |
onLoad | (component) => void | Fired after load completes |
onError | (error: string) => void | Fired on load failure |
style | CSSProperties | Container styles |
loader | ReactNode | Custom loading indicator |
fallback | ReactNode | Custom error fallback |
autoSize | boolean | Auto-size container to content |
environment | string | Load from a specific environment |
preview | boolean | Load unpublished preview version |
Auto-generated typed packagesโ
Every Myop component has an auto-generated npm package that bakes in the
componentId and exposes a fully-typed component:
npm install https://cloud.myop.dev/npm/{componentId}/react
import { TaskList } from "@myop/task-list";
<TaskList
data={{ tasks }}
onTaskToggled={(payload) => {
// payload is typed: { taskId: string; completed: boolean }
}}
/>
Recommended for production. Types come from the component's
<script type="myop/types"> block.
Preloadingโ
Eagerly fetch components to avoid loading delay on first render:
import { preloadComponents, isPreloaded } from "@myop/react";
await preloadComponents(["id-1", "id-2"]);
Local devโ
Point the SDK at a local component dev server (port 9292 by default):
import { enableLocalDev } from "@myop/react";
if (import.meta.env.DEV) enableLocalDev();
You can also enable via a URL param without code changes โ open the app with
?env=dev.
Run a component locally with:
cd path/to/your-component
npx myop dev
The dev server registers the component with the local repository and hot-reloads on file changes.
Configurationโ
All SDKs export the same configuration functions:
import {
enableLocalDev,
setCloudRepositoryUrl,
setEnvironment,
} from "@myop/react";
enableLocalDev(); // Load from localhost:9292
setCloudRepositoryUrl("https://custom"); // Custom cloud URL
setEnvironment("staging"); // Default environment
Where to nextโ
- Auto-generated packages โ typed components, baked-in
componentId - System architecture โ how the host, cloud, and component runtime fit together
@myop/reactreference โ full type signatures- Host integration (all frameworks) โ same flow for Vue, Angular, React Native