Szybki start dla iframe
To najszybszy sposób wypróbowania interfejsu API dla programistów bez konieczności wcześniejszego tworzenia zaplecza.
W trybie iframe Twoja aplikacja komunikuje się z elementem nadrzędnym Chastify za pośrednictwem postMessage, a Chastify wywołuje interfejsy API serwera w Twoim imieniu.
Co Chastify przekazuje do Twojej ramki iframe
Po otwarciu Chastify umieszcza ładunek JSON w location.hash.
Ważne pola:
bridge.nonce: żąda wartości podpisu dla komunikatów mostu.bridge.parentOrigin: wymagany początek docelowy dlapostMessage.sessionId: identyfikator stabilnej sesji rozszerzenia dla tej blokady.lockId: identyfikator aktywnej blokady.ui: wartości motywu ze strony nadrzędnej.- Opcjonalnie:
homeActionSlug,homeAction,intent,regularActionsSummary,mainToken.
Szybki start z biblioteką Bridge (zalecane)
Użyj pomocników z apps/extension/src/lib/ChastifyBridge.ts:
parseHashPayload()ChastifyBridgeClientstartAutoResizeToParent(...)themeVars(...)
Minimalny bootstrap Reacta
import { useEffect, useMemo, useState } from "react";
import {
parseHashPayload,
ChastifyBridgeClient,
startAutoResizeToParent,
themeVars,
} from "../lib/ChastifyBridge";
const payload = parseHashPayload();
if (!payload?.bridge?.nonce || !payload?.bridge?.parentOrigin) {
throw new Error("Missing bridge payload in iframe hash");
}
export function App() {
const [client, setClient] = useState<ChastifyBridgeClient | null>(null);
const [session, setSession] = useState<any>(null);
const [stateDoc, setStateDoc] = useState<any>(null);
const vars = useMemo(() => themeVars(payload.ui ?? null), []);
useEffect(() => {
const c = new ChastifyBridgeClient({
nonce: payload.bridge!.nonce,
targetOrigin: payload.bridge!.parentOrigin,
});
setClient(c);
return () => c.destroy();
}, []);
useEffect(() => {
if (!client) return;
(async () => {
const s = await client.request("session.get", {});
setSession(s);
const st = await client.request("state.get", {});
setStateDoc(st);
})().catch(console.error);
}, [client]);
useEffect(() => {
return startAutoResizeToParent({
nonce: payload.bridge!.nonce,
targetOrigin: payload.bridge!.parentOrigin,
extraPx: 12,
});
}, []);
return (
<div style={{ background: vars.pageBg, color: vars.text, minHeight: "100%" }}>
<h2>Extension Quickstart</h2>
<pre>{JSON.stringify(session, null, 2)}</pre>
<pre>{JSON.stringify(stateDoc, null, 2)}</pre>
</div>
);
}
Surowy przykład postMessage (bez klasy pomocniczej)
Jeżeli nie używasz ChastifyBridgeClient, wyślij ręcznie pełną kopertę żądania:
const req = {
type: "chastify:ext:req",
v: 1,
id: crypto.randomUUID(),
nonce,
action: "session.get",
payload: {},
};
window.parent.postMessage(req, parentOrigin);
Posłuchaj pasujących odpowiedzi:
window.addEventListener("message", (event) => {
if (event.origin !== parentOrigin) return;
const msg = event.data;
if (!msg || msg.type !== "chastify:ext:resp" || msg.v !== 1) return;
if (msg.id !== req.id) return;
if (msg.ok) console.log("Bridge success:", msg.data);
else console.error("Bridge error:", msg.error);
});
Przepływ testowy, który należy uruchomić jako pierwszy
session.getstate.getmetadata.getregularActions.get
Potwierdza to uwierzytelnianie mostu, bezpieczne odczyty oraz obsługę żądań/odpowiedzi. Zapisy stanu muszą być wykonywane przez zaplecze z użyciem poświadczeń API dla programistów.
Przesyłanie plików z ramki iframe
Jeśli Twoje rozszerzenie potrzebuje obrazów lub generowanych multimediów, skorzystaj z pomocy plików pomostowych. Chastify przesyła do zarządzanej pamięci masowej R2, zwraca stabilny identyfikator pliku i podaje krótkotrwały podpisany adres URL do renderowania.
const capabilities = await client.filesCapabilities();
if (capabilities.enabled) {
const uploaded = await client.filesUpload({
file,
filename: file.name,
purpose: "puzzle-image",
});
// Send uploaded.file.id to your backend if it should be stored in session state.
const refreshed = await client.filesGet(uploaded.file.id);
image.src = refreshed.file.signedUrl;
}
Przechowuj kod uploaded.file.id, a nie podpisany adres URL. Podpisane adresy URL wygasają i należy je odświeżyć kodem files.get / client.filesGet(...) po ponownym załadowaniu ramki iframe.
Obsługa motywów (ui + themeVars)
Chastify przekazuje obiekt ui w skrócie iframe.
themeVars(ui) konwertuje je na użyteczne tokeny projektowe:
pageBgtextpanelbordermutedinputBg
Użyj tych wartości jako bazowego stylu swojego rozszerzenia, aby Twoja ramka iframe pasowała do motywu hosta.
Aktualizacje motywu na żywo
Element nadrzędny może wysyłać zdarzenia chastify:ext:ui, gdy ramka iframe jest otwarta.
Jeśli chcesz zsynchronizować motyw na żywo, nasłuchuj tego zdarzenia i aktualizuj lokalny stan motywu.
Szczegółowe informacje na temat obsługi jasnego/ciemnego motywu, przykładów kontrastu i wzorców Tailwind można znaleźć w artykule Motywy iframe.
Obsługa automatycznej zmiany rozmiaru
Użyj startAutoResizeToParent(...), aby element nadrzędny mógł dostosować rozmiar ramki iframe do Twojej zawartości.
Dlaczego to jest ważne:
- Zapobiega powstawaniu pułapek przewijania wewnątrz ramki iframe.
- Utrzymuje prawidłowy rozmiar okien instalacyjnych i stron rozszerzeń.
- Dobrze sprawdza się w przypadku dynamicznych sekcji, które rozwijają się/zwijają.
Typowe błędy
- Nieprawidłowy kod
targetOrigin(musi pasować do kodubridge.parentOrigin). - Brakujący lub nieaktualny kod
nonce. - Nie wywołano
destroy()podczas odmontowywaniaChastifyBridgeClient. - Wysyłanie nieobsługiwanych akcji bez wcześniejszego sprawdzenia możliwości
session.get.
Pliki referencyjne
apps/extension/src/lib/ChastifyBridge.tsapps/extension/src/pages/MainPage.tsxapps/extension/src/pages/SetupPage.tsx