Adding a Download Button to PhotoSwipe 4

Photoswipe 4 is a gallery lightbox coded in JavaScript by Dmitry Semenov. This lightbox is powerful, yet clean out of the box and offers many features, such as multi-device compatibility. While it has yet to support videos, it is perfect for images.

If you're on this post, then you're likely dissatisfied with how the download "button" in the default configuration is nested within the "Share" button, which may not be intuitive for users visiting your image gallery.

In this beginner-friendly tutorial, I will walk you through how to add a custom download button to PhotoSwipe 4. (It's also a tutorial for me in case I forget in the future.)


Before following this tutorial, you will need a few things:

  • Basic understanding of C-based programming
  • Basic understanding of string properties and operations
  • Web server with PhotoSwipe installed
  • Text-editor (preferably with syntax highlighting)
  • (Optional) Either Adobe Illustrator/Image Vector Editor or any photo editor

Step 1: Set Up Button Framework

First, we are going to create the backbone for our button. I will first introduce the necessary code, where to add them, and why each line matters.

We begin by opening photoswipe-ui-default.js in our favorite text editor.

Find the _defaultUIOptions array.

Scroll down a little bit, and you’ll find variables such as zoomEl, which is responsible for controlling whether the zoom element is enabled in the lightbox. We will add a variable named downloadEL and enable it.

_defaultUIOptions = {
    zoomEl: true,
    downloadEl: true,
    shareEl: true,

Then, we need to create the button itself in JavaScript. Find the _uiElements array. We’ll create an element titled button-download and have its state specified by downloadEL.

var _uiElements = [
    name: 'button-download', 
    option: 'downloadEl',
    onTap: function() {

The contents nested in onTap: function() will be executed once the button is pressed. We have yet to write the _download function, but we’ll get to it later.

Now, we have half of the code back-end set up. We now need to work on the front end.

Add the HTML button element among the buttons you have already in your HTML. Order here does matter, and I’ve decided to place it between the Zoom and Fullscreen toggle buttons.

<button class="pswp__button pswp__button--close" title="Close (Esc)"</button>
<button class="pswp__button pswp__button--share" title="Share"</button>
<button class="pswp__button pswp__button--fs" title="Toggle fullscreen"</button>
<button class="pswp__button pswp__button--download" title="Download image"</button>
<button class="pswp__button pswp__button--zoom" title="Zoom in/out"</button>

Step 2: Add button graphics and CSS

Now we need to give the code a download icon to work with so users have a visible button to press.

PhotoSwipe’s button icons are stored and called from default-skin.png.

For reference, the vector graphic is also supplied with the download in default-skin.svg

You will have either: find a vector graphic or PNG image of the download icon that you want and use an image editor to add it. Either way, you must ensure that your icon is spaced as equally as possible, similar to the other icons. Either way, the final image should be exported to PNG.

I have personally used a FontAwesome vector and my vector graphic and PNG can be found below to save some time if you’d like. My download icon is placed in the top row.

Replace the provided PNG with the PNG with the download icon.

Now we need to use CSS to add the download icon and to specify its location in default-skin.png.

Open default-skin.css and add the following highlighted code:

.pswp__button--close {
  background-position: 0 -44px; }

.pswp__button--download {
  background-position: -176px 0px; }

.pswp__button--share {
  background-position: -44px -44px; }

As you can see, spacing is per every 44px so adjust yours accordingly if you’ve made your own adjustments.

Once this is done, you can go into your gallery and see your download button come to life. You may need to clear cache. Hard refreshes are recommended.

You can press it, but nothing will occur since we have yet to specify a download function. If the button does not appear, you might need to look at your code.

Step 3: Configure a download function

Normally, you would use HTML to initialize the download, but since the JavaScript is dynamic and already handles download URLs, we can use built-in PhotoSwipe functions to automatically retrieve the image URL for each image that is currently displayed in the lightbox.

I have added the following code above _uiElements in photoswipe-default-ui.js.

function _download() { 
    var link = document.createElement('a');
    var photoURL = image_url;
    var ext = photoURL.length;
    var slash = photoURL.lastIndexOf("/"); = photoURL.substring(slash+1, ext);
    link.href = image_url;

PhotoSwipe stores the link to each image in the string image_url.

The strategy is to append a element in HTML, specify the download URL, file name, and then automatically click that link behind the scenes.

Above, the name of the file is specified after the last backslash until the end. We use string operations to extract the index of each location and then assign this interval to a

IMPORTANT: Although the coding is now done, you will also want to reflect your JavaScript changes in the minified version photoswipe-default-ui.min.js. Minification optimizes our code to use as least space as possible by cleaning up code and removing comments. I used JSCompress to achieve this.

Once done, upload all files to the server and you’re done!

Optional: Custom download links

This is extra code for if the images you want your visitor to download is NOT the image that is displayed in the lightbox. For example, I display 1546×1240 images in my lightboxes (for 3:2 images) to conserve visitor bandwidth and to reduce load on the server. Adding full resolutions in 6000×4000 and higher and having WordPress crunch images with a low-RAM server configuration is simply not reasonable.

As a result, my full resolution images available for dowonload are located in a subfolder where the smaller images are stored: /full/.

Now, one could use a combination of Regex and redirects to accomplish, but you’ll find it will take longer for the URL to process and that the previous download script will trigger one to view the image (depending on the browser) rather than a forced download.

function _download() { 
    var link = document.createElement('a');
    var photoURL = image_url;
    var ext = photoURL.length;
    var slash = photoURL.lastIndexOf("/"); = photoURL.substring(slash+1, ext);
    var photoURLFull = photoURL.substring(0,slash+1) + 'full' + photoURL.substring(slash,photoURL.length);
    link.href = photoURLFull;

We call parts of the original image URL while adding our own modification to the download URL.

Somewhat Comprehensive Multivariable & Vector Calculus Formula Sheet

Add a comment