How to use Cloudinary with Ghost.js
Tags: ghostjs, cloudinary, jamstack
Published: 2021-07-29 12:41:50

---
title: How to use Cloudinary with Ghost.js
published: true
description: This is the story how I've configured my locally installed Ghost to work with Cloudinary and Nuxt.js at the front
tags: ghostjs, cloudinary, jamstack
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ec79ziew0o9ud0ctlny4.png
---

## Introduction
[Ghost.js](https://ghost.org/) - is an open-sourced blog publishing platform built with Node.js (with great help of Handlebars, of course). It has amazing Medium-like [inline editor](https://github.com/TryGhost/Admin/tree/main/lib/koenig-editor), which is simple and inspiring for writing new content without any hastle.

[Cloudinary](https://cloudinary.com/) is "a cloud-based SaaS that provides an end-to-end image and video management solution including uploads, storage, manipulations, optimizations and delivery. All your media resources are optimized and delivered through a fast CDN using industry best practices."

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x357xvf5u613gjk9y65i.png)

## Cloudinary in Ghost.js
Why bothering with another post if everything is in the docs? That's because of specifity of my current task: I want to Ghost.js be on my local machine, uploading all images to Cloudinary and build static front with Nuxt.js.

Well, there is [adapter solution](https://github.com/eexit/ghost-storage-cloudinary) which will allow us/me/you to automatically fetch ALL (that's the pit) uploaded images to Cloudinary. It's a good solution except lack of control for my images at the front.

## My solution
I've dig Internet a bit/a lot and found my way to fetch images to Cloudinary. First of all, I've modified Ghost config. As it is my local installation, I've used dev config.

```json
"imageOptimization": {
    "cloudinary": {
      "baseUrl": "https://res.cloudinary.com/summertimesadness/image/fetch/f_auto,q_auto"
    }
}
```

This config is using default `imageOptimization` object, so there is no need to double-check it's presence in the guts of Ghost.js. Cloudinary settings object is WIP, but it's working fine already. 

The second step is to modify/fork/make pr into several Ghost packages, responsible for image set generation. This is not the best way to deal with this problem, but certainly it gives you more control over image content in your blog then using adapter (correct me, if I'm wrong).

So, you'll need to find this package: `@tryghost/kg-default-cards/lib/cards/image.js`. Then you'll need to change `render` method a bit:

```js
const { cloudinary } = options.imageOptimization;

const payloadSrc = cloudinary ? `${cloudinary.baseUrl}/${payload.src}` : payload.src;
img.setAttribute('src', payloadSrc);
```

This will prefix every image `src` inside your post with Cloudinary fetch url with chosen params.

Next step, you will change the way srcset is generated. Find `@tryghost/kg-default-cards/lib/utils/set-srcset-attribute.js` module.

```js
srcsetWidths.forEach((width) => {
  if (width === image.width) {
     // use original image path if width matches exactly (avoids 302s from size->original)
     srcs.push(`${image.src} ${width}w`);
  } else if (width <= image.width) {
     // avoid creating srcset sizes larger than intrinsic image width
     if (options.imageOptimization.cloudinary) {
        srcs.push(`${options.imageOptimization.cloudinary.baseUrl},w_${width}/${imagesPath}/${filename} ${width}w`);
     } else {
        srcs.push(`${imagesPath}/size/w${width}/${filename} ${width}w`);
     }
   }
});
```

After making this code modifications you'll need to `ghost restart` and reupload images in your posts. Then you'll get (in your static site front) such piece of code in api response:

```html
...
<figure class="kg-card kg-image-card">
  <img src="https://res.cloudinary.com/summertimesadness/image/fetch/f_auto,q_auto/http://localhost:2368/content/images/2021/07/aspect-ratio-3.png" class="kg-image" alt="" loading="lazy" width="944" height="444"
    srcset="https://res.cloudinary.com/summertimesadness/image/fetch/f_auto,q_auto,w_600/http://localhost:2368/content/images/2021/07/aspect-ratio-3.png 600w, https://res.cloudinary.com/summertimesadness/image/fetch/f_auto,q_auto,w_944/http://localhost:2368/content/images/2021/07/aspect-ratio-3.png 944w"
    sizes="(min-width: 720px) 720px">
</figure>
...
```

## PS
This is proof of concept and I'm still searching for ways to achieve my result in better ways. Every `ghost update` will destroy your code changes (or better say, it will stay in older versions folder). But if you want better PageSpeed Insights metrics, free static site hosting and amazing post editor hosted locally on your laptop - may be this is the way. 

Also I hope to read in comments if you had anything related with your static site generator and Ghost.js and how you've solved it. May be together we'll find better way to integrate Cloudinary (or such) service with Ghost.js.