iframeのテーマ設定
Chastifyは、iframe拡張機能にテーマ情報を送信し、UIが埋め込まれているロックページと一致するようにします。
ユーザーがダークテーマを使用していると決めつけないでください。拡張機能は、ライト、ダーク、カスタム、半透明、高コントラストなど、さまざまなテーマで開くことができます。
最も安全なデフォルト設定は、iframe の ui ペイロードをページの背景、テキストの色、および境界線の色に関する真の情報源として扱い、その後、ui.isDark から独自の読みやすいパネルとバッジを生成することです。
テーマペイロード
Chastifyがiframeを開くと、URIエンコードされたJSONペイロードがlocation.hashに追加されます。
ペイロードにはuiが含まれています。
{
"bridge": {
"v": 1,
"nonce": "request-nonce",
"parentOrigin": "https://chastify.net"
},
"sessionId": "extension-session-id",
"lockId": "lock-id",
"ui": {
"isDark": true,
"bg": "rgb(10, 10, 10)",
"text": "#e5e7eb",
"border": "#27272a"
}
}
フィールドの意味:
ui.isDark: ホストページが現在ダークテーマを使用しているかどうか。ui.bg: ホストからのページ/サーフェスの背景。これは色または複雑なCSS背景の場合があります。ui.text: 主要な読みやすいテキストの色。ui.border: ホストテーマに一致する枠線の色。
ui.bg は、単なる 16 進数カラーコードではなく、完全な CSS 背景文字列として使用できます。手動で解析する値としてではなく、CSS の値として background を使用してください。
ハッシュを解析する
type ChastifyThemePayload = {
ui?: {
isDark?: boolean;
bg?: string;
text?: string;
border?: string;
};
};
export function parseHashPayload(): ChastifyThemePayload | null {
const raw = window.location.hash.startsWith("#")
? window.location.hash.slice(1)
: window.location.hash;
if (!raw) return null;
try {
return JSON.parse(decodeURIComponent(raw));
} catch {
return null;
}
}
最小限のCSS変数
起動時にペイロードをCSS変数に変換する:
const payload = parseHashPayload();
const ui = payload?.ui ?? {};
const isDark = ui.isDark !== false;
document.documentElement.style.setProperty("--chastify-bg", ui.bg || (isDark ? "#040711" : "#f8fafc"));
document.documentElement.style.setProperty("--chastify-text", ui.text || (isDark ? "#e5e7eb" : "#0f172a"));
document.documentElement.style.setProperty("--chastify-border", ui.border || (isDark ? "#27272a" : "#e2e8f0"));
document.documentElement.dataset.themeMode = isDark ? "dark" : "light";
アプリシェルでこれらの変数を使用してください。
html,
body,
#root {
min-height: 100%;
margin: 0;
}
body {
background: var(--chastify-bg);
color: var(--chastify-text);
}
.panel {
border: 1px solid var(--chastify-border);
}
Reactの例
import { useMemo } from "react";
function getTheme(payload: any) {
const ui = payload?.ui ?? {};
const isDark = ui.isDark !== false;
return {
isDark,
pageStyle: {
background: ui.bg || (isDark ? "#040711" : "#f8fafc"),
color: ui.text || (isDark ? "#e5e7eb" : "#0f172a"),
} satisfies React.CSSProperties,
panelClass: isDark
? "border-white/10 bg-black/35 text-slate-100"
: "border-slate-200 bg-white/85 text-slate-950 shadow-sm",
mutedClass: isDark ? "text-slate-400" : "text-slate-600",
badgeClass: isDark
? "bg-sky-400/15 text-sky-200"
: "bg-sky-50 text-sky-900 ring-1 ring-sky-200",
};
}
export function ExtensionApp({ payload }: { payload: any }) {
const theme = useMemo(() => getTheme(payload), [payload]);
return (
<main style={theme.pageStyle} className="min-h-screen p-4">
<section className={`rounded-2xl border p-4 ${theme.panelClass}`}>
<h1 className="text-xl font-bold">My Extension</h1>
<p className={`mt-2 text-sm ${theme.mutedClass}`}>
This text stays readable on light and dark Chastify themes.
</p>
<span className={`mt-3 inline-flex rounded-full px-3 py-1 text-xs font-semibold ${theme.badgeClass}`}>
Connected
</span>
</section>
</main>
);
}
追い風パターン
Tailwindを使用する場合は、テキストを含むすべてのサーフェスに対して、ui.isDarkから分岐してください。
const isDarkTheme = payload?.ui?.isDark !== false;
const panelClass = isDarkTheme
? "border-white/10 bg-black/30 text-slate-100"
: "border-slate-200 bg-white/85 text-slate-950 shadow-sm";
const successClass = isDarkTheme
? "border-emerald-300/20 bg-emerald-400/10 text-emerald-100"
: "border-emerald-500/25 bg-emerald-50 text-emerald-950";
const errorClass = isDarkTheme
? "border-rose-300/20 bg-rose-400/10 text-rose-100"
: "border-rose-500/25 bg-rose-50 text-rose-950";
テキストを表示する場所に、選択したクラスを使用してください。
<div className={`rounded-xl border px-3 py-2 text-sm ${result.ok ? successClass : errorClass}`}>
<div className="font-semibold">{result.title}</div>
<div className="mt-1 opacity-85">{result.message}</div>
</div>
ライブテーマアップデート
親テーマは、iframeが開いている間にリアルタイムのテーマアップデートを送信する場合があります。
type UiUpdateMessage = {
type: "chastify:ext:ui";
v: 1;
nonce: string;
ui: {
isDark?: boolean;
bg?: string;
text?: string;
border?: string;
};
};
そのメッセージを聞き取り、nonceを検証してください。
const nonce = payload.bridge.nonce;
const parentOrigin = payload.bridge.parentOrigin;
window.addEventListener("message", (event) => {
if (event.origin !== parentOrigin) return;
const msg = event.data as Partial<UiUpdateMessage>;
if (msg.type !== "chastify:ext:ui" || msg.v !== 1) return;
if (msg.nonce !== nonce) return;
applyTheme(msg.ui);
});
よくある間違い
- ライトテーマの代替案がないカード内に、
text-whiteまたは淡いtext-*-100をハードコーディングする。 - ページの背景をスタイリングしたが、ネストされたカード、バッジ、プログレスリング、結果フィードを忘れてしまった。
ui.bgを単純な16進数カラーとして扱います。グラデーションまたはブラウザで正規化されたCSSの背景文字列である可能性があります。- 背景色と文字色の両方を設定せずにネイティブのフォームコントロールを使用すると、ダークテーマでは選択オプションが読みにくくなる場合があります。
- テーマ変更にはiframeの再読み込みが必要だと想定しています。リアルタイム更新をご希望の場合は、
chastify:ext:uiをリッスンしてください。
テーマデータは表示データのみです。認証、信頼性判断、ロック解除ロジック、報酬、罰則、またはバックエンドセッションの識別には使用しないでください。
チェックリスト
iframe拡張機能を公開する前に:
- ライトテーマをテストします。
- ダークテーマをテストする。
- 利用可能な場合は、カスタムテーマをテストしてください。
- すべてのカード、ボタン、バッジ、フォームコントロール、プログレスリング、および結果メッセージのコントラストが読みやすいことを確認してください。
- テキストがモバイル端末にもきちんと収まることを確認してください。
- テーマやコンテンツの変更後にiframeが自動的にリサイズされることを確認してください。
次へ:Iframe クイックスタート または API サンプル。