Skip to content
Embedded PDF Files - Free Tutorial
Browse other ways to boost conversion rate & profit

Embedded PDF Files - Free Tutorial

In this tutorial, we show you how to add embedded PDF files to your Shopify store, a conversion-boosting customization that enhances your customer experience. This feature can help you share detailed information to simplify buyer decisions. And simpler customer decisions means more profit margins that will help you scale effectively.

Compatible Themes: This code should work on all free Shopify themes (Dawn, Refresh, Craft, Studio, Publisher, Crave, Origin, Taste, Colorblock, Sense, Ride, Spotlight).

 

Create metafield (product, collection, page, etc) for dynamic behavior

  • Create product metafield
    • Name: PDF File
    • Namespace and key: custom.pdf_file
    • Type: Single line text

Create new section file pdf-file-viewer-custom.liquid

{%- if section.settings.pdf_file != blank -%}

  <script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.10.377/pdf.min.js" defer="defer"></script>
  
  <div class="pdf-file-viewer-{{ section.id }} page-width section-{{ section.id }}-padding" style="position: relative;">
    <div class="pdf-container-wrapper-{{ section.id }}">
      <div class="pdf-container-{{ section.id }}">
        <div id="pdf-viewer-{{ section.id }}" style="position: relative;"></div>
      </div>
      <div class="zoom-controls-{{ section.id }}">
        <button class="zoom-in-{{ section.id }}">
          <svg width="30" height="30" viewBox="0 0 30 30" aria-hidden="true">
            <circle cx="15" cy="15" r="15" fill="rgba(0, 0, 0, 0.5)"/>
            <line x1="8" y1="15" x2="22" y2="15" stroke="white" stroke-width="2"/>
            <line x1="15" y1="8" x2="15" y2="22" stroke="white" stroke-width="2"/>
          </svg>
        </button>
        <button class="zoom-out-{{ section.id }}">
          <svg width="30" height="30" viewBox="0 0 30 30" aria-hidden="true">
            <circle cx="15" cy="15" r="15" fill="rgba(0, 0, 0, 0.5)"/>
            <line x1="8" y1="15" x2="22" y2="15" stroke="white" stroke-width="2"/>
          </svg>
        </button>
      </div>
    </div>
  </div>
  
  {%- style -%}
    .section-{{ section.id }}-padding {
      padding-top: {{ section.settings.padding_top | times: 0.75 | round: 0 }}px;
      padding-bottom: {{ section.settings.padding_bottom | times: 0.75 | round: 0 }}px;
    }
  
    @media screen and (min-width: 750px) {
      .section-{{ section.id }}-padding {
        padding-top: {{ section.settings.padding_top }}px;
        padding-bottom: {{ section.settings.padding_bottom }}px;
      }
    }
  
    .pdf-container-wrapper-{{ section.id }} {
      position: relative;
      width: {{ section.settings.width }}%; 
      margin: 0 auto;
    }
  
    .pdf-container-{{ section.id }} {
      position: relative;
      overflow-y: scroll;
      -webkit-overflow-scrolling: touch;
      height: 70vh;
      min-height: 400px;
    }
  
    @media (max-width: 749px) {

    .pdf-container-wrapper-{{ section.id }} {
      position: relative;
      width: 100%; 
      margin: 0 auto;
    }
      
      .pdf-container-{{ section.id }} {
        height: {{ section.settings.mobile_height }}px;
      }
    }
  
    .pdf-container-{{ section.id }}::-webkit-scrollbar {
      width: 8px;
    }
  
    .pdf-container-{{ section.id }}::-webkit-scrollbar-thumb {
      background-color: rgba(0, 0, 0, 0.6);
      border-radius: 10px;
    }
  
    .pdf-container-{{ section.id }}::-webkit-scrollbar-track {
      background: rgba(0, 0, 0, 0.1);
    }
  
    .pdf-container-{{ section.id }}::-webkit-scrollbar-thumb:hover {
      background-color: rgba(0, 0, 0, 0.8);
    }
  
    .zoom-controls-{{ section.id }} {
      position: absolute;
      top: 10px;
      right: 20px;
      display: flex;
      flex-direction: column;
      gap: 5px;
      z-index: 1000;
    }
    
    @media (max-width: 749px) {
      .zoom-controls-{{ section.id }} {
        right: 15px; /* Different position for mobile devices */
      }
    }
    
    @media (min-width: 750px) and (max-width: 989px) {
      .zoom-controls-{{ section.id }} {
        right: 20px; /* Different position for tablets */
      }
    }
  
    .zoom-controls-{{ section.id }} button {
      padding: 0;
      border: none;
      background: none;
      cursor: pointer;
      transition: opacity 0.3s ease;
    }
  
    .zoom-controls-{{ section.id }} button:hover {
      opacity: 0.8;
    }
  {%- endstyle -%}
  
  <script>
  document.addEventListener("DOMContentLoaded", function() {
    var url = "{{ section.settings.pdf_file | escape }}";
    var pdfjsLib = window['pdfjs-dist/build/pdf'];
    pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.10.377/pdf.worker.min.js';
  
    var pdfDoc = null,
        currentPage = 1,
        scale = 1.0,
        canvasContainer = document.getElementById('pdf-viewer-{{ section.id }}'),
        pdfContainer = document.querySelector('.pdf-container-{{ section.id }}'),
        zoomInButton = document.querySelector('.zoom-in-{{ section.id }}'),
        zoomOutButton = document.querySelector('.zoom-out-{{ section.id }}');
  
    function renderPage(num) {
      pdfDoc.getPage(num).then(function(page) {
        var viewport = page.getViewport({ scale: scale });
        var canvas = document.createElement('canvas');
        var ctx = canvas.getContext('2d');
        canvas.height = viewport.height;
        canvas.width = viewport.width;
  
        canvasContainer.appendChild(canvas);
  
        var renderContext = {
          canvasContext: ctx,
          viewport: viewport
        };
  
        page.render(renderContext);
      });
    }
  
    function renderAllPages() {
      canvasContainer.innerHTML = '';
      for (var num = 1; num <= pdfDoc.numPages; num++) {
        renderPage(num);
      }
    }
  
    function adjustScale() {
      if (pdfDoc) {
        pdfDoc.getPage(1).then(function(page) {
          var containerWidth = pdfContainer.clientWidth;
          var viewport = page.getViewport({ scale: 1 });
          scale = containerWidth / viewport.width;
          renderAllPages();
        });
      }
    }
  
    function zoomIn() {
      scale *= 1.2;
      renderAllPages();
    }
  
    function zoomOut() {
      scale /= 1.2;
      renderAllPages();
    }
  
    pdfjsLib.getDocument(url).promise.then(function(pdfDoc_) {
      pdfDoc = pdfDoc_;
      adjustScale();
    });
  
    window.addEventListener('resize', adjustScale);
  
    pdfContainer.style.overscrollBehavior = 'contain';
    
    let lastScrollTop = 0;
    pdfContainer.addEventListener('scroll', function(e) {
      let st = pdfContainer.scrollTop;
      if (st <= 0 || st + pdfContainer.offsetHeight >= pdfContainer.scrollHeight) {
        pdfContainer.style.overscrollBehavior = 'auto';
      } else {
        pdfContainer.style.overscrollBehavior = 'contain';
      }
      lastScrollTop = st <= 0 ? 0 : st;
    }, false);
  
    zoomInButton.addEventListener('click', zoomIn);
    zoomOutButton.addEventListener('click', zoomOut);
  });
  </script>

