Incorporação e Embedding
Como incorporar documentos e formulários de aceite em sites externos usando iframe
Guia: Incorporação e Embedding
Visão Geral
O Termatica permite incorporar documentos legais e formulários de aceite em qualquer site externo usando iframes. Isso é útil para:
- Exibir termos de uso em páginas de cadastro - Mostrar políticas de privacidade em sites institucionais - Coletar aceites diretamente em seu site
---
Tipos de Incorporação
1. Leitura Pública (Sem Aceite)
Apenas exibe o conteúdo do documento, sem formulário de aceite.
URL:
`
https://seu-dominio.com/documents/read/embedded/{document_key}/
`
Uso: Páginas informativas, consulta de termos
2. Aceite via Embedding (Com Formulário)
Exibe o documento com formulário de aceite integrado.
URL:
`
https://seu-dominio.com/embedded/{document_key}/
`
Uso: Páginas de cadastro, checkout, onboarding
---
Implementação Passo a Passo
Passo 1: Habilitar Embedding no Documento
No Dashboard:
1. Acesse Documentos > Selecione o documento 2. Vá em Configurações de Embedding 3. Marque Embedding Habilitado 4. Configure os Domínios Permitidos (opcional) 5. Clique em Salvar
Passo 2: Obter o Código de Incorporação
Na página do documento, clique em Obter Código Embed.
O sistema gera o código automaticamente:
`html
<iframe
src="https://termatica.com.br/embedded/550e8400-e29b-41d4-a716-446655440000/"
width="100%"
height="600"
frameborder="0"
style="border: 1px solid #e5e7eb; border-radius: 8px;"
allow="clipboard-write"
sandbox="allow-forms allow-scripts allow-same-origin allow-popups"
title="Termos de Uso"
></iframe>
`
Passo 3: Adicionar ao Seu Site
Cole o código na página desejada:
`html
<!DOCTYPE html>
<html>
<head>
<title>Cadastro - Meu Site</title>
</head>
<body>
<h1>Aceite os Termos de Uso</h1>
<div class="terms-container"> <iframe src="https://termatica.com.br/embedded/550e8400-e29b-41d4-a716-446655440000/" width="100%" height="600" frameborder="0" ></iframe> </div>
<button onclick="verificarAceite()">Continuar Cadastro</button>
</body>
</html>
`
---
Configuração de Domínios Permitidos
Por Que Configurar?
Restringe quais sites podem incorporar seu documento, aumentando a segurança.
Como Configurar
No documento, adicione domínios à lista:
`
seusite.com
www.seusite.com
*.seusite.com
app.seusite.com
`
Wildcards
| Padrão | Corresponde a |
|--------|---------------|
| seusite.com | Apenas seusite.com |
| *.seusite.com | app.seusite.com, blog.seusite.com, etc. |
| www.seusite.com | Apenas www.seusite.com |
Modo Permissivo
Se a lista estiver vazia, qualquer domínio pode incorporar (não recomendado para produção).
---
Comunicação com o Iframe
Recebendo Eventos do Iframe
O iframe envia mensagens quando eventos ocorrem:
`javascript
window.addEventListener('message', function(event) {
// Verifica origem por segurança
if (event.origin !== 'https://termatica.com.br') return;
const data = event.data;
switch(data.type) { case 'acceptance_complete': console.log('Aceite registrado!'); console.log('Email:', data.email); console.log('ID do Aceite:', data.acceptance_key); habilitarBotaoContinuar(); break;
case 'acceptance_pending': console.log('Aguardando confirmação por email'); break;
case 'resize_iframe': document.getElementById('terms-iframe').style.height = data.height + 'px'; break;
case 'error':
console.error('Erro:', data.message);
break;
}
});
`
Eventos Disponíveis
| Evento | Descrição | Dados |
|--------|-----------|-------|
| acceptance_complete | Aceite confirmado | email, acceptance_key |
| acceptance_pending | Aguardando confirmação | email, method |
| resize_iframe | Altura do conteúdo mudou | height |
| document_loaded | Documento carregado | version, title |
| error | Erro ocorreu | message, code |
---
Ajuste Automático de Altura
Implementação Simples
`html
<iframe
id="terms-iframe"
src="https://termatica.com.br/embedded/UUID/"
width="100%"
height="600"
frameborder="0"
></iframe>
<script>
window.addEventListener('message', function(event) {
if (event.data.type === 'resize_iframe') {
document.getElementById('terms-iframe').style.height =
event.data.height + 'px';
}
});
</script>
`
Com Altura Mínima
`javascript
window.addEventListener('message', function(event) {
if (event.data.type === 'resize_iframe') {
const minHeight = 400;
const newHeight = Math.max(event.data.height, minHeight);
document.getElementById('terms-iframe').style.height = newHeight + 'px';
}
});
`
---
Customização Visual
CSS Customizado
No Dashboard, adicione CSS personalizado:
`css
/ Cores da sua marca /
.title {
color: #1a56db;
font-family: 'Inter', sans-serif;
}
.content { font-size: 16px; line-height: 1.75; }
/ Botão de aceite / .btn-accept { background-color: #2563eb; border-radius: 8px; }
.btn-accept:hover { background-color: #1d4ed8; }
/ Remove branding (se disponível no plano) /
.powered-by {
display: none;
}
`
Classes CSS Disponíveis
| Classe | Elemento |
|--------|----------|
| .document-container | Container principal |
| .title | Título do documento |
| .version-info | Informações da versão |
| .content | Conteúdo do documento |
| .acceptance-form | Formulário de aceite |
| .btn-accept | Botão de aceite |
| .powered-by | Branding do Termatica |
---
Exemplos de Integração
Formulário de Cadastro
`html
<form id="signup-form" action="/api/signup" method="POST">
<input type="text" name="name" placeholder="Nome" required>
<input type="email" name="email" placeholder="Email" required>
<input type="password" name="password" placeholder="Senha" required>
<div class="terms-section"> <iframe id="terms-iframe" src="https://termatica.com.br/embedded/UUID/" width="100%" height="400" ></iframe> </div>
<input type="hidden" name="acceptance_key" id="acceptance-key">
<button type="submit" id="submit-btn" disabled> Criar Conta </button> </form>
<script>
window.addEventListener('message', function(event) {
if (event.data.type === 'acceptance_complete') {
// Armazena o ID do aceite
document.getElementById('acceptance-key').value = event.data.acceptance_key;
// Habilita o botão de submit
document.getElementById('submit-btn').disabled = false;
}
});
</script>
`
React Component
`jsx
import { useEffect, useState, useRef } from 'react';
export default function TermsEmbed({ documentKey, onAccept }) { const iframeRef = useRef(null); const [accepted, setAccepted] = useState(false);
useEffect(() => { const handleMessage = (event) => { if (event.origin !== 'https://termatica.com.br') return;
if (event.data.type === 'acceptance_complete') { setAccepted(true); onAccept?.(event.data); }
if (event.data.type === 'resize_iframe' && iframeRef.current) {
iframeRef.current.style.height = ${event.data.height}px;
}
};
window.addEventListener('message', handleMessage); return () => window.removeEventListener('message', handleMessage); }, [onAccept]);
return (
<div className="terms-embed">
<iframe
ref={iframeRef}
src={https://termatica.com.br/embedded/${documentKey}/}
width="100%"
height="500"
frameBorder="0"
title="Termos de Uso"
/>
{accepted && (
<p className="accepted-message">
✓ Termos aceitos com sucesso
</p>
)}
</div>
);
}
`
Vue Component
`vue
<template>
<div class="terms-embed">
<iframe
ref="iframeRef"
:src="https://termatica.com.br/embedded/${documentKey}/"
width="100%"
height="500"
frameborder="0"
title="Termos de Uso"
/>
<p v-if="accepted" class="accepted-message">
✓ Termos aceitos com sucesso
</p>
</div>
</template>
<script setup> import { ref, onMounted, onUnmounted } from 'vue';
const props = defineProps(['documentKey']); const emit = defineEmits(['accept']);
const iframeRef = ref(null); const accepted = ref(false);
const handleMessage = (event) => { if (event.origin !== 'https://termatica.com.br') return;
if (event.data.type === 'acceptance_complete') { accepted.value = true; emit('accept', event.data); }
if (event.data.type === 'resize_iframe' && iframeRef.value) {
iframeRef.value.style.height = ${event.data.height}px;
}
};
onMounted(() => window.addEventListener('message', handleMessage));
onUnmounted(() => window.removeEventListener('message', handleMessage));
</script>
`
---
Segurança
Headers de Segurança
O iframe inclui atributos de segurança:
`html
sandbox="allow-forms allow-scripts allow-same-origin allow-popups"
`
| Atributo | Permite |
|----------|---------|
| allow-forms | Envio de formulários |
| allow-scripts | Execução de JavaScript |
| allow-same-origin | Acesso à mesma origem |
| allow-popups | Abertura de popups (verificação) |
Validação de Origem
Sempre valide a origem das mensagens:
`javascript
window.addEventListener('message', function(event) {
// IMPORTANTE: Valide a origem
const allowedOrigins = [
'https://termatica.com.br',
'https://www.termatica.com.br'
];
if (!allowedOrigins.includes(event.origin)) { console.warn('Origem não permitida:', event.origin); return; }
// Processe a mensagem...
});
`
---
Solução de Problemas
Iframe não carrega (403 Forbidden)
Causa: Domínio não está na lista de permitidos.
Solução:
1. Adicione seu domínio em Domínios Permitidos
2. Verifique se incluiu variações (com e sem www)
3. Use wildcards se necessário: *.seusite.com
Iframe carrega mas não envia eventos
Causa: Erro na configuração do listener.
Solução:
`javascript
// Verifique se está escutando corretamente
window.addEventListener('message', function(event) {
console.log('Mensagem recebida:', event.data);
console.log('Origem:', event.origin);
});
`
Altura não ajusta corretamente
Causa: Conteúdo dinâmico após carregamento.
Solução:
`javascript
// Aguarde um pouco antes de ajustar
setTimeout(() => {
if (event.data.type === 'resize_iframe') {
document.getElementById('iframe').style.height = event.data.height + 'px';
}
}, 100);
`
Aceite não é registrado
Verifique: - [ ] Embedding está habilitado no documento - [ ] Existe versão publicada e ativa - [ ] Email do usuário é válido - [ ] Verificação por email foi confirmada
---
Rate Limiting
O embedding possui limite de aceites por hora para proteção:
| Configuração | Padrão | Máximo | |--------------|--------|--------| | Aceites por hora | 100 | 1000 | | Requisições por minuto | 60 | 300 |
Se exceder, retorna erro 429 (Too Many Requests).
---
Próximos Passos
- Integração via API - Controle total via REST API - Leitura Pública - Embedding apenas para leitura - Configurando Documentos - Configurações avançadas