How To Embed A PDF In An HTML Page

How to embed a PDF in an HTML page: the three tags compared, responsive sizing, the iPhone fallback everyone forgets, and copy-paste code that works as-is.
The OxyPages Team · · 9 min read
You have a PDF. A menu, a price list, a resume, a report that got signed off this morning. And you have a web page where that document is meant to appear on the page, not hidden behind a link that sends the reader somewhere else.
That is a five line job. Most guides about it are wrong or twenty years out of date, and nearly all skip the part that actually stops people.
To embed a PDF in an HTML page you need three things: a tag, a size, and a URL the browser can reach. The tag is easy. The size is where it falls apart on phones. The URL catches almost everybody, because a file on your desktop cannot appear inside a page you send to someone else. Their browser has no route to your hard drive.
So here is the tag I would use, code you can paste, the two places it breaks, and where the address comes from.
TL;DR: Use one <iframe> with width: 100%, a height in vh rather than pixels, and a title attribute. Put a plain download link next to it in the page, not inside the tag, because content inside an <iframe> never renders for anyone. The src has to be a public URL ending in .pdf, not a file path and not a cloud drive share link. On an iPhone the embed shows a flat picture of page one and nothing else, which is why that download link matters.
What An Embedded PDF Actually Is
An embedded PDF is a window in your page onto a file that lives somewhere else.
The tag does not copy the document into your HTML. It tells the browser: there is a PDF at this address, go and fetch it, and draw it inside this rectangle. Two separate requests happen. One for your page, one for the file.
So the file has to sit somewhere a browser can go. A real address on the public internet, or a relative path to a file you uploaded alongside the page.
The page itself has to be online too. Double clicking it on your desktop is fine for a look, but the moment you send it to anybody both files need addresses. Getting the page online covers that half.
Three Tags Can Do This, And Only One Is Worth Using
Three HTML tags can display a PDF, and they are not interchangeable.
| Tag | What it does | Do children render as fallback? | Closing tag | Reach for it when |
|---|---|---|---|---|
<iframe> | Loads any URL in a nested browsing context | No. Never, in any current browser | Yes | Always, unless you specifically want markup fallback |
<embed> | Hands the URL straight to the browser's built-in viewer | Not possible. It takes no children | No, it is a void element | Basically never. It is the oldest and adds nothing |
<object> | Embeds an external resource, with children as fallback | Yes. They render when the file fails to load | Yes | You want the fallback message inside the markup itself |
My pick is <iframe>, every time. It behaves the most consistently across desktop browsers, and it is what the rest of the web uses for embedded anything. MDN on the iframe element
The Fallback Trick That Does Not Work
Here is the thing almost every tutorial on this gets wrong.
You will constantly see a message and a download link put between the opening and closing <iframe> tags, so people whose browser cannot show the PDF see the link instead.
It does nothing. Content inside an <iframe> is only displayed by browsers that do not support iframes at all, and there are none of those left. Your carefully written fallback is invisible to every human being on earth.
<object> children genuinely do render, so that is the tag if you want fallback inside the markup.
You do not need it though. Put the link in the page, beside the frame, where everybody sees it all of the time, for a reason the iPhone section makes obvious.
How Do You Embed A PDF In An HTML Page?

You embed a PDF in an HTML page with one tag and three things on it: a src, a title, and some CSS for the size.
Paste this, change the two URLs to your own, and you are done.
<div style="max-width: 900px; margin: 0 auto;">
<iframe
src="https://yoursite.example.com/files/menu.pdf"
title="Spring menu, PDF document"
style="width: 100%; height: 80vh; min-height: 400px; border: 1px solid #ddd;"
loading="lazy">
</iframe>
<p style="margin-top: 12px;">
Cannot see the document above?
<a href="https://yoursite.example.com/files/menu.pdf" download>Download the menu (PDF)</a>
</p>
</div>
Both URLs point at the same file. The first draws it in the page, the second is the escape hatch, and it is not optional.
One catch on that download attribute: a browser ignores it for a file on another domain, where the link quietly becomes an ordinary one that opens the PDF instead of saving it. The sample above points at your own site, so it behaves. Somebody else's URL will open, not save.
Size It In vh, Not Pixels
width: 100% is not negotiable. A fixed pixel width overflows a phone screen and hands you a horizontal scrollbar across the whole page.
Height is where people go wrong. 600px looks reasonable on a laptop and eats more than a whole screen on a phone, so the visitor arrives on a grey rectangle with no idea what they are looking at. Use 80vh instead: eighty percent of the browser window's height, whatever size that window is. Add a min-height so it does not collapse on a short landscape screen.
Always Add A Title Attribute
title="Spring menu, PDF document" is what a screen reader announces when it reaches the frame. Without it, somebody using one hears "iframe" and gets no further. It is the one accessibility attribute on this tag that genuinely changes the experience.
Why It Looks Broken On An iPhone
Because mobile Safari usually does not render an embedded PDF at all. It draws a flat picture of page one.
Your five page brochure turns up as page one, frozen, with no way to scroll to page two. It is not your code, and no attribute repairs it.
Chrome on Android is different and no better: it usually offers a download prompt or shows an empty box instead of drawing the document inline. In-app browsers are worse again, because the webview inside Instagram, Facebook or LinkedIn is not a full browser.
So a large share of your visitors, most of them if the link goes out on social, will never see the embedded document properly. That is the entire argument for the download link beside the frame: on phones it is the main path, and the embed is a bonus for laptops.
Label it honestly, too: "Download the menu (PDF)" beats "Click here".
Open It At Page 3: PDF URL Fragments That Actually Work
You can control where the document opens by adding a fragment to the end of the URL, after a #.
#page=3opens on page three instead of page one#zoom=100sets the zoom level as a percentage#view=FitHfits the page width to the frame#toolbar=0hides the viewer's toolbar- Join two or more with
&, like#page=3&zoom=100
So a src ending in report.pdf#page=12&toolbar=0 drops the reader straight onto page twelve in a cleaner frame, which is genuinely useful in a long document you are quoting from.
One honest caveat. These are not HTML and they are not a standard. They are instructions to whichever PDF viewer the browser uses, so support varies: Chrome's built-in viewer honours all four, Firefox honours page, zoom and view but ignores toolbar, and Safari largely ignores the lot.
Treat them as a bonus, never as something the page depends on.
What An Embed Cannot Do

