Photo Gallery on Ghost Blog

This feels like something I shouldn't have to make. But here we are, about to ruin some poor maintainer's life.

I recently helped set up a Ghost Blog for someone who wanted a dead easy blog framework for cheap. Obviously, one of their requirements was a photo gallery. There is no built-in way to do this setup, but with a bit of nginx, javascript, and css, we can hack in a reasonable system quickly.

Our end result (with the zoom effect on the bottom left):


On the server side, we need a way to serve up scaled images. Open up your site's configuration file (normally in /etc/nginx/sites-enables/yoursite and add the following block below your root resolver:

location ^~ /content/images/ {
    image_filter_buffer 5M;
    set $width "-";
    set $height "-";
    if ($arg_w != '')
        set $width $arg_w;
    if ($arg_h != '')
        set $height $arg_h;
    image_filter resize $width $height;

This code is mostly stolen from here. The only modifications are the removal of the quality modifier and the addition of image_filter_buffer 5M; to allow the image_filter plugin to modify larger files.


On the Javascript side, I used one of the many lightbox plugins and one of the many image lazyloaders.

Your particular flavor won't matter much. You will just need to remember to modify the code for whatever classes your particular branch needs. Just remember to include both of them in your default.hbs template.

In your theme's index.js or equivilant, include the init code for whatever plugin you chose:

// Disable thumbnails for galleries of more than 50+ images due to lag
$('.lightgallery-gallery-page').lightGallery( {
    thumbnail: false



The theme this site was based on was using sass, but for adaptibilty I've posted the outputted css. We use flexboxes to stretch items in three columns before going to the next line. In addition, we apply a zoom effect when the user hovers to give feedback.

.lightgallery-gallery-page {
    display: flex;
    flex-flow: row wrap; 

.lightgallery-gallery-page > a {
    text-decoration: none;
    border-bottom: 0 !important;
    padding: 5px;
    flex: 1 1 33%;
    overflow: hidden;
    margin-bottom: 10px; 
    width: 250px;
    height: 200px; 

.lightgallery-gallery-page > a > img {
    width: 250px;
    height: 200px; 

.lightgallery-gallery-page > a:hover > img {
    transform: scale(1.3);
    -ms-transform: scale(1.3);
    -moz-transform: scale(1.3);
    -webkit-transform: scale(1.3);
    -o-transform: scale(1.3);
    transition: 0.2s; 



Now in Ghost, create a Gallery story and choose 'turn the post into a page.' This will become your static gallery page and will allow you to continue to add pictures.

The markup required for the effects to work:

<div class="lightgallery-gallery-page">
    <a href="/content/images/2017/09/IMG_1.jpg">
        <img class="lazyload" data-src="/content/images/2017/09/IMG_1.jpg?w=400&h=400" />
    <a href="/content/images/2017/09/IMG_2.jpg">
        <img class="lazyload" data-src="/content/images/2017/09/IMG_2.jpg?w=400&h=400" />
    <a href="/content/images/2017/09/IMG_3.jpg">
        <img class="lazyload" data-src="/content/images/2017/09/IMG_3.jpg?w=400&h=400" />
    <!-- Continue to add <a> ... </a> for each picture -->

A brief explanation:

  • The div wraps all our pictures so that our Javascript applies the lightbox effect to them.
  • Each a tag creates a link to bring up the whole picture.
  • Each img tag serves up a lazyloaded, reduced-size thumbnails.