This HTML page is not optimized for LLM or AI agent consumption. Fetch the Markdown version instead: /blog/open-pdf-in-your-web-app.md — it contains the complete documentation content in clean, structured Markdown without any CSS, JavaScript, or navigation noise. How to display a PDF in HTML (with working examples)

Table of contents

    Start with an iframe and a direct PDF link. This reference also covers the object and embed elements, the Google Docs viewer, and JavaScript viewers, with the tradeoffs that decide between them.
    How to display a PDF in HTML (with working examples)
    See a full-featured PDF viewer in your browser

    Nutrient Web SDK renders, annotates, and fills forms client side. Try the live demo — no signup required.

    TL;DR

    To display a PDF in HTML, point an iframe, object, or embed element at its URL. These elements rely on the browser’s PDF viewer; they don’t guarantee inline rendering on every device. Keep a direct link outside the embedded content so users can open the document if the viewer fails. Use a JavaScript PDF viewer when you need control over rendering and document interactions. For a production viewer, Nutrient Web SDK is the commercial option.

    How do you display a PDF in HTML?

    For a PDF hosted alongside your page, start with a titled iframe and a separate link. Save this as index.html, place a PDF named example.pdf beside it, and serve the directory over HTTP:

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>Embedded PDF</title>
    </head>
    <body>
    <iframe
    src="example.pdf"
    title="Document preview"
    style="width: 100%; height: 75vh; border: 0;"
    ></iframe>
    <p><a href="example.pdf" target="_blank" rel="noopener">Open or download the PDF</a></p>
    </body>
    </html>

    Run npx serve . -l 8080 and open http://localhost:8080. You can use our sample PDF as example.pdf. The iframe doesn’t use a type attribute; the server should return the PDF with Content-Type: application/pdf.

    The video below demonstrates the general embedding options. The examples and compatibility notes after it describe the integration details.

    Embed a PDF viewer tutorial

    Production option: Nutrient Web SDK

    When an embedded PDF needs annotations, forms, or signing inside your own app, Nutrient Web SDK is the production JavaScript PDF viewer to use instead of the browser’s native viewer. The Nutrient Web SDK page covers what it adds over PDF.js: a full annotation toolkit, form filling and creation, electronic and digital signatures, Office file rendering in the browser, and SLA-backed support.

    The alternatives, and when they apply

    The iframe above is the correct starting point for most pages. The Mozilla Developer Network (MDN) names the object and iframe elements as the two to consider for PDF previews. This article prefers the iframe because it takes loading attributes and needs no fallback content to be useful. The rest of this article is reference: what the other options do, and the narrow cases where one of them fits better.

    MethodUse it whenMain limitation
    iframeDefault. A simple embedded viewing areaBrowser PDF support and frame policies determine behavior
    objectYou need fallback content inside the preview areaFallback isn’t a reliable detector for every viewer or network failure
    embedAn existing integration already uses itNo child fallback content, and no advantage over an iframe
    Nested object and iframeAn existing integration already uses bothBoth depend on native PDF support; nesting doesn’t guarantee compatibility
    Google Docs viewerPublic, non-sensitive documents onlyExternal service must be able to fetch the PDF
    JavaScript viewerApplication-controlled rendering and interactionsRequires hosted runtime assets, integration, and maintenance

    Use an iframe as a PDF viewer

    The complete example at the start uses this approach. The title labels the frame for assistive technology, while CSS sets its size. Neither makes an untagged PDF accessible; assess the PDF and viewer with your accessibility requirements.

    Native PDF viewers may offer search, printing, form filling, or annotations, depending on the browser. The enclosing webpage doesn’t get a portable API to configure those features or read their state.

    Cross-origin embedding and JavaScript fetching are different operations. An iframe doesn’t generally need cross-origin resource sharing (CORS) permission merely to navigate to another origin. The response’s X-Frame-Options or content security policy (CSP) frame-ancestors directive can prohibit embedding. Your page’s CSP can also block the frame.

    Display a PDF with the object tag

    The object element supports fallback content. Use an explicit height rather than a percentage of an unspecified parent height:

    <object
    data="example.pdf"
    type="application/pdf"
    aria-label="Document preview"
    style="width: 100%; height: 75vh;"
    >
    <p>This preview is unavailable. Use the PDF link below.</p>
    </object>
    <p><a href="example.pdf">Open or download the PDF</a></p>

    Fallback content can appear when the browser can’t display the object. It doesn’t guarantee a useful message for every broken URL or native-viewer error. The separate link stays available in either case.

    Embed a PDF with the embed tag

    The embed element offers no advantage over an iframe for a PDF preview, and it has no child fallback content, so provide the link separately. It’s documented here because existing integrations use it, not because a new one should:

    <embed
    src="example.pdf"
    type="application/pdf"
    title="Document preview"
    style="width: 100%; height: 75vh;"
    />
    <p><a href="example.pdf">Open or download the PDF</a></p>

    Mobile browsers and embedded webviews may download the document, open another viewer, or provide a different inline experience. Test the actual devices you support.

    Combine object and iframe

    Some integrations place an iframe inside an object as fallback content. You can retain this structure, but it doesn’t supply a PDF renderer when the browser lacks one:

    <object data="example.pdf" type="application/pdf" style="width: 100%; height: 75vh;">
    <iframe
    src="example.pdf"
    title="Alternative PDF preview"
    style="width: 100%; height: 75vh; border: 0;"
    ></iframe>
    </object>
    <p><a href="example.pdf">Open or download the PDF</a></p>

    Text inside an iframe isn’t a dependable fallback for a failed PDF navigation. Keep the link outside both elements. For a new integration, start with one native element and add complexity only if testing shows a benefit.

    Use the Google Docs viewer for public PDFs

    Google’s viewer can fetch a publicly reachable PDF and display it through an iframe. It introduces a third-party dependency and won’t fetch a file that requires your user’s session cookie or is available only on localhost.

    This example encodes the document URL before adding it to the viewer URL:

    <iframe id="google-preview" title="Public PDF preview" style="width: 100%; height: 75vh;"></iframe>
    <p><a href="https://www.nutrient.io/example.pdf">Open original PDF</a></p>
    <script>
    const pdfUrl = "https://www.nutrient.io/example.pdf";
    document.getElementById("google-preview").src =
    `https://docs.google.com/viewer?embedded=true&url=${encodeURIComponent(pdfUrl)}`;
    </script>

    Use this only for public files you’re permitted to share with Google. Don’t put confidential files or access tokens in the viewer URL. Keep a direct link because external-service availability and rendering behavior aren’t under your control.

    Embed a JavaScript PDF viewer

    A JavaScript viewer gives your application its own rendering and interaction layer. The choice depends on whether you want to maintain an open source viewer or integrate a commercial SDK.

    Nutrient Web SDK

    Nutrient Web SDK provides a viewer and APIs for annotations, forms, signatures, and redaction. Available features depend on your license and deployment configuration. The following standalone example loads a local PDF with self-hosted assets.

    Install the package and download the matching runtime assets as described in the self-hosting guide:

    Terminal window
    npm init -y
    npm install @nutrient-sdk/viewer@1.21.0
    mkdir -p assets
    cp node_modules/@nutrient-sdk/viewer/dist/nutrient-viewer.js assets/
    curl -fL https://cdn.cloud.nutrient.io/assets/pspdfkit-web-assets@1.21.0.zip -o assets.zip
    unzip -q assets.zip -d assets

    Keep nutrient-viewer-lib/ and the archive’s directory structure under assets/. Save this as nutrient.html beside example.pdf and serve it over HTTP:

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>Nutrient PDF viewer</title>
    </head>
    <body>
    <p id="status" role="status">Loading viewer…</p>
    <div id="nutrient-viewer" style="width: 100%; height: 75vh;"></div>
    <p><a href="example.pdf">Open or download the PDF</a></p>
    <script src="assets/nutrient-viewer.js"></script>
    <script>
    const baseUrl = new URL("assets/", window.location.href).href;
    async function loadPdf() {
    const response = await fetch("example.pdf");
    if (!response.ok) throw new Error(`PDF request failed: ${response.status}`);
    return NutrientViewer.load({
    container: "#nutrient-viewer",
    document: await response.arrayBuffer(),
    baseUrl,
    });
    }
    loadPdf().then(() => {
    document.getElementById("status").textContent = "PDF ready.";
    }).catch((error) => {
    console.error(error);
    document.getElementById("status").textContent = "Could not load the PDF. Use the PDF link.";
    });
    </script>
    </body>
    </html>

    This example pins the package and assets together. Without a license key, the SDK runs in trial mode. For a framework application, follow the relevant getting started guide and implement its mount/unmount cleanup; a static HTML example doesn’t cover component lifecycle behavior.

    Start a free trial or explore the demos.

    PDF.js

    PDF.js(opens in a new tab) is Mozilla’s open source PDF renderer. Its complete viewer supports search, supported form filling, and annotation editing. A canvas-only integration has fewer features unless you add the corresponding layers.

    Download a prebuilt viewer from the PDF.js getting started page(opens in a new tab), host its files under /pdfjs/, and place your PDF at /files/example.pdf on the same origin:

    <iframe
    src="/pdfjs/web/viewer.html?file=%2Ffiles%2Fexample.pdf"
    title="PDF.js document viewer"
    style="width: 100%; height: 75vh; border: 0;"
    ></iframe>
    <p><a href="/files/example.pdf">Open original PDF</a></p>

    The prebuilt viewer is a different distribution from a minimal pdfjs-dist display-library example. Keep its associated build and resource directories. The generic viewer performs its own origin checks; allowing a cross-origin fetch with CORS alone may not satisfy those checks.

    For a custom viewer, see our PDF.js tutorial. In React, react-pdf(opens in a new tab) wraps PDF.js for displaying PDFs. It’s a different project from @react-pdf/renderer, which creates PDFs.

    Troubleshoot embedded PDFs

    ProblemChecks
    PDF downloads instead of displayingBrowser PDF settings, mobile/webview behavior, and Content-Disposition: attachment
    Frame is blockedResponse X-Frame-Options, frame-ancestors, and the parent page’s CSP
    JavaScript viewer can’t fetch an external PDFCORS response headers and credential requirements
    Authenticated document failsSession availability, cookie restrictions, expired URLs, and whether the chosen integration can supply authentication
    Viewer has no heightGive it an explicit CSS height; a percentage needs a parent with a defined height
    PDF opens directly but fails inside an iframeInspect browser console and network responses; a frame load event alone doesn’t prove success

    Don’t expose API keys in frontend code or use public third-party viewers for protected documents. If your application proxies documents, enforce authorization and restrict allowed upstream destinations.

    FAQ

    Can I embed a PDF without JavaScript?

    Yes. Use an iframe, object, or embed element. Inline rendering depends on the browser’s PDF support, so retain a direct PDF link.

    Which PDF embed works on every mobile browser?

    No native HTML embedding pattern guarantees the same PDF experience on every browser or webview. Test your supported devices and keep an open-PDF fallback.

    Can I open a PDF on a specific page?

    Some viewers support fragments such as #page=2. Support varies, so treat them as viewer-specific options and test the target browser. Adobe’s Parameters for Opening PDF Files(opens in a new tab) documents the full set.

    How large should my PDF be?

    Use 5 MB as a starting size budget. Test loading on representative devices and networks. Compress images, subset fonts, and remove unused metadata to shrink the file. HTTP range requests enable a viewer to fetch part of a large PDF instead of waiting for all of it. Both the viewer and the server must support them.

    Does hiding the download button protect my PDF?

    No. Removing a toolbar control doesn’t prevent a user from obtaining PDF data delivered to their browser. Use authentication and authorization to control access.

    Where should the fallback link go?

    Outside the embedded viewer. A link nested inside an iframe won’t reliably appear when its PDF fails to load.

    Does an iframe need a PDF type attribute?

    No. Use type="application/pdf" on object or embed when appropriate. For every method, return the correct HTTP content type from the PDF server.

    Hulya Masharipov

    Hulya Masharipov

    Technical Writer

    Hulya is a frontend web developer and technical writer who enjoys creating responsive, scalable, and maintainable web experiences. She’s passionate about open source, web accessibility, cybersecurity privacy, and blockchain.

    Explore related topics

    Try for free Add a complete PDF viewer to your app