miinideckmiinideck
PricingUse casesBlog
Sign in
How-to & formats

Embedding a PDF in an HTML page you're about to send (2026)

The iframe snippet works on your laptop because the PDF is sitting next to the HTML. The moment the page travels, it's two files — and only one of them arrives. What actually survives the trip.

By miinideck·August 8, 2026·Updated September 10, 2026·7 min read
TL;DR
  • The snippet works locally for one reason: <iframe src="report.pdf"> means "the file sitting next to me", and on your machine that file is sitting right there. Share the page and the HTML travels alone — the frame resolves to nothing and you get a blank box.
  • Three fixes look plausible and two of them quietly aren't. Base64-inlining works for images but browsers block data: URLs in frames, so it doesn't carry over to PDFs. Zipping the pair only helps if the host actually serves .pdf files — many static hosts, miinideck included, serve a curated set of web asset types and skip the rest. An absolute https:// URL is the one that reliably survives.
  • The honest first question is whether the PDF should be in the page at all. A PDF in a frame is a scrollbar inside a scrollbar and doesn't reflow on a phone. If the reader is meant to read it, put the content in the page; if they're meant to keep it, give them a download link.

You built a page — a report, a proposal, a client summary — and there's a PDF that belongs with it. The spec sheet, the signed contract, the appendix nobody rebuilt in HTML. So you search for how to show a PDF inside a web page, find the snippet everyone finds, and drop it in:

<iframe src="report.pdf" width="100%" height="800"></iframe>

Refresh. There it is, rendering perfectly. Job done.

Then you send the page to someone, and they see a blank rectangle.

The snippet was never about the PDF — it was about the neighbour

src="report.pdf" is a relative path. It doesn't mean "this PDF"; it means "whatever file happens to be sitting next to me called report.pdf." On your laptop, there is such a file, in the same folder, so the browser finds it instantly.

The instant the page travels, that sentence stops being true. You upload one .html file, or attach it to an email, or paste it into a host — and the HTML goes, and the PDF stays behind. The frame does exactly what you told it to: it looks for a neighbour, finds nobody, and renders empty. Nothing is broken. The page is just describing a room it no longer lives in.

This is the same shape as an AI share link that opens fine for you and not for them — the thing worked on the side where all the context was, and the context was the part that didn't travel.

The two fixes that look right and aren't

Base64-inlining it. This is the reflex, and it's a good reflex — it's exactly how you make images travel inside a single HTML file. Encode the file, paste it into the src, done. It works for images because <img src="data:image/png;base64,…"> is permitted essentially everywhere.

It does not carry over to PDFs, because a PDF has to render in a frame, and browsers deliberately block navigating a frame to a data: URL — Chrome has enforced that for years as an anti-phishing measure. So the encoded PDF sits in your file, adds about a third to its size, and still shows a blank box. The trick that saves images is the wrong tool here.

Zipping the HTML and the PDF together. Reasonable instinct — a ZIP is the right container for a genuinely multi-file build, and the relative path would resolve if both files got served. The catch is that "served" is doing a lot of work in that sentence. Static hosts generally serve a curated set of web asset types — HTML, CSS, JS, images, fonts — and skip everything else, partly for security and partly because anything else isn't a web page.

miinideck works this way too, and it's worth being blunt about it: a .pdf inside an uploaded ZIP is skipped, not served. The upload succeeds, the page goes live, and the frame 404s — which is a worse failure than an outright rejection, because nothing warns you. Whatever host you're using, this is the thing to test before you send: upload the bundle, open the live URL yourself, and check the frame actually renders. Don't check the source; check the page.

While you're testing, one more thing to know about strict hosts, ours included: <embed> and <object> are the plugin-era elements, and they're the first two a tight security policy switches off. <iframe> is the modern equivalent and is far more widely allowed. If you're copying a snippet, copy the <iframe> one.

Testing whether your page survives the trip is the whole point — drop the HTML, open the link yourself, and see what your reader will see before they do. No card, no account.

Try it free (no signup)

