Tematizzazione Iframe
Chastify invia informazioni sul tema alle estensioni iframe in modo che l'interfaccia utente possa adattarsi alla pagina di blocco in cui è incorporata.
Non dare per scontato che l'utente stia utilizzando un tema scuro. La tua estensione può essere aperta con temi chiari, scuri, personalizzati, trasparenti e ad alto contrasto.
L'impostazione predefinita più sicura è considerare il payload ui dell'iframe come fonte di riferimento per lo sfondo della pagina, il colore del testo e il colore del bordo, quindi derivare i propri pannelli e badge leggibili da ui.isDark.
Payload del tema
Quando Chastify apre il tuo iframe, aggiunge un payload JSON codificato in URI a location.hash.
Il payload include 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"
}
}
Significato dei campi:
ui.isDark: indica se la pagina host sta attualmente utilizzando un tema scuro.ui.bg: sfondo della pagina/superficie dall'host. Può essere un colore o uno sfondo CSS complesso.ui.text: colore primario del testo leggibile.ui.border: colore del bordo che corrisponde al tema host.
ui.bg può essere una stringa CSS completa per lo sfondo, non solo un codice colore esadecimale. Usalo come valore CSS background, non come un valore da analizzare manualmente.
Analizza l'hash
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;
}
}
Variabili CSS minime
Converti il payload in variabili CSS una sola volta all'avvio:
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";
Utilizza queste variabili nella shell della tua app:
html,
body,
#root {
min-height: 100%;
margin: 0;
}
body {
background: var(--chastify-bg);
color: var(--chastify-text);
}
.panel {
border: 1px solid var(--chastify-border);
}
Esempio 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>
);
}
Schema di vento a favore
Se si utilizza Tailwind, creare un ramo da ui.isDark per ogni superficie che contiene testo.
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";
Utilizza le classi selezionate dove viene visualizzato il testo:
<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>
Aggiornamenti del tema in tempo reale
Il genitore potrebbe inviare aggiornamenti del tema in tempo reale mentre l'iframe è aperto:
type UiUpdateMessage = {
type: "chastify:ext:ui";
v: 1;
nonce: string;
ui: {
isDark?: boolean;
bg?: string;
text?: string;
border?: string;
};
};
Ascolta quel messaggio e verifica il 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);
});
Errori comuni
- Codifica fissa
text-whiteotext-*-100chiaro all'interno delle schede senza un'alternativa a tema chiaro. - Personalizzare lo sfondo della pagina, ma dimenticare le schede annidate, i badge, gli anelli di avanzamento e i feed dei risultati.
ui.bgviene trattato come un semplice colore esadecimale. Può trattarsi di una sfumatura o di una stringa di sfondo CSS normalizzata dal browser.- Utilizzo dei controlli nativi dei moduli senza impostare sia il colore di sfondo che quello del testo. Le opzioni selezionate potrebbero risultare illeggibili nei temi scuri.
- Si presume che sia necessario ricaricare l'iframe per le modifiche al tema. Ascolta
chastify:ext:uise desideri ricevere aggiornamenti in tempo reale.
I dati del tema sono esclusivamente dati di presentazione. Non utilizzarli per l'autorizzazione, le decisioni di fiducia, la logica di sblocco, i premi, le punizioni o l'identità della sessione di backend.
Lista di controllo
Prima di pubblicare l'estensione iframe:
- Tema chiaro di prova.
- Prova il tema scuro.
- Se disponibile, prova un tema personalizzato.
- Verifica che tutte le schede, i pulsanti, i badge, i controlli dei moduli, gli anelli di avanzamento e i messaggi dei risultati abbiano un contrasto leggibile.
- Verifica che il testo si adatti ancora ai dispositivi mobili.
- Verifica che l'iframe si ridimensioni automaticamente dopo modifiche al tema o al contenuto.
Successivamente: Guida rapida all'iframe o Esempi API.