It cannot stop anyone downloading, printing or saving the file. Not with any tag, any attribute, or any fragment.
#toolbar=0 hides the download button. It does not remove access to the document. The browser already fetched the whole PDF to draw it, and right click, save as, still works.
Every "protect your PDF" snippet you will find is theatre. If a person can read the document, they can keep it.
So the rule is blunt, and it applies to every host including this one: if the document is confidential, do not publish it. Put it behind a login on something built for that, or send it directly. A file on a public URL is public, whatever markup you wrap around it.
Why Does An Embedded PDF Show A Blank Frame?
Nearly always because the src is not a plain, public, HTTPS link to a .pdf file. Three causes cover it, and each has its own fix.
- A cloud drive share link. A Google Drive or Dropbox share URL points at a viewer page, not at a PDF, and those pages send headers that forbid framing outright. Host the file yourself instead. MDN on X-Frame-Options
- Mixed content. An
http://PDF inside anhttps://page is blocked silently, with nothing on the page to tell you why. Your browser console says so. Serve both over HTTPS. - A path instead of a URL. Something beginning
file:///works on your machine and nowhere else. Upload it and use the address you get back.
Where The URL Comes From
The document needs an address. That is the only genuinely new thing this task asks of you.
If the page and the PDF live in the same folder and you upload the whole folder to a host, the src is simply menu.pdf and you are finished. That is usually the right version. Netlify, Cloudflare Pages and GitHub Pages all do this free, and so does any old cPanel host you may already be paying for.
If the file also has to stand on its own, on a QR code taped to a table or in an email signature, host it as a file and use the full URL in both places. OxyPages works this way: the PDF sits at your address plus the filename, over HTTPS, and swapping the file later keeps the same link so a printed code does not go stale. There is a per file size limit and a storage pool though, so a print ready catalogue is not a free plan job. What hosting a PDF involves carries the current numbers.
Before you publish, check the file. The PDF viewer opens a document from your own machine without uploading it anywhere, and the PDF compressor shrinks it, because a 20 MB document makes for a slow page.
What To Do Next
Work through this in order:
- Get the PDF to a public HTTPS URL, and open that URL on its own first.
- Paste the block above and swap both URLs for yours.
- Set the height in
vhand check it on a real phone, not a narrowed browser window. - Confirm the download link works by itself.
Put the PDF somewhere with a real address if you have nowhere to host it yet. Then apply the only test that counts: open the page on your phone, on mobile data. If the frame is blank there, the download link is doing all the work, which is exactly what it is for.
FAQ
Why Is My Embedded PDF Blank?
Three usual causes: the URL is a file path or a cloud drive share link rather than a direct link to a .pdf file, the document is served over HTTP inside an HTTPS page, or its server sends an X-Frame-Options header that forbids framing. Open the PDF URL on its own in a tab first. If it does not load there, no tag will save it.
Can I Stop People Downloading The PDF?
No. The browser has to fetch the entire file to display it, and the address is visible in your page source. Hiding the toolbar with #toolbar=0 removes the button, not the access. If a document must not be copied, keep it off a public web page.
Iframe Or Object: Which One Should I Use?
Use <iframe> unless you want fallback markup to appear when the file fails to load, which is the one thing <object> does that an iframe cannot. <embed> is the oldest of the three, accepts no children, and adds nothing.
Do I Need A JavaScript PDF Viewer?
Only if you need something the browser's own viewer lacks: a custom toolbar, page thumbnails, or search running inside your own page. For simply showing the document, the plain tag has fewer moving parts and loads faster. Most people setting out to embed a PDF in an HTML page need one iframe and a download link, nothing more.