
Embed PDF Document in HTML. Learn how to embed a PDF document in HTML with iframes, objects, and viewer libraries. Covers responsive sizing, accessibility
You're staring at a PDF that has to live on a page right now. Maybe it's a brand guide, a product manual, a contract, or a sales deck, and nobody wants to rebuild 40 pages of layout into HTML before launch. In that moment, the practical question isn't “Can I embed a PDF?” It's which embed path won't fall apart on mobile, in screen readers, or inside a locked-down company browser.
Teams often use an embed PDF document in HTML pattern because people expect a document to open inside the page, not as a separate file they have to chase down later. That expectation matters for reports, brochures, menus, manuals, forms, and contracts, since the reading flow stays intact and the page still feels like part of the product.
HTML gives you three built-in ways to display a PDF, iframe, object, and embed. They work without a JavaScript dependency, and browser support for inline viewing is exposed through navigator.pdfViewerEnabled in web APIs (MDN Web Docs). HTML5 also made <embed> part of the specification, which is why it still appears in older codebases and current ones alike (Nutrient).
Practical rule: if the PDF should be read in place, start with a native tag. If the PDF needs stronger control, measurement, or hardening, add a viewer layer.
Native embedding still depends on the browser's built-in PDF viewer. Desktop support is usually fine, but mobile and tablet behavior can vary, and some corporate browsers or locked-down environments handle inline PDFs differently enough to break the experience. That is why the issue is consistent rendering plus fallback, not just syntax.
A direct link flow is also useful when the PDF should behave more like a shareable page than a file, and LinkShip's PDF to Link workflow fits that need.
The three native tags solve similar problems, but they fail in different ways. That difference matters more than the syntax. In production, I treat iframe as the default, object as the fallback-friendly option, and embed as the shortest but least forgiving choice.
iframe creates its own browsing context, so it fits naturally inside a page layout. It also gives you more room for sizing rules, headers, and handoff logic. embed is terse, but its fallback story is weak, and object is the only one of the three that can render nested HTML when the PDF cannot be shown inline (PDFObject).
| Attribute | iframe | embed | object |
|---|---|---|---|
| Fallback behavior | Limited, only if the resource can't load | Weak, often no usable fallback | Strong, can show nested HTML fallback |
| Control surface | Better, with loading and same-origin messaging | Minimal | Moderate |
| Mobile reliability | Better than embed in practice, but still browser-dependent | Spotty | Better than embed, still browser-dependent |
| Best use | Default native choice | Short, simple display only | Graceful fallback and older environments |
Only iframe gives you the control hooks that matter in a real app, like loading, error handling, and postMessage when you are coordinating with same-origin UI. object is the one I reach for when I want a visible fallback link inside the element itself. embed is fine in demos, but it is the easiest one to outgrow.
The safest mental model is this, iframe is your layout tool, object is your fallback tool, and embed is your bare-minimum tool.
The catch is that all three native tags, iframe, object, and embed, rely on the browser's built-in PDF viewer, which can behave inconsistently. Desktop browsers generally handle inline PDFs well, but mobile and tablet behavior can be poor, including examples such as Chrome on Android not displaying PDFs and iOS Safari showing only the first page in some cases (Nutrient). That is why tag choice and device behavior need to be evaluated together.
The fastest way to get something live is to use explicit dimensions and a real fallback URL. Avoid vague markup and let the browser know exactly how much room the viewer gets. PDFs don't reflow like HTML, so the frame size you choose controls whether the reading experience feels calm or cramped.
Use iframe when you want the broadest native compatibility and you can live with a browser-controlled viewer. Add width and height in CSS pixels or a responsive wrapper, then keep a plain link inside the tag for browsers that fail to render the file.
<iframe src="/docs/brand-guide.pdf" type="application/pdf" width="100%" height="800" title="Brand guidelines"> <p>Your browser can't display this PDF inline. <a href="/docs/brand-guide.pdf">Download the PDF</a>.</p> </iframe>
This is the version I'd ship first for a marketing page or a help article. It's simple, readable, and easy to troubleshoot because the browser is doing the rendering. If you need a quick inline viewer and you're not trying to hide or control much, this is usually enough.
object is the better choice when you want fallback content to render for real, not just as a theoretical last resort. Put a short explanation and a direct download link inside the element so unsupported browsers, or users on restrictive devices, still get a path forward.
<object data="/docs/brand-guide.pdf" type="application/pdf" width="100%" height="800" title="Brand guidelines"> <p>This browser can't show the PDF inline. <a href="/docs/brand-guide.pdf">Download the file</a> to open it separately.</p> </object>
That nested HTML is the main reason to keep object in your toolkit. It's the least flashy option, but it gives you a cleaner degradation path when inline rendering fails.
embed is the compact version, and it's useful when you want minimal syntax and you already know the browser can render PDFs inline. It's less flexible than the other two, so I treat it as a narrow solution rather than a default.
<embed src="/docs/brand-guide.pdf" type="application/pdf" width="100%" height="800" />
I wouldn't lead with this for a public site, especially not if the audience includes Safari on iOS or Android browsers with unpredictable PDF behavior. The lack of real fallback content is the main reason. If you do use it, keep the page context simple and make the surrounding copy make the download path obvious.
Common advice to “just use an iframe” often misses mobile and managed-environment problems. A desktop demo can look fine, then the same page lands on a phone, a locked-down laptop, or a different browser family and the PDF behaves differently enough to confuse users.
Desktop browsers generally support inline PDFs well, while mobile and tablet support can be unreliable (Dynamsoft). On Android, native embedding can still trigger a download instead of inline viewing. iOS is also uneven, and browser behavior changes depending on the viewer implementation (Nutrient).
| Browser | iframe inline render | object/embed inline render | Notes |
|---|---|---|---|
| Desktop Chrome | Usually yes | Usually yes | Native viewer support is generally solid |
| Desktop Firefox | Usually yes | Usually yes | Toolbar behavior can still differ |
| Desktop Edge | Usually yes | Usually yes | Corporate policies can still change behavior |
| iOS Safari | Inconsistent | Inconsistent | Mobile handling can diverge from desktop expectations |
| Android Chrome | Inconsistent | Inconsistent | May download instead of rendering inline |
Managed devices add another layer of variance. Corporate policies, browser settings, and security tools can all interfere with the built-in PDF viewer, even on desktop browsers that usually behave well.
The practical workflow is to test support first, then use inline embedding only when the environment can handle it. PDFObject checks navigator.pdfViewerEnabled before applying browser-family heuristics, then decides whether to embed or fall back (PDFObject GitHub). That is a better fit than assuming the tag itself will behave the same everywhere.
A small guard in front of your embed can save users from a confusing two-tap path, especially when Android or a managed browser decides to download the file instead of showing it. If support looks weak, route the user to a download link or a dedicated viewer page. That is not a compromise, it is the clearer path for the device they are using.
Operational takeaway: native PDF tags are fine when the browser cooperates. When support is uncertain, send users to a predictable fallback.
Consistency matters more than chasing inline rendering in every case. If your audience includes mobile users, the goal is to show the document cleanly, without making them guess what happened.
A PDF isn't like a card or a blog embed. The text doesn't reflow when the container gets smaller, so a tiny frame often becomes a bad reading experience even if the document technically loads. That's why sizing matters as much as the tag itself.

