Thèmes des iframes
Chastify envoie des informations de thème aux extensions iframe afin que votre interface utilisateur puisse correspondre à la page de verrouillage dans laquelle elle est intégrée.
Ne présumez pas que l'utilisateur utilise un thème sombre. Votre extension peut s'ouvrir avec des thèmes clairs, sombres, personnalisés, translucides et à contraste élevé.
La valeur par défaut la plus sûre consiste à considérer la charge utile de l'iframe ui comme la source de vérité pour l'arrière-plan de la page, la couleur du texte et la couleur de la bordure, puis à dériver vos propres panneaux et badges lisibles à partir de ui.isDark.
Charge utile du thème
Lorsque Chastify ouvre votre iframe, il ajoute une charge utile JSON encodée en URI à location.hash.
La charge utile comprend 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"
}
}
Significations des champs :
ui.isDark: indique si la page hôte utilise actuellement un thème sombre.ui.bg: arrière-plan de la page/surface provenant de l’hôte. Il peut s’agir d’une couleur ou d’un arrière-plan CSS complexe.ui.text: couleur de texte lisible principale.ui.border: couleur de bordure correspondant au thème hôte.
ui.bg peut être une chaîne CSS complète définissant l'arrière-plan, et non pas seulement une couleur hexadécimale. Utilisez-la comme valeur CSS background, et non comme une valeur à analyser manuellement.
Analyser le hachage
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;
}
}
Variables CSS minimales
Convertissez la charge utile en variables CSS une seule fois au démarrage :
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";
Utilisez ces variables dans le shell de votre application :
html,
body,
#root {
min-height: 100%;
margin: 0;
}
body {
background: var(--chastify-bg);
color: var(--chastify-text);
}
.panel {
border: 1px solid var(--chastify-border);
}
Exemple 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>
);
}
Modèle de vent arrière
Si vous utilisez Tailwind, créez une branche à partir de ui.isDark pour chaque surface contenant du texte.
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";
Utilisez les classes choisies pour l'affichage du texte :
<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>
Mises à jour en direct du thème
Le parent peut envoyer des mises à jour de thème en direct pendant que votre iframe est ouvert :
type UiUpdateMessage = {
type: "chastify:ext:ui";
v: 1;
nonce: string;
ui: {
isDark?: boolean;
bg?: string;
text?: string;
border?: string;
};
};
Écoutez ce message et vérifiez le 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);
});
Erreurs courantes
- Intégration en dur de
text-whiteou detext-*-100pâle dans les cartes sans alternative de thème clair. - J'ai mis en forme l'arrière-plan de la page, mais j'ai oublié les cartes imbriquées, les badges, les anneaux de progression et les flux de résultats.
ui.bgest interprété comme une simple couleur hexadécimale. Il peut s'agir d'un dégradé ou d'une chaîne de fond CSS normalisée par le navigateur.- L'utilisation des contrôles de formulaire natifs sans définir la couleur d'arrière-plan ni celle du texte peut rendre les options de sélection illisibles dans les thèmes sombres.
- Un rechargement de l'iframe est probablement nécessaire pour les changements de thème. Écoutez le signal
chastify:ext:uipour recevoir les mises à jour en direct.
Les données thématiques sont uniquement destinées à la présentation. Ne les utilisez pas pour l'autorisation, les décisions de confiance, la logique de déverrouillage, les récompenses, les sanctions ou l'identité de session du serveur.
Liste de contrôle
Avant de publier votre extension iframe :
- Tester le thème clair.
- Tester le thème sombre.
- Tester un thème personnalisé s'il est disponible.
- Vérifiez que toutes les cartes, boutons, badges, contrôles de formulaire, anneaux de progression et messages de résultat présentent un contraste lisible.
- Vérifiez que le texte s'affiche correctement sur mobile.
- Vérifiez que l'iframe se redimensionne automatiquement après les changements de thème ou de contenu.
Suivant : Démarrage rapide Iframe ou Exemples d'API.