How to customise "Unsubscribe" link?

Dear Ghost community,

Building my blog on Ghost was nothing but a delight, even though I’m self-hosting it. Still I was able to customise emails by editing api.js, signup.js and signin.js. However, I can’t find a template to customise a newsletter, especially the “Unsubscribe” link. I have tried:

  1. Searching all files in the Ghost folder by keywords: unsubscribe and parameters uuid, newsletter that are present in the generated link.
  2. Searching folders manually and there is no email template in the members/emails folder.
  3. Searched the forum and found one similar question, which is still unanswered.

How can I customise “Unsubscribe” action in the newsletter and insert a custom link?
Thank you in advance.

Are you looking for this?

@vikaspotluri123 thank you for the reply. I can’t find this file in my local Ghost installation. The local installation version is: 5.69.1.

  1. I have searched for “template.hbs” within the the Ghost folder. The file you posted was not found. Even the folder structure is different from the one you showed, probably it changes after Ghost is compiled.
  2. I have searched for “email-templates” and the only folder I found is: Ghost/versions/5.69.1/core/server/services/comments/email-templates, where I have comment and report templates.
  3. To experiment I tried to search for “email” folder. I have found this file: 5.69.1/core/server/services/mail/templates/newsletter.html. It is different from my actual newsletter and changing it didn’t produce any results.

Maybe someone has a local install and is able to double check on the file @vikaspotluri123 has posted, please?

It would be in the node_modules because @tryghost/email-service is a dependency of the Ghost server. You’re right that Ghost has a compile step which is why it’s a bit obfuscated :slight_smile:

Try versions/5.69.1/node_modules/@tryghost/email-service/lib/email-templates/?

@vikaspotluri123 Even thought it might be a correct path to the file, modifying it changes nothing.

In the file: /var/www/ghost/versions/5.28.0/node_modules/@tryghost/email-service/lib/email-templates/template.hbs
I replaced the <a href="%%{unsubscribe_url}%%"> with <a href="https://my_custom_URL"> and restarted Ghost.

It didn’t help after the Ghost restart. The URL in the newsletter stayed the same. I decided to check if HTML in the opened newsletter corresponds to the one in template.hbs. It has some differences, for example class names have random numbers, like: class="m_-216777451830...footer", where in the template it is just: <td class="footer">.

I haven’t found any other similar template.hbs file, but I made an assumption that email template is not generated by this file. I took a different route and modified the /versions/5.28.0/node_modules/@tryghost/email-service/lib/email-renderer.js file which generates the %%{unsubscribe_url}%% used in template.hbs.

I replaced this function:

 createUnsubscribeUrl(uuid, options = {}) {
        const siteUrl = this.#urlUtils.urlFor('home', true);
        const unsubscribeUrl = new URL(siteUrl);
        unsubscribeUrl.pathname = `${unsubscribeUrl.pathname}/unsubscribe/`.replace('//', '/');
        if (uuid) {
            unsubscribeUrl.searchParams.set('uuid', uuid);
        } else {
            unsubscribeUrl.searchParams.set('preview', '1');
        if (options.newsletterUuid) {
            unsubscribeUrl.searchParams.set('newsletter', options.newsletterUuid);
        if (options.comments) {
            unsubscribeUrl.searchParams.set('comments', '1');

        return unsubscribeUrl.href;

With a function that just returns my custom URL:

createUnsubscribeUrl(uuid, options = {}) {
    const unsubscribeUrl = "https://my_custom_URL";
    return unsubscribeUrl;

I reverted template.hbs back to the original, restarted Ghost and even rebooted the server. However, the URL stayed the same, it still has uuid and newsletter parameters, even though I modified the function.

I’m totally confused now. Please, help me put custom unsubscribe link in the newsletter.

Quick simple check before we go further - Are you still on Ghost 5.28.0? If you updated Ghost, that’s the wrong path to change!

Yes, I’m still running version 5.28.0

Have you tried modifying template-old.hbs as well (ref)?

As a note, this is approaching the boundary of where I can help, since I don’t have mailgun set up to actually step through and debug.

Thank you for the reference file!

There is no template-old.hbs in ./email-templates. Also, I navigated to the root Ghost root folder and run grep -rl "template-old.hbs" and grep -rl "template-old" to doublecheck. Unfortunately, nothing came back.

Moreover, the template-old.hbs is not even mentioned in EmailRenderer.js:

        // Actual template
        const htmlTemplateSource = await fs.readFile(path.join(__dirname, './email-templates/', `template.hbs`), 'utf8');
        this.#renderTemplate = this.#handlebars.compile(Buffer.from(htmlTemplateSource).toString());
        return this.#renderTemplate(data);

I appreciate your efforts and understand at this point it will be difficult for you to help me further. I will update Ghost to the newest version and will try to modify template.hbs or EmailRenderer.js.
Maybe Ghost update will solve this issue by itself.

1 Like

Updated Ghost to the latest version which has template-old.hbs my previous installation was missing. Edited the unsubscribe URL and it worked!