Embedded content means putting content from another source inside your HTML page.
Examples:
The most important HTML element for embedded content is:
<iframe>Normally, your webpage displays content that belongs directly to your HTML:
<h1>My Website</h1>
<p>Welcome to my website.</p>With embedded content, your page can display content that comes from another resource.
For example:
Your Website
│
├── Header
├── Navigation
├── Your Content
│
└── Embedded Content
│
├── YouTube
├── Google Maps
├── PDF
└── External ApplicationA simplified example:
<iframe
src="https://example.com"
title="Example website">
</iframe>The browser loads the external resource inside a rectangular area of your page.
HTML provides several ways to embed external content.
| Element | Common use |
|---|---|
<iframe> |
Webpages, YouTube, maps, apps |
<embed> |
External resources such as PDFs |
<object> |
External resources/documents |
<video> |
Video files |
<audio> |
Audio files |
<img> |
Images |
<picture> |
Responsive images |
For modern web development, <iframe> is the most important one to understand.
<iframe> Element#iframe means:
Inline Frame
It creates a browsing context inside your webpage.
Basic syntax:
<iframe
src="https://example.com"
title="Example website">
</iframe>Conceptually:
┌──────────────────────────────────────────┐
│ YOUR WEBSITE │
│ │
│ Header │
│ Navigation │
│ │
│ ┌────────────────────────────────────┐ │
│ │ IFRAME │ │
│ │ │ │
│ │ External website/content │ │
│ │ │ │
│ └────────────────────────────────────┘ │
│ │
└──────────────────────────────────────────┘src#The src attribute specifies what should be loaded.
<iframe
src="https://example.com"
title="Example">
</iframe>Here:
src
↓
https://example.comThe browser attempts to load that URL inside the iframe.
title#An iframe should generally have a meaningful title.
<iframe
src="https://example.com"
title="Example website">
</iframe>Why?
Accessibility tools such as screen readers need to understand what the iframe contains.
Bad:
<iframe src="https://example.com"></iframe>Better:
<iframe
src="https://example.com"
title="Company careers portal">
</iframe>For example:
<iframe
src="https://www.youtube.com/embed/abc123"
title="Introduction to HTML tutorial">
</iframe>The title should describe the embedded content, not simply say:
iframeYou can specify dimensions:
<iframe
src="https://example.com"
title="Example"
width="800"
height="500">
</iframe>This creates approximately:
800px × 500pxHowever, modern websites commonly control sizing using CSS.
<iframe
class="embedded-content"
src="https://example.com"
title="Example">
</iframe>.embedded-content {
width: 100%;
height: 500px;
border: 0;
}This is generally more flexible.
One of the most common uses of <iframe> is YouTube.
For example:
<iframe
width="560"
height="315"
src="https://www.youtube.com/embed/VIDEO_ID"
title="YouTube video"
allowfullscreen>
</iframe>Notice:
youtube.com/embed/VIDEO_IDrather than simply:
youtube.com/watch?v=VIDEO_IDThe /embed/ URL is intended for embedding.
A more complete example:
<iframe
width="560"
height="315"
src="https://www.youtube.com/embed/VIDEO_ID"
title="HTML Tutorial"
loading="lazy"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
allowfullscreen>
</iframe>Important attributes:
loading="lazy"can defer loading until the iframe is near the viewport.
allowfullscreenallows fullscreen functionality when supported by the embedded content.
allow="..."controls which browser capabilities may be available to the embedded content.
allowfullscreen#Example:
<iframe
src="https://www.youtube.com/embed/VIDEO_ID"
title="Tutorial"
allowfullscreen>
</iframe>This allows the embedded document to request fullscreen.
You may also see:
allow="fullscreen"in modern embed configurations.
For third-party services, use the embed code recommended by that service.
loading="lazy"#You can tell the browser that an iframe doesn't need to load immediately:
<iframe
src="https://example.com"
title="Example"
loading="lazy">
</iframe>Possible values:
loading="lazy"or:
loading="eager"For an iframe far below the fold, lazy loading can reduce initial work.
For example:
Page loads
↓
Header
↓
Hero
↓
Products
↓
Reviews
↓
Map iframe ← lazy loaded when approaching viewportThis can improve initial page performance.
Another common use is embedding maps.
For example:
<iframe
src="https://www.google.com/maps/embed?..."
width="600"
height="450"
style="border:0;"
loading="lazy"
referrerpolicy="no-referrer-when-downgrade"
title="Office location map">
</iframe>Google Maps provides an embed URL/code through its sharing/embed functionality.
Don't manually invent a complicated Maps URL when the service already provides an official embed code.
A common mistake is:
<iframe
width="800"
height="600"
src="..."
title="Map">
</iframe>On a desktop:
┌──────────────────────────────┐
│ │
│ iframe │
│ │
└──────────────────────────────┘But on a mobile screen:
┌───────────────┐
│ │
│ iframe too │
│ wide │
│ │
└───────────────┘Instead, make it responsive.
<div class="iframe-wrapper">
<iframe
src="https://example.com"
title="Example content">
</iframe>
</div>.iframe-wrapper {
width: 100%;
aspect-ratio: 16 / 9;
}
.iframe-wrapper iframe {
width: 100%;
height: 100%;
border: 0;
}Now:
Desktop
┌───────────────────────────────┐
│ │
│ iframe │
│ │
└───────────────────────────────┘
Mobile
┌──────────────────┐
│ │
│ iframe │
│ │
└──────────────────┘aspect-ratio Is Useful#Suppose you want a video iframe to maintain:
16 : 9CSS:
iframe {
width: 100%;
aspect-ratio: 16 / 9;
height: auto;
}Or use a wrapper:
.video-container {
width: 100%;
aspect-ratio: 16 / 9;
}
.video-container iframe {
width: 100%;
height: 100%;
border: 0;
}This is much better than hardcoding:
width="560"
height="315"for every screen size.
You can technically do:
<iframe
src="https://example.com"
title="Example website">
</iframe>But there is an important limitation:
Not every website allows itself to be embedded.
A website can use security policies such as:
X-Frame-Optionsor:
Content-Security-Policyto prevent other websites from embedding it.
For example:
Your Website
│
│ iframe request
↓
example.com
│
├── Allows embedding → iframe works
│
└── Blocks embedding → browser refusesSo:
An iframe does not mean you can embed any website you want.
One major reason is security.
Imagine:
Attacker Website
│
↓
iframe
│
↓
Bank WebsiteIf arbitrary embedding were always allowed, attackers could attempt to trick users into interacting with sensitive websites inside deceptive pages.
This relates to attacks such as clickjacking.
Therefore websites can restrict framing.
This is an important web security concept.
An origin consists broadly of:
scheme + host + portFor example:
https://example.com:443Changing one of these can create a different origin.
For example:
https://example.com
https://api.example.comThese are different origins because the host differs.
Similarly:
http://example.com
https://example.comare different origins because the scheme differs.
Suppose your page contains:
<iframe
id="myFrame"
src="https://example.com"
title="Example">
</iframe>You might think JavaScript can freely do:
const frame = document.getElementById("myFrame");
frame.contentWindow.document.body.innerHTML = "Hello";Usually not if the iframe is cross-origin.
The browser's same-origin policy restricts direct access.
Conceptually:
Your page
origin: mysite.com
│
│ iframe
↓
example.com
different origin
│
X
direct DOM access restrictedThis is a fundamental browser security mechanism.
postMessage()#Sometimes two windows/frames from different origins need to communicate.
The browser provides:
window.postMessage()Conceptually:
Parent Window
│
│ postMessage()
↓
Iframe
│
│ message event
↓
Handle messageExample:
Parent:
const iframe = document.getElementById("payment");
iframe.contentWindow.postMessage(
{
type: "payment-complete"
},
"https://payment.example.com"
);Iframe can listen:
window.addEventListener("message", (event) => {
if (event.origin !== "https://your-site.example") {
return;
}
console.log(event.data);
});The important security rule is:
Always validate
event.originwhen receiving messages.
Don't blindly trust:
event.datafrom any origin.
sandbox#One of the most important iframe security attributes is:
sandboxExample:
<iframe
src="https://example.com"
title="Example"
sandbox>
</iframe>A sandboxed iframe has additional restrictions.
Think of it as:
Normal iframe
↓
More permissions
sandbox iframe
↓
More restrictionsYou can selectively allow certain capabilities.
Example:
<iframe
src="https://example.com"
title="Example"
sandbox="allow-scripts">
</iframe>Some commonly encountered tokens include:
| Token | Purpose |
|---|---|
allow-scripts |
Allows scripts |
allow-forms |
Allows form submission |
allow-modals |
Allows modal APIs |
allow-popups |
Allows popups |
allow-downloads |
Allows downloads |
allow-same-origin |
Preserves the embedded document's origin behavior |
allow-pointer-lock |
Allows pointer lock |
allow-presentation |
Allows presentation features |
Example:
<iframe
src="https://example.com"
title="Example"
sandbox="allow-scripts allow-forms">
</iframe>The principle is:
Give the iframe only the capabilities it actually needs.
You may see:
sandbox="allow-scripts allow-same-origin"Be careful with combinations like this when embedding content you do not fully trust.
The exact security implications depend on the origin and the embedded content.
For production systems:
Don't add sandbox permissions simply because an embedded service fails without them.
Understand what each permission enables.
allow#The allow attribute controls access to certain browser capabilities through Permissions Policy.
Example:
<iframe
src="https://example.com"
title="Example"
allow="fullscreen">
</iframe>A video service might use something like:
allow="autoplay; fullscreen; picture-in-picture"This doesn't mean the iframe automatically gets every permission.
It specifies capabilities that the embedding page is willing to delegate, subject to browser and server policies.
referrerpolicy#Example:
<iframe
src="https://example.com"
title="Example"
referrerpolicy="strict-origin-when-cross-origin">
</iframe>This controls what referrer information is sent when navigating/fetching from the embedded context.
A commonly used policy is:
strict-origin-when-cross-originYou may encounter other policies such as:
no-referrer
same-origin
origin
strict-originThe right choice depends on the application and privacy requirements.
PDFs can sometimes be displayed using an iframe:
<iframe
src="/documents/resume.pdf"
width="100%"
height="700"
title="Resume PDF">
</iframe>This can allow the browser's built-in PDF viewer to display the document.
However, PDF rendering behavior can vary between browsers and environments.
<embed>#HTML also has:
<embed>Example:
<embed
src="/documents/manual.pdf"
type="application/pdf"
width="100%"
height="700"><embed> is a void element.
That means:
<embed>not:
<embed></embed><object>#Another element is:
<object>Example:
<object
data="/documents/manual.pdf"
type="application/pdf"
width="100%"
height="700">
</object>Unlike <embed>, <object> is not a void element and can contain fallback content.
Example:
<object
data="/documents/manual.pdf"
type="application/pdf"
width="100%"
height="700">
<p>
Your browser cannot display this PDF.
<a href="/documents/manual.pdf">
Download the PDF
</a>
</p>
</object>This gives the user an alternative if inline display doesn't work.
<iframe> vs <object> vs <embed>#| Feature | <iframe> |
<object> |
<embed> |
|---|---|---|---|
| Webpage | ✅ | ⚠️ | ❌ |
| YouTube | ✅ | ❌ | ❌ |
| Google Maps | ✅ | ❌ | ❌ |
| External application | ✅ | ⚠️ | ⚠️ |
| ✅ | ✅ | ✅ | |
| Fallback content | Limited | ✅ | ❌ |
| Security controls | Strong | More limited | More limited |
| Common modern usage | ⭐⭐⭐⭐⭐ | ⭐⭐ | ⭐ |
For modern web applications:
Use the element that matches the content.
Don't automatically choose <embed> just because it can display a resource.
<iframe> vs <video>#This distinction is extremely important.
Suppose you have:
my-video.mp4Use:
<video controls>
<source src="my-video.mp4" type="video/mp4">
</video>If you are embedding YouTube:
<iframe
src="https://www.youtube.com/embed/VIDEO_ID"
title="YouTube video">
</iframe>So:
| Situation | Use |
|---|---|
| Your own MP4 | <video> |
| Your own WebM | <video> |
| YouTube | <iframe> |
| Vimeo | Usually <iframe> |
| Google Maps | <iframe> |
| External webpage | <iframe> |
<iframe>, <object>, or <embed> depending on requirements |
<iframe> for Your Own Video?#You could technically serve your own page containing a video through an iframe.
But that adds unnecessary layers:
Page
↓
iframe
↓
another HTML document
↓
videoInstead:
Page
↓
videoUse:
<video controls>
<source src="/videos/tutorial.mp4" type="video/mp4">
</video>This is simpler and gives you direct control over the media element.
Suppose your company has an analytics dashboard:
https://analytics.example.com/dashboardYou might embed it:
<iframe
src="https://analytics.example.com/dashboard"
title="Analytics dashboard"
loading="lazy">
</iframe>However, you need to consider:
Suppose:
Your website
│
↓
iframe
│
↓
Private dashboardAuthentication can become complicated because browsers enforce security rules around:
Therefore, don't assume:
<iframe src="/private-dashboard">will automatically behave like a normal page navigation in every architecture.
For modern applications, authentication architecture needs to be designed intentionally.
Third-party embeds can introduce:
Performance
Security
Privacy
Tracking
Availabilityrisks.
For example:
<iframe src="https://third-party.example"></iframe>The third party may load:
JavaScript
Images
Fonts
Analytics
Advertisements
Other resourcesSo your page may become dependent on another service.
Imagine your page contains:
Page
│
├── Header
├── Hero
├── Products
├── YouTube iframe
├── Google Maps iframe
├── Social media iframe
└── Chat widget iframeEach embedded resource can add work.
Potentially:
Page
│
├── Your resources
│
├── YouTube resources
│
├── Maps resources
│
├── Social resources
│
└── Chat resourcesThis can increase:
If an iframe isn't immediately visible:
<iframe
src="https://example.com"
title="Example"
loading="lazy">
</iframe>This can help.
For example, a map at the bottom of a contact page:
Top of page
↓
Hero
↓
Contact information
↓
Contact form
↓
Map iframe ← lazy loadThe user doesn't need the map immediately.
For very expensive third-party embeds, you can initially show a placeholder.
For example:
┌──────────────────────────────────┐
│ │
│ ▶ Watch on YouTube │
│ │
│ Load video │
│ │
└──────────────────────────────────┘Only load the actual iframe when the user interacts.
Conceptually:
Initial page
↓
Lightweight placeholder
↓
User clicks
↓
Create/load iframeThis is sometimes called a facade or click-to-load approach.
Embedded content must be considered from an accessibility perspective.
Always give an iframe a meaningful title:
<iframe
src="..."
title="Company office location map">
</iframe>Avoid:
title="iframe"because it tells the user almost nothing.
Good:
title="Google Map showing our Delhi office location"Suppose you embed a map:
<iframe
src="..."
title="Office location map">
</iframe>It's useful to also provide a normal link:
<p>
<a href="https://maps.example.com">
Open this location in Maps
</a>
</p>Why?
Because:
<section aria-labelledby="location-heading">
<h2 id="location-heading">Our Location</h2>
<p>
Visit our office in Delhi.
</p>
<div class="map-container">
<iframe
src="https://www.google.com/maps/embed?..."
title="Map showing our Delhi office location"
loading="lazy"
referrerpolicy="strict-origin-when-cross-origin">
</iframe>
</div>
<p>
<a href="https://maps.google.com/">
Open location in Maps
</a>
</p>
</section>CSS:
.map-container {
width: 100%;
aspect-ratio: 16 / 9;
}
.map-container iframe {
width: 100%;
height: 100%;
border: 0;
}This is much closer to production-quality HTML.
<section aria-labelledby="video-heading">
<h2 id="video-heading">
Learn HTML
</h2>
<div class="video-container">
<iframe
src="https://www.youtube.com/embed/VIDEO_ID"
title="HTML tutorial for beginners"
loading="lazy"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
allowfullscreen>
</iframe>
</div>
</section>CSS:
.video-container {
width: 100%;
max-width: 900px;
aspect-ratio: 16 / 9;
}
.video-container iframe {
width: 100%;
height: 100%;
border: 0;
}<section aria-labelledby="document-heading">
<h2 id="document-heading">
Company Brochure
</h2>
<iframe
src="/documents/company-brochure.pdf"
title="Company brochure PDF"
width="100%"
height="700"
loading="lazy">
</iframe>
<p>
<a href="/documents/company-brochure.pdf">
Download the brochure
</a>
</p>
</section>The download link is important because PDF rendering isn't guaranteed in every environment.
Bad:
<iframe src="..."></iframe>Better:
<iframe
src="..."
title="Company dashboard">
</iframe>Bad:
<iframe
width="1200"
height="600"
src="...">
</iframe>Better:
iframe {
width: 100%;
aspect-ratio: 16 / 9;
}Don't add:
YouTube iframe
Maps iframe
Instagram iframe
Chat iframe
Ads iframe
Analytics iframejust because they are available.
Every external embed has a cost.
External content can introduce:
Bad mindset:
sandbox="allow-scripts allow-forms allow-popups allow-same-origin ..."without understanding why.
Instead:
Start restrictive and add only what is required.
For a PDF:
<iframe src="/file.pdf"></iframe>is less useful than:
<iframe
src="/file.pdf"
title="Product manual">
</iframe>
<a href="/file.pdf">
Download Product Manual
</a>Use this mental model:
What are you embedding?
│
├── Your own video?
│ ↓
│ <video>
│
├── Your own audio?
│ ↓
│ <audio>
│
├── YouTube/Vimeo?
│ ↓
│ <iframe>
│
├── Google Maps?
│ ↓
│ <iframe>
│
├── Another webpage/application?
│ ↓
│ <iframe>
│
└── PDF/document?
↓
<iframe>/<object>/<embed><iframe> Attribute Cheat Sheet#| Attribute | Purpose |
|---|---|
src |
Resource URL |
title |
Accessibility description |
width |
Width |
height |
Height |
loading |
Loading behavior |
allow |
Delegated capabilities |
allowfullscreen |
Fullscreen support |
sandbox |
Security restrictions |
referrerpolicy |
Referrer behavior |
name |
Browsing context name |
Example:
<iframe
src="https://example.com"
title="Example application"
loading="lazy"
allow="fullscreen"
sandbox="allow-scripts"
referrerpolicy="strict-origin-when-cross-origin">
</iframe>Don't blindly copy every attribute. Use the ones required by the embedded service and your security/performance requirements.
Imagine you're building your NextGen Blog.
A blog article might contain:
<article>
<header>
<h1>What Are AI Agents?</h1>
</header>
<p>
AI agents can perform tasks instead of only answering questions.
</p>
<figure>
<img
src="/images/ai-agent.jpg"
alt="Diagram illustrating an AI agent workflow">
</figure>
<h2>Watch the Explanation</h2>
<div class="video-container">
<iframe
src="https://www.youtube.com/embed/VIDEO_ID"
title="AI agents explained"
loading="lazy"
allowfullscreen>
</iframe>
</div>
<h2>Our Office</h2>
<div class="map-container">
<iframe
src="https://www.google.com/maps/embed?..."
title="Office location map"
loading="lazy">
</iframe>
</div>
<footer>
<p>Published October 2026</p>
</footer>
</article>This combines several concepts you've already learned:
HTML
│
├── Semantic structure
│ ├── article
│ ├── header
│ ├── footer
│ └── section
│
├── Images
│ └── figure
│
└── Embedded content
├── YouTube iframe
└── Maps iframeAn iframe creates an inline browsing context that allows another document/resource to be displayed inside the current page.
<video> directly represents a video resource controlled by the page.
<iframe> embeds another document or external service.
Example:
<video src="movie.mp4" controls></video>versus:
<iframe
src="https://www.youtube.com/embed/..."
title="Video">
</iframe>For accessibility. Screen-reader users need a meaningful description of the embedded content.
No.
The target website can prevent framing using mechanisms such as:
X-Frame-Options
Content-Security-Policysandbox applies additional restrictions to the embedded document and can selectively grant capabilities using sandbox tokens.
It is a browser security mechanism that restricts how documents from different origins interact with each other.
One common mechanism is:
window.postMessage()with careful origin validation.
loading="lazy"?#To defer loading of off-screen iframe content and potentially reduce initial page loading work.
Because third-party frames can trigger additional:
Network requests
JavaScript execution
CPU work
Memory usage
Tracking/analyticsTypically:
<iframe>because YouTube provides an embed interface.
Create:
embedded-content.htmlBuild this page:
┌─────────────────────────────────────┐
│ Embedded Content Demo │
├─────────────────────────────────────┤
│ │
│ 1. YouTube Video │
│ │
│ ┌───────────────────────────────┐ │
│ │ │ │
│ │ YouTube iframe │ │
│ │ │ │
│ └───────────────────────────────┘ │
│ │
│ 2. Google Map │
│ │
│ ┌───────────────────────────────┐ │
│ │ │ │
│ │ Map │ │
│ │ │ │
│ └───────────────────────────────┘ │
│ │
│ 3. PDF Document │
│ │
│ ┌───────────────────────────────┐ │
│ │ │ │
│ │ PDF │ │
│ │ │ │
│ └───────────────────────────────┘ │
│ │
│ [Open PDF] │
│ │
└─────────────────────────────────────┘Requirements:
<main><section>loading="lazy"Embedded Content
│
├── <iframe>
│ ├── YouTube
│ ├── Maps
│ ├── External websites
│ └── External applications
│
├── <object>
│ └── External resources/documents
│
├── <embed>
│ └── External resources
│
├── Security
│ ├── sandbox
│ ├── same-origin policy
│ ├── X-Frame-Options
│ ├── CSP
│ └── postMessage
│
├── Performance
│ ├── loading="lazy"
│ ├── avoid unnecessary embeds
│ └── click-to-load for expensive embeds
│
└── Accessibility
├── meaningful title
├── responsive design
└── provide alternativesRemember:
YOUR HTML
│
├── Your content
│
└── External content
│
└── <iframe>
│
├── YouTube
├── Maps
├── External App
└── External PageAnd remember the three major concerns:
1. Security
sandbox
same-origin policy
CSP
postMessage2. Performance
lazy loading
fewer embeds
optimized loading3. Accessibility
meaningful title
responsive layout
alternative links/content<head>#Next, we'll go deep into the <head> section, including:
<title><meta><link><head><head> exampleMark it as complete to track your mastery.