The one that survives: an absolute URL

If the PDF genuinely has to render inside the page, give the frame an address instead of a neighbour:

<iframe src="https://example.com/files/report.pdf" width="100%" height="800"></iframe>

Now the page carries no assumption about what's sitting beside it. Wherever the HTML ends up, the frame goes and fetches the PDF from a place that exists. This is the version that works on a hosted link, in a colleague's downloads folder, and on a phone.

Three things to get right. The address has to be the file itself — a URL that ends in the PDF. A private-link host's viewer page is a different thing: it's a web page wrapped around the file, and hosts that care about who sees a page usually refuse to be framed by someone else's site. Ours is one of them — embedding miinideck pages in other sites isn't supported right now — so a miinideck link belongs in the page as a link, not inside an iframe. The URL also has to be https:// — a page served over HTTPS won't load an http:// frame, and you'll get another blank box for a completely different reason. And the PDF needs to live somewhere that will still be there in six months, which usually means your own storage or a document host, not a temporary link from a chat thread.

The honest version: it probably shouldn't be embedded

Everything above answers the question as asked. It's worth asking a different one before you use any of it.

A PDF inside a web page is a document inside a document. The reader gets a scrollbar within a scrollbar, a fixed page size that doesn't reflow on a phone, text that's harder to select and search, and a zoom level that's never quite right. It's a viewer bolted into a page that was already a perfectly good viewer.

So the question is what the reader is meant to do with it:

  • Read it → put the content in the page. If an AI built the page, ask it to fold the PDF's content into the HTML rather than embed the file. That's the whole case for sending HTML instead of a PDF: the page reflows, reads on a phone, and doesn't ask anyone to pinch-zoom a fixed A4 layout.
  • Keep it → give them a plain download link. They want the file — to sign it, file it, forward it — and a frame is friction between them and the download button.
  • The PDF is the deliverable → skip the HTML page altogether and send the PDF as its own link. We started taking PDFs directly in September 2026, so the file you already exported can go up exactly as it is — sharing a PDF as a private link covers what the reader sees and what a link can't fix about a PDF.
  • Read it and keep it, and it can't be rebuilt → the absolute-URL iframe above, with a download link underneath it.

Most of the time the first option is both less work and a better page. The embed is a habit carried over from a world where the PDF was the deliverable; when the page is the deliverable, the format question is worth answering deliberately rather than by reflex.

More in How-to & formats

How do I edit a password-protected HTML page without re-encrypting it?

Client-side encryption tools turn your page into an encrypted file, so the protection and the artifact are the same object — every edit means re-running the tool and re-uploading. What that actually costs, the salt setting that decides whether your old share links survive, and when a hosted password is the better trade.

September 25, 2026·6 min read

Anyone can read your page's source. Which services can it still use?

A static page has no backend and no secrets, which sounds like it rules out forms, payments and bookings. It doesn't. The line isn't 'frontend versus backend' — it's whether the credential you'd have to publish is designed to be published. How to tell, in one question, before you build.

September 6, 2026·7 min read

How to share a data dashboard without giving someone a login (2026)

The person who needs your dashboard usually has no seat in your BI tool — and buying one is the wrong fix. How to ship a live, interactive dashboard to a no-login viewer, and where a live connection beats a snapshot.

September 5, 2026·6 min read

Send your own private link.

miinideck turns a single HTML file into an unguessable link with optional password and expiry. Default-private, never indexed.

Try it free →See pricing
miinideck

HTML files, finally as links — for AI builders, agencies, and consultants. Default-noindex, default-private, default-yours.

Product

  • Pricing
  • Use cases
  • Try it free

Resources

  • Blog
  • Free tools
  • Featured on
  • Report abuse

Legal

  • Privacy
  • Terms
Listed onmiinideck listed on Product Huntmiinideck listed on Faziermiinideck listed on TheSaaSDirmiinideck listed on AIToolHuntmiinideck listed on LaunchNest
© 2026 miinideckMade for people who don't want their work indexed.