The classic responsive trick is still useful. Wrap the embed in a container that defines its own height, then let the PDF viewer fill that space. Modern browsers also support aspect-ratio, which makes it easier to preserve a predictable viewer shape without hard-coding strange height values. The primary goal is simple, keep the document large enough that users don't have to scroll the page and the viewer at the same time.
A few patterns work well in practice:
width: 100% and height: 100%.aspect-ratio on modern browsers when you want a stable preview block.Native embedding is display-only and gives you limited control over interaction. If you need text selection, search, page-level dwell analytics, thumbnails, or consistent iOS behavior, a viewer layer is a better fit. Libraries like PDF.js, PDFObject, Mozilla's pdf.js viewer build, and react-pdf add controls that raw HTML tags don't provide.
That trade-off comes with cost. A viewer library adds bundle weight and implementation overhead, so it's overkill for a simple brochure on a marketing page. It makes more sense for annual reports, manuals, and workflows where users need to inspect the document, not just glance at it.
A clean iframe doesn't automatically mean an accessible or secure document. The question is whether the PDF content itself can be reached, understood, and safely displayed across the environments you support.
Shallow checklists usually stop at the iframe element, but that's not enough. Screen reader access depends on whether the PDF has a logical reading order, tagged structure, headings, and text that assistive technology can parse. If the source file is poorly built, the embed won't fix it.
At minimum, give the frame a descriptive title, keep a nearby download link, and provide a plain HTML summary for users who can't interact with the embedded file at all. An aria-label on the frame alone isn't a substitute for accessible PDF content. It just labels the container.
If you're embedding untrusted or semi-trusted files, iframe sandbox can limit script execution and form submission inside the frame. That matters because the risk surface is bigger than the tag itself, especially when PDFs come from mixed sources or pass through generated viewer stacks. Modern viewer approaches also isolate documents inside sandboxed iframes and CSP boundaries for the same reason (Smallpdf).
Server-side policy controls help too. Use CSP frame-src and object-src to restrict where embedded content can load from, and avoid leaving third-party PDF URLs floating through pages that weren't built to host them. If the PDF sits behind a file-sharing flow, a hosted viewer page can reduce some of the risk and make the access pattern clearer. A service like LinkShip's file hosting tools is one example of that kind of browser-based delivery.
Security gets harder the moment the PDF becomes part of a workflow. Treat the embed as a delivery surface, not a harmless image box.
The decision usually gets easier once you stop asking which tag is “best” and start asking what the document has to survive. A static PDF on a content page has a very different reliability target from an internal manual behind a proxy, or a form that people need to open on phones.
iframe with a visible fallback link when you just need an in-page reader and the audience is mostly desktop.object when unsupported clients must see usable HTML inside the element.The browser support gap is still the biggest practical issue in 2026, especially on mobile and inside managed environments. That's why “embed first, then inspect support, then degrade cleanly” remains the sane workflow. It avoids the trap of shipping markup that looks right in QA but fails for the actual people who need the document most.

If you want a browser-based handoff instead of raw file exposure, LinkShip's PDF to Link tool is one way to turn a PDF into a shareable URL with viewer-backed delivery. That isn't the same as native HTML embedding, but it solves a lot of the same distribution problems when you care more about access, tracking, and a stable viewing page than about owning the frame markup.
Start with iframe if you need something simple. Move to object if fallback matters more. Switch to a viewer when mobile reliability, accessibility, or security controls matter enough that browser defaults stop being good enough.
If you're trying to embed PDFs without guesswork, LinkShip gives you a browser-based way to turn files into shareable links with access control and analytics around the viewer experience. Visit LinkShip to see how its PDF sharing flow can fit alongside your HTML embed strategy when you need a reliable fallback path and a cleaner way to distribute documents.
Join the community
Subscribe to our newsletter for the latest news and updates