{%- endif -%}
            
{% schema %}
{
  "name": "PDF File Viewer",
  "settings": [
    {
      "type": "text",
      "id": "pdf_file",
      "label": "PDF file path",
      "default": "https://cdn.shopify.com/s/files/your-file.pdf"
    },
    {
      "type": "range",
      "id": "mobile_height",
      "min": 400,
      "max": 1200,
      "step": 50,
      "unit": "px",
      "label": "Height of embedded PDF viewer (mobile)",
      "default": 600
    },
    {
      "type": "range",
      "id": "width",
      "min": 50,
      "max": 100,
      "step": 5,
      "unit": "%",
      "label": "Width % of embedded PDF viewer",
      "default": 100
    },
    {
      "type": "header",
      "content": "t:sections.all.padding.section_padding_heading"
    },
    {
      "type": "range",
      "id": "padding_top",
      "min": 0,
      "max": 100,
      "step": 4,
      "unit": "px",
      "label": "t:sections.all.padding.padding_top",
      "default": 36
    },
    {
      "type": "range",
      "id": "padding_bottom",
      "min": 0,
      "max": 100,
      "step": 4,
      "unit": "px",
      "label": "t:sections.all.padding.padding_bottom",
      "default": 36
    }
  ],
  "presets": [
    {
      "name": "PDF File Viewer",
      "category": "Custom"
    }
  ]
}
{% endschema %}

Browse other ways to boost conversion rate & profit

Here's 4 Ways We Can Help You

Here's 4 ways we can help you:

  1. Get our high-converting theme that generated us $4.3M in sales: Click here
  2. Find Conversion Leaks that cost you orders and profit: Click here
  3. Work with us to add $10,000 to your store in 10 weeks. Send an email to hello [at] theprompted.co with the subject line “10k”
  4. Email us to work privately on custom development. Send an email to hello [at] theprompted.co and use the subject line "custom", and then detail out what you have in mind, including all specifics.