ReactifySDK · React
Custom elements work in JSX, but the script must run in the browser once. Use a tiny client component to inject the bundle; keep thread markup in the same subtree so layout is predictable.
In-page recorder vs hosted record page
WordPress shows a popup for "React To This" / "Stitch this" because the plugin sets window.reactifyWprtEmbed.apiKey before reactify.js runs. A script-only React install without that bootstrap turns those CTAs into links to https://api.reactionsaas.com/reactify/record. Set apiKey (and base) the same way below to get the WordPress-style modal.
1. Client-only script loader (with apiKey)
Bootstrap before appending the script. Use your publishable Reactify API key from the dashboard (same key the WordPress plugin stores).
// ReactifyLoader.tsx — mark "use client"
import { useEffect } from "react";
const SRC = "https://reactify-cdn.s3.us-east-2.amazonaws.com/reactify.js?v=1.1.34";
const APP_BASE = "https://api.reactionsaas.com";
declare global {
interface Window {
reactifyWprtEmbed?: { base: string; apiKey: string };
reactifyShopifyEmbed?: { base: string; apiKey: string };
REACTIFY_EMBED_BASE?: string;
}
}
/** Same gate WordPress/Shopify use: apiKey → in-page recorder; no key → opens https://api.reactionsaas.com/reactify/record. */
function bootstrapReactifyEmbed(apiKey: string) {
const cfg = { base: APP_BASE.replace(/\/+$/, ""), apiKey: apiKey.trim() };
window.reactifyWprtEmbed = cfg;
window.reactifyShopifyEmbed = cfg;
window.REACTIFY_EMBED_BASE = cfg.base;
}
export function ReactifyLoader({ apiKey }: { apiKey: string }) {
useEffect(() => {
if (typeof window === "undefined") return;
bootstrapReactifyEmbed(apiKey);
if (document.querySelector(`script[src="${SRC}"]`)) return;
const s = document.createElement("script");
s.src = SRC;
s.async = true;
document.body.appendChild(s);
}, [apiKey]);
return null;
}2. Use the element
Prefer a concrete thread id for beat/stitch popups. Template-only shells may still deep-link to the hosted record page. TypeScript may warn on unknown intrinsic elements—add a reactify-thread declaration in a *.d.ts or suppress per line as below.
import { ReactifyLoader } from "./ReactifyLoader";
export function ThreadSection() {
const apiKey = process.env.REACT_APP_REACTIFY_API_KEY ?? ""; // or VITE_REACTIFY_API_KEY
return (
<>
<ReactifyLoader apiKey={apiKey} />
{/* eslint-disable-next-line react/no-unknown-property */}
<reactify-thread
thread="YOUR_THREAD_ID"
data-base="https://api.reactionsaas.com"
/>
</>
);
}Strict mode & Fast Refresh
Guard script injection with a DOM query (shown above) so double mount in development does not insert two tags. Thread state lives in the custom element; remounting the React tree recreates the element and refetches—pin keys if you need stability across navigations.