Быстрый старт с использованием Iframe
Это самый быстрый способ опробовать API для разработчиков, не создавая предварительно бэкэнд.
В режиме iframe ваше приложение взаимодействует с родительским элементом Chastify через postMessage, а Chastify вызывает серверные API от вашего имени.
Что передает Chastify вашему iframe
При открытии Chastify помещает полезную нагрузку в формате JSON в location.hash.
Важные поля:
bridge.nonce: запрос значения подписи для сообщений моста.bridge.parentOrigin: требуется целевая точка отсчета дляpostMessage.sessionId: идентификатор стабильной сессии расширения для этой блокировки.lockId: идентификатор активной блокировки.ui: значения темы с родительской страницы.- Дополнительные опции:
homeActionSlug,homeAction,intent,regularActionsSummary,mainToken.
Быстрый старт с библиотекой Bridge (рекомендуется)
Используйте вспомогательные функции из apps/extension/src/lib/ChastifyBridge.ts:
parseHashPayload()ChastifyBridgeClientstartAutoResizeToParent(...)themeVars(...)
Минималистичный React Bootstrap
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>
);
}
Пример кода postMessage без вспомогательных классов.
Если вы не используете код ChastifyBridgeClient, отправьте полный запрос вручную:
const req = {
type: "chastify:ext:req",
v: 1,
id: crypto.randomUUID(),
nonce,
action: "session.get",
payload: {},
};
window.parent.postMessage(req, parentOrigin);
Прислушайтесь к совпадениям в ответах:
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);
});
Сначала следует запустить тестовый сценарий.
session.getstate.getmetadata.getregularActions.get
Это подтверждает аутентификацию моста, безопасное чтение и обработку запросов/ответов. Запись состояния должна выполняться вашим бэкэндом с использованием учетных данных API разработчика.
Загрузка файлов из iframe
Если вашему расширению требуются изображения или сгенерированные медиафайлы, используйте вспомогательные функции для работы с файлами-мостами. Chastify загружает файл в управляемое хранилище R2, возвращает стабильный идентификатор файла и предоставляет вам кратковременный подписанный URL-адрес для рендеринга.
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;
}
Сохраняйте uploaded.file.id, а не подписанный URL. Подписанные URL-адреса истекают и должны быть обновлены на files.get / client.filesGet(...) при повторной загрузке iframe.
Поддержка тем оформления (ui + themeVars)
Chastify передает объект ui в хеше iframe.
themeVars(ui) преобразует его в пригодные для использования дизайн-токены:
pageBgtextpanelbordermutedinputBg
Используйте эти значения в качестве базового стиля вашего расширения, чтобы ваш iframe соответствовал теме оформления основного сайта.
Обновления тем в реальном времени
Родительский элемент может отправлять события chastify:ext:ui, пока ваш iframe открыт.
Если вам нужна синхронизация темы в реальном времени, отслеживайте это событие и обновляйте локальное состояние темы.
Для получения подробной информации об обработке светлой/темной темы, примерах контраста и шаблонах Tailwind см. Iframe Theming.
Поддержка автоматического изменения размера
Используйте startAutoResizeToParent(...), чтобы родительский элемент мог изменять размер iframe в соответствии с вашим содержимым.
Почему это важно:
- Предотвращает ловушки прокрутки внутри iframe.
- Обеспечивает корректное отображение размеров модальных окон настройки и страниц расширений.
- Хорошо подходит для динамических разделов, которые разворачиваются/сворачиваются.
Распространенные ошибки
- Неверный
targetOrigin(должен совпадать сbridge.parentOrigin). - Отсутствует или устарел код
nonce. - При размонтировании
ChastifyBridgeClientне вызываетсяdestroy(). - Отправка неподдерживаемых действий без предварительной проверки возможностей
session.get.
Справочные файлы
apps/extension/src/lib/ChastifyBridge.tsapps/extension/src/pages/MainPage.tsxapps/extension/src/pages/SetupPage.tsx