El Editor de HTML muestra tu código y la página uno al lado del otro. Lo que escribes aparece al instante en la vista previa (encabezados, listas, tablas, imágenes y todo tu CSS), y un clic en cualquier cosa de la vista previa te lleva a su lugar en el código. También puedes editar el texto directamente en la vista previa. Así creas rápidamente páginas de aterrizaje, boletines, artículos y formularios sin instalar nada.
Todo se ejecuta en tu navegador. Las páginas no se suben, no hay registro ni publicidad.
Etiquetas, atributos, entidades, comentarios y el CSS y JavaScript de la página con sus propios colores, números de línea, etiquetas de cierre que se cierran solas y una sangría ordenada con un clic.
La página tal como la muestra el navegador, en un marco donde los scripts y los atributos on… nunca se ejecutan y los enlaces no navegan. Revísala a ancho completo, en tamaño de tableta o de móvil.
Haz clic en un encabezado o un párrafo de la vista previa y escribe: el cambio va al código, con &, < y > escritos como entidades.
Etiquetas sin cerrar o mal anidadas, elementos desconocidos, imágenes sin alt, archivos que faltan e ids usados dos veces, cada uno con su línea.
Arrastra archivos al editor y úsalos por su nombre: <img src="../logo.png">, <link rel="stylesheet" href="../style.css">. Se guardan con la página en tu navegador.
El archivo .html, un archivo HTML con todos los archivos dentro, un ZIP con los archivos, un PDF con el diálogo de impresión, o el texto sin formato.
Cualquier página https (y localhost) puede integrar el editor con un <iframe> y ?embed=1, sin registro y sin clave. Integrado, el editor oculta este texto y muestra un botón Guardar. Hay dos formas de meter y sacar el documento.
src= abre un archivo (tu servidor debe permitir CORS), webhook= hace que «Guardar» (Ctrl+S) envíe el documento a esa dirección. Añade &token=… para una cabecera Authorization: Bearer … y &auto para guardar después de cada cambio.
<iframe src="https://html.giit.ch/?embed=1&src=https://your-site.com/pages/offer.html&webhook=https://your-site.com/save.php"
allow="clipboard-write" style="width:100%;height:800px;border:0"></iframe>
El webhook recibe un POST con JSON { editor, event: "save", id, name, content, assets, updated }. Un pequeño script PHP que lo guarda:
<?php
header('Access-Control-Allow-Origin: https://html.giit.ch');
header('Access-Control-Allow-Headers: Content-Type, Authorization');
header('Access-Control-Allow-Methods: POST, OPTIONS');
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') exit;
if (($_SERVER['HTTP_AUTHORIZATION'] ?? '') !== 'Bearer SECRET') { http_response_code(403); exit; }
$d = json_decode(file_get_contents('php://input'), true);
$name = preg_replace('/[^\w\- ]/u', '_', $d['name']);
file_put_contents(__DIR__ . "/pages/$name.html", $d['content']);
echo '{"ok":true}';
El editor dice htmleditor:ready, tu página responde con htmleditor:load, el editor informa con htmleditor:loaded, con htmleditor:change en cada edición real y con htmleditor:save cuando el usuario guarda. Tu página puede enviar htmleditor:get (el estado actual) o htmleditor:save (pulsar Guardar). Así el guardado pasa por tu propio inicio de sesión y tu sesión.
<iframe id="ed" src="https://html.giit.ch/?embed=1" allow="clipboard-write" style="width:100%;height:800px;border:0"></iframe>
<script>
const ed = document.getElementById('ed');
const ORIGIN = 'https://html.giit.ch';
addEventListener('message', async e => {
if (e.source !== ed.contentWindow || e.origin !== ORIGIN) return;
const m = e.data;
if (m.type === 'htmleditor:ready') { // el editor está listo: pásale el documento
ed.contentWindow.postMessage({
type: 'htmleditor:load',
name: 'Offer',
content: await (await fetch('/pages/offer.html')).text(),
assets: { 'logo.png': 'data:image/png;base64,…' } // archivos opcionales
}, ORIGIN);
}
if (m.type === 'htmleditor:change') document.title = '● not saved'; // una edición real
if (m.type === 'htmleditor:save') { // el usuario hizo clic en «Guardar»
await fetch('/api/save', { method: 'POST', headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name: m.name, content: m.content, assets: m.assets }) });
document.title = 'Saved';
}
});
// Un botón de guardar en tu propia página: la respuesta llega como htmleditor:save
function saveNow() { ed.contentWindow.postMessage({ type: 'htmleditor:get' }, ORIGIN); }
</script>
Asistente de IA dentro de tu página: también funciona en el marco. Con allow="clipboard-write" en el iframe, «Copiar prompt» usa el portapapeles directamente (si no, el editor recurre al antiguo comando de copiar o muestra el prompt para copiarlo a mano). Un enlace que envía la IA no puede llegar a un editor dentro de otro sitio web, así que el editor indica a la IA y al usuario que peguen la respuesta completa de la IA en el editor, o que abran el editor en una ventana propia.
window.open("https://html.giit.ch/?embed=window", "htmleditor-17") abre el editor completo en su propia ventana y usa los mismos mensajes con window.opener. Ahí sí le llegan los enlaces de una IA. htmleditor:load también puede llevar context: { host, title, rules } (el prompt de IA dice entonces a dónde pertenece el documento y sigue tus reglas) y hook: { url, token, assets: false }, un webhook solo para este documento que nunca se guarda. Al cerrar la ventana con cambios sin guardar se envía htmleditor:closing.
Pasa al editor tu propio prompt, una dirección en tu sitio y una clave para esta sesión del editor. El diálogo de IA muestra entonces «Conectado a» tu sitio, lo que le dices a la IA y la opción cambiar el documento actual o crear uno nuevo; Copiar prompt lo junta todo. La IA envía su resultado con la clave a tu servidor, y tu página lo abre en el editor: un documento nuevo se abre aparte y se queda en el navegador del usuario. Una clave por sesión del editor: sigue siendo válida mientras el editor esté abierto, y solo mientras no tenga ninguna el editor la pide con htmleditor:key-request. El editor nunca envía la clave por sí mismo ni la guarda; la dirección debe ser https en tu propio host o en un subdominio suyo.
const key = async () => (await fetch('/api/ai-key.php?doc=17')).json(); // una clave por sesión del editor
const k = await key();
ed.contentWindow.postMessage({ type: 'htmleditor:load', name: 'Offer', content, ai: {
label: 'My Site', prompt: 'Keep the [[placeholders]]. Write in German.',
endpoint: 'https://your-site.com/api/ai-result.php', key: k.key } }, ORIGIN);
// recuerda el id de htmleditor:loaded e ignora change/save/closing con otro id
// solo mientras el editor no tenga clave:
if (m.type === 'htmleditor:key-request') { const k = await key(); ed.contentWindow.postMessage({ type: 'htmleditor:ai', key: k.key }, ORIGIN); }
// mientras el editor esté abierto, avisa a tu servidor cada minuto; cerrar el editor o la página anula la clave
setInterval(() => fetch('/api/ai-key.php?alive=' + k.key.slice(0, 8)), 60000);
// tu servidor tiene un resultado (polling, SSE …): target es «current» o «new»
ed.contentWindow.postMessage({ type: 'htmleditor:load', name: 'Offer', content: draft, from: 'ai', target }, ORIGIN);
<?php // api/ai-key.php - la clave de esta sesión del editor del usuario con sesión iniciada (la llama tu página)
session_start(); // comprueba que el usuario puede editar este documento
$key = bin2hex(random_bytes(24));
$_SESSION['ai'][hash('sha256', $key)] = ['doc' => (int)$_GET['doc'], 'seen' => time()]; // o en tu base de datos; ?alive= vuelve a fijar seen
echo json_encode(['key' => $key]);
<?php // api/ai-result.php - la IA envía aquí (sin cabeceras CORS: las IA lo llaman desde un servidor)
$key = preg_replace('/^Bearer\s+/', '', $_SERVER['HTTP_AUTHORIZATION'] ?? '');
$row = find_key(hash('sha256', $key)); // tu base de datos: no anulada, vista en los últimos 3 minutos
if (!$row) { http_response_code(401); exit('{"ok":false,"error":"key not valid"}'); }
$d = json_decode(file_get_contents('php://input', false, null, 0, 2000000), true);
save_draft($row['doc'], $d['content'], $d['target'] === 'new' ? 'new' : 'current'); // tu página lo muestra con htmleditor:load
echo '{"ok":true}';
Crea claves con al menos 128 bits aleatorios, guarda solo su hash, vincula cada una al usuario con sesión iniciada, al documento y a esta sesión del editor, crea una por sesión, mantenla válida solo mientras tu página informe de que la sesión está abierta, y anúlala cuando se cierre el editor o la página.
El protocolo completo está en llms.txt: dáselo a una IA y construirá la conexión para tu sistema. El Editor de LaTeX y el Editor de SVG funcionan igual con los prefijos latexeditor: y svgeditor:: latex.giit.ch, svg.giit.ch.
No. El editor se ejecuta por completo en tu navegador. Tus páginas y sus archivos nunca se envían a un servidor, salvo que tú mismo configures un webhook a tu propio servidor.
No. La vista previa muestra el HTML y el CSS de la página, pero los scripts y los atributos on… nunca se ejecutan, y los enlaces no navegan. Así el editor es seguro con cualquier página que abras. El código conserva sus scripts, de modo que la página exportada funciona como antes.
Arrástralas o pégalas en el editor, o añádelas en la pestaña Archivos de la derecha. Se guardan con la página en tu navegador y se usan por su nombre, por ejemplo <img src="../logo.png"> o <link rel="stylesheet" href="../style.css">.
Haz clic en «Exportar», elige PDF y haz clic en «Imprimir / Guardar como PDF». En el diálogo de impresión elige «Guardar como PDF» como impresora.
Solo en tu navegador. Haz clic en el botón de carpeta arriba a la izquierda (Mis documentos) para abrirlos, renombrarlos, duplicarlos, descargarlos o eliminarlos. Si borras los datos del sitio en tu navegador, desaparecen; descarga los que quieras conservar, o deja que el editor los envíe a tu propio servidor («Guardar en servidor»).
Sí, cualquier IA: ChatGPT, Claude, Gemini, Copilot o la IA de tu herramienta de programación. Haz clic en «Asistente de IA» y luego en «Copiar prompt», pégalo en tu IA y dile qué debe escribir. La IA responde con un enlace; haz clic en él y la página aparece en tu editor. «Deshacer» revierte cada cambio.
Sí. Intégralo con un iframe e intercambia documentos con postMessage, o deja que envíe cada versión guardada a tu servidor con un webhook. Mira Usa el editor en tu propio sitio web para ver ejemplos.
No. El editor es gratuito, sin anuncios y sin registro.