Guia de Início Rápido do Iframe
Esta é a maneira mais rápida de experimentar a API para desenvolvedores sem precisar construir um backend primeiro.
No modo iframe, seu aplicativo se comunica com o componente pai Chastify por meio do postMessage, e o Chastify chama as APIs do servidor em seu nome.
O que Chastify passa para o seu iframe
Ao ser aberto, Chastify coloca uma carga útil JSON em location.hash.
Campos importantes:
bridge.nonce: valor de assinatura da solicitação para mensagens de ponte.bridge.parentOrigin: origem de destino necessária parapostMessage.sessionId: ID da sessão de extensão estável para esta fechadura.lockId: ID de bloqueio ativo.ui: valores do tema da página pai.- Opcional:
homeActionSlug,homeAction,intent,regularActionsSummary,mainToken.
Guia rápido para usar a Bridge Library (Recomendado)
Utilize os auxiliares de apps/extension/src/lib/ChastifyBridge.ts:
parseHashPayload()ChastifyBridgeClientstartAutoResizeToParent(...)themeVars(...)
Bootstrap React minimalista
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>
);
}
Exemplo bruto de postMessage (sem classe auxiliar)
Caso não utilize o código ChastifyBridgeClient, envie o envelope de solicitação completo manualmente:
const req = {
type: "chastify:ext:req",
v: 1,
id: crypto.randomUUID(),
nonce,
action: "session.get",
payload: {},
};
window.parent.postMessage(req, parentOrigin);
Ouça atentamente as respostas correspondentes:
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);
});
Fluxo de teste que você deve executar primeiro
session.getstate.getmetadata.getregularActions.get
Isso confirma a autenticação da ponte, leituras seguras e o tratamento de solicitações/respostas. As gravações de estado devem ser realizadas pelo seu backend com as credenciais da API de desenvolvedor.
Upload de arquivos a partir de iframe
Se sua extensão precisar de imagens ou mídia gerada, use os auxiliares de arquivo de ponte. O Chastify carrega o arquivo para o armazenamento gerenciado do R2, retorna um ID de arquivo estável e fornece uma URL assinada de curta duração para renderização.
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;
}
Armazene uploaded.file.id, não a URL assinada. URLs assinadas expiram e devem ser atualizadas com files.get / client.filesGet(...) quando o iframe for carregado novamente.
Suporte a temas (ui + themeVars)
Chastify passa um objeto ui no hash do iframe.
themeVars(ui) converte isso em tokens de design utilizáveis:
pageBgtextpanelbordermutedinputBg
Use esses valores como estilo base da sua extensão para que seu iframe corresponda ao tema do host.
Atualizações de temas ao vivo
O processo pai pode enviar eventos chastify:ext:ui enquanto seu iframe estiver aberto.
Se você deseja sincronização de temas em tempo real, fique atento a esse evento e atualize o estado do tema local.
Para obter detalhes sobre o tratamento de temas claros/escuros, exemplos de contraste e padrões do Tailwind, consulte Temas de Iframe.
Suporte para redimensionamento automático
Use startAutoResizeToParent(...) para que o elemento pai possa redimensionar o iframe de acordo com o seu conteúdo.
Por que isso é importante:
- Impede que a rolagem fique travada dentro do iframe.
- Mantém os modais de configuração e as páginas de extensão com o tamanho correto.
- Funciona bem para seções dinâmicas que se expandem e se recolhem.
Erros comuns
- Código
targetOriginincorreto (deve corresponder abridge.parentOrigin). - Código
nonceausente ou desatualizado. - Não chamando
destroy()na desmontagem paraChastifyBridgeClient. - Envio de ações não suportadas sem verificar primeiro as capacidades do
session.get.
Arquivos de referência
apps/extension/src/lib/ChastifyBridge.tsapps/extension/src/pages/MainPage.tsxapps/extension/src/pages/SetupPage.tsx