Incorporando conteúdo externo com iframe
Entenda como usar o iframe para embutir mapas do Google, vídeos do YouTube e outros conteúdos externos na sua página.
Algumas das funcionalidades mais comuns de sites modernos
dependem de uma única tag: o mapa do Google embaixo do endereço
de uma empresa, o vídeo do YouTube incorporado em um artigo,
o formulário de pagamento do Stripe em uma loja virtual, o
widget de comentários de uma rede social. Todos eles usam
a tag <iframe>.
O <iframe> — inline frame — é uma janela aberta dentro
da sua página que carrega e exibe outro documento HTML completo.
Anatomia básica do iframe
<iframe
src="https://exemplo.com"
width="600"
height="400"
title="Descrição do conteúdo incorporado"
>
</iframe>
| Atributo | Propósito |
|---|---|
src |
URL do documento a ser incorporado |
width |
Largura em pixels ou porcentagem |
height |
Altura em pixels |
title |
Descrição acessível do conteúdo — obrigatório |
Diferente da <img>, o <iframe> tem abertura e
fechamento — e o conteúdo entre as tags é o texto
de fallback para navegadores muito antigos:
<iframe src="https://exemplo.com" title="Exemplo">
Seu navegador não suporta iframes.
<a href="https://exemplo.com">Acessar o conteúdo</a>
</iframe>
O atributo title: obrigatório para acessibilidade
O atributo title é essencial em todo <iframe>.
Leitores de tela anunciam o título do iframe antes de
entrar em seu conteúdo — sem ele, o usuário não sabe
o que encontrará dentro:
<!-- ❌ Sem title — o leitor de tela anuncia apenas "frame" -->
<iframe src="https://maps.google.com/..."></iframe>
<!-- ✅ Com title — o leitor de tela anuncia o conteúdo -->
<iframe
src="https://maps.google.com/..."
title="Mapa com a localização da nossa loja"
></iframe>
Casos de uso comuns
Incorporando um vídeo do YouTube
O YouTube gera automaticamente o código de incorporação para qualquer vídeo. O resultado é um iframe com configurações já definidas:
<iframe
width="560"
height="315"
src="https://www.youtube.com/embed/dQw4w9WgXcQ"
title="Rick Astley — Never Gonna Give You Up (videoclipe oficial)"
frameborder="0"
allow="accelerometer; autoplay; clipboard-write;
encrypted-media; gyroscope; picture-in-picture"
allowfullscreen
>
</iframe>
💡 O URL de incorporação do YouTube usa o formato
youtube.com/embed/ID-DO-VIDEO— diferente da URL de visualização normalyoutube.com/watch?v=ID-DO-VIDEO.
Incorporando um mapa do Google Maps
O Google Maps também oferece código de incorporação:
<iframe
src="https://www.google.com/maps/embed?pb=..."
width="600"
height="450"
style="border: 0"
allowfullscreen
loading="lazy"
referrerpolicy="no-referrer-when-downgrade"
title="Mapa com a localização da sede da empresa"
>
</iframe>
Incorporando um formulário externo
<iframe
src="https://forms.google.com/..."
width="640"
height="800"
frameborder="0"
title="Formulário de inscrição no evento"
>
</iframe>
Incorporando um documento PDF
<iframe
src="manual-usuario.pdf"
width="100%"
height="600"
title="Manual do usuário em PDF"
>
<p>
Seu navegador não suporta exibição de PDF.
<a href="manual-usuario.pdf" download>
Baixar o manual (PDF)
</a>.
</p>
</iframe>
Atributos de comportamento e aparência
frameborder
<!-- Valores: 0 (sem borda) ou 1 (com borda) -->
<iframe src="..." frameborder="0"></iframe>
O frameborder foi deprecado no HTML5 — a forma
correta de remover a borda é via CSS:
iframe {
border: none;
}
allowfullscreen
<iframe
src="https://www.youtube.com/embed/..."
allowfullscreen
title="Vídeo demonstrativo"
>
</iframe>
Atributo booleano que permite ao conteúdo do iframe entrar em modo de tela cheia — necessário para players de vídeo.
loading: carregamento preguiçoso
<!-- lazy: carrega apenas quando entra na área visível -->
<iframe
src="https://www.google.com/maps/embed?pb=..."
loading="lazy"
title="Mapa de localização"
>
</iframe>
<!-- eager: carrega imediatamente (padrão) -->
<iframe
src="https://exemplo.com"
loading="eager"
title="Conteúdo prioritário"
>
</iframe>
loading="lazy" é especialmente recomendado para
iframes abaixo da área visível inicial da página —
como mapas no rodapé — pois evita carregar conteúdo
que o usuário pode nunca ver.
referrerpolicy: controle de privacidade
<iframe
src="https://exemplo.com"
referrerpolicy="no-referrer-when-downgrade"
title="Conteúdo externo"
>
</iframe>
Define quais informações de referência são enviadas ao servidor do iframe. Os valores mais usados:
| Valor | Comportamento |
|---|---|
no-referrer |
Não envia informação de origem |
no-referrer-when-downgrade |
Padrão — envia em HTTPS, omite em HTTP |
strict-origin-when-cross-origin |
Mais restritivo — recomendado |
Segurança: o atributo sandbox
O atributo sandbox é um dos mais importantes do
<iframe> — ele restringe as capacidades do
conteúdo incorporado, protegendo sua página de
comportamentos maliciosos:
<!-- Sandbox máximo: bloqueia tudo -->
<iframe
src="https://externo.com"
sandbox
title="Conteúdo externo em sandbox"
>
</iframe>
Quando sandbox está presente sem valor, o iframe
fica com todas as restrições ativas:
- Sem JavaScript
- Sem formulários
- Sem pop-ups
- Sem navegação da página pai
- Sem plugins
- Sem acesso à câmera ou microfone
- Sem armazenamento local
Para liberar permissões específicas, use os valores:
<iframe
src="https://externo.com"
sandbox="allow-scripts allow-forms"
title="Formulário externo seguro"
>
</iframe>
| Permissão | O que libera |
|---|---|
allow-scripts |
Execução de JavaScript |
allow-forms |
Envio de formulários |
allow-popups |
Abertura de pop-ups e novas abas |
allow-same-origin |
Acesso ao mesmo domínio de origem |
allow-top-navigation |
Navegação da página pai |
allow-fullscreen |
Modo de tela cheia |
allow-downloads |
Download de arquivos |
<!-- Iframe de vídeo com permissões necessárias -->
<iframe
src="https://www.youtube.com/embed/..."
sandbox="allow-scripts allow-same-origin allow-fullscreen"
allowfullscreen
title="Vídeo do YouTube"
>
</iframe>
<!-- Iframe de mapa com carregamento lazy -->
<iframe
src="https://www.google.com/maps/embed?pb=..."
sandbox="allow-scripts allow-same-origin"
loading="lazy"
title="Mapa de localização da loja"
>
</iframe>
⚠️ Evite usar
sandbox="allow-same-origin allow-scripts"juntos sem necessidade real — essa combinação pode permitir que o iframe escape do sandbox ao acessar o contexto de origem.
O risco do clickjacking
Clickjacking é um ataque onde um site malicioso incorpora sua página em um iframe invisível e posiciona botões falsos sobre ela — fazendo o usuário clicar em elementos da sua página sem saber:
Site malicioso:
┌─────────────────────────────────┐
│ [Botão falso: "Ganhe um prêmio!"] │
│ │
│ [SEU SITE invisível em iframe]│
│ ← o usuário clica aqui sem │
│ saber que é seu site │
└─────────────────────────────────┘
Proteção contra clickjacking
A proteção é feita no servidor com o cabeçalho
HTTP X-Frame-Options ou com a diretiva
frame-ancestors do Content Security Policy:
# No servidor: impede que qualquer site incorpore sua página
X-Frame-Options: DENY
# Permite incorporação apenas no próprio domínio
X-Frame-Options: SAMEORIGIN
# CSP moderno — mais flexível
Content-Security-Policy: frame-ancestors 'self'
💡 Proteger sua própria página contra clickjacking é responsabilidade do servidor — não do HTML. Como desenvolvedor front-end, é importante conhecer o conceito para comunicar a necessidade à equipe de back-end ou DevOps.
Problemas de performance com iframes
Cada <iframe> carrega um documento HTML completo —
com seus próprios recursos, scripts e estilos. Isso
tem implicações de performance:
<!-- ❌ Múltiplos iframes carregados juntos -->
<iframe src="mapa.com" ...></iframe>
<iframe src="video.com" ...></iframe>
<iframe src="widget.com" ...></iframe>
<iframe src="chat.com" ...></iframe>
<!-- ✅ Com loading lazy para os não-críticos -->
<iframe src="mapa.com" loading="lazy" ...></iframe>
<iframe src="video.com" loading="lazy" ...></iframe>
<iframe src="widget.com" loading="lazy" ...></iframe>
<iframe src="chat.com" loading="eager" ...></iframe>
Boas práticas de performance com iframes:
- Use
loading="lazy"em iframes abaixo da área inicial - Evite múltiplos iframes na mesma página
- Prefira APIs nativas quando disponíveis — como a API do Google Maps em JavaScript — em vez de iframes, para maior controle e performance
- Considere carregar o iframe apenas após interação do usuário para conteúdos pesados
Exemplo completo: página de contato
<section id="contato">
<h2>Fale Conosco</h2>
<div>
<!-- Formulário de contato via Google Forms -->
<iframe
src="https://docs.google.com/forms/d/e/.../viewform?embedded=true"
width="640"
height="600"
title="Formulário de contato"
loading="lazy"
sandbox="allow-scripts allow-forms allow-same-origin"
>
<p>
Não foi possível carregar o formulário.
<a href="mailto:contato@empresa.com">
Envie um e-mail diretamente.
</a>
</p>
</iframe>
</div>
<div>
<!-- Mapa da localização -->
<iframe
src="https://www.google.com/maps/embed?pb=..."
width="600"
height="450"
style="border: 0"
loading="lazy"
referrerpolicy="no-referrer-when-downgrade"
title="Mapa com a localização da nossa sede em São Paulo"
sandbox="allow-scripts allow-same-origin"
>
</iframe>
</div>
</section>
Resumindo
| Atributo | Tipo | Propósito |
|---|---|---|
src |
Valor | URL do documento incorporado |
title |
Valor | Descrição acessível — sempre obrigatório |
width / height |
Valor | Dimensões do frame |
allowfullscreen |
Booleano | Permite tela cheia |
loading |
Valor | Controla o carregamento (lazy / eager) |
sandbox |
Valor ou booleano | Restringe permissões do conteúdo |
referrerpolicy |
Valor | Controla informações de origem enviadas |
Regras de ouro:
- Sempre inclua o atributo
titlecom descrição útil - Use
sandboxem iframes de fontes não confiáveis - Use
loading="lazy"em iframes abaixo da dobra - Remova bordas com CSS — não com
frameborder="0" - Forneça fallback acessível entre as tags
- Evite múltiplos iframes pesados na mesma página