Host a Ghost Blog on AWS in 2023 (III) - Blog Customization

Host a Ghost Blog on AWS in 2023 (III)  - Blog Customization
Photo by Vincent Yuan @USA / Unsplash

Now that the website is up,  customization should come into play to address specific functional and aesthetic needs, in this post, there are a few improvements that I have done to make it better. Please note that there are a lot of tutorials already so this post just put things together.

Besides, for those who are interested in building the blog, the prior 2 parts are the go-to reference:

Host a Ghost Blog on AWS in 2023 (Part 1) - AWS Setup
I used to share a lot of programming and data science content on the Internet along with a few friends, BulletTech is one of the websites we built to this end, and we have actually learnt a lot during peer review and discussion on those topics. This reminds me of
Set Up Ghost On AWS
Host a Ghost Blog on AWS in 2023 (Part 2) - Domain Setup
Following the last part of installing Ghost on AWS, the website should be up and running, but the website can only be accessed by its IP address, so in this post the tutorial of setting up the domain will be shared to show that how your website can be access
Domain Setup for Ghost

1  Functional Enhancement

1.1 Back Up Periodically

Periodical backup ensure that you can easily restore your website when something unexpected happens. So far if you self host the blog, Ghost suggests you go to Ghost Admin, then Labs and export the content yourself periodically.

Export Your Content

This will be a .json file, with a name like my-site.ghost.2020-09-30-14-15-49.json

💡
More info regarding backup and restore can be found on the Ghost documentation.

1.2 Deploy Custom Theme via GitHub

This automatic pipeline saves a lot of time of uploading custom themes to your website.

More info can be found in the Ghost official tutorial:

Official Ghost + GitHub Integration
Set up simple continuous integration of your Ghost theme to deploy directly to your Ghost website with GitHub Actions. Share code snippets with GitHub Gists 👨‍💻
GitHub Integration

1.3 Set up Mail Delivery Service

Ghost has the ability to deliver posts as email newsletters natively. In order to do this, the bulk mail API has to be set up and now Ghost only supports Mailgun.

Configuration - Adapt your publication to suit your needs
Find out how to configure your Ghost publication or override Ghost’s default behaviour with robust config options, including mail, storage, scheduling and more!
Set up Mail for Ghost

Go to the Newsletter section of your Ghost Admin, get the domain name and private APIs from Mailgun.

Set up Newsletter
💡
Mailgun has a flex plan that does not charge you if the number of mails sent in a month is less than 1,000. But this plan is hidden on their website. It is suggested that after you create an account, open a support ticket and ask agents to directly enroll into the Flex plan for your startup website. Mostly 1,000 mails are way more than enough for beginners.

1.4 Configure Comment System

Now Ghost supports native comment system that allows members to comment on your post:

Comments
The native comments feature in Ghost allows you to invite members to join the discussion and participate in a community directly on your website. How to enable comments in Ghost Member commenting can be enabled for either All members or Paid-members only from within Ghost Admin, in the Settings →…
Native Ghost Comment System

Or you can set up Disqus to make the settings more flexible:

The complete guide to adding comments in Ghost
Comments can jump-start the conversation on your publication and give your community a place to engage with one another. This tutorial will walk you through the process of adding comments to your Ghost theme.
Set up Disqus for Ghost

2 Aesthetic Enhancement

2.1 Custom Theme

You can use whatever theme you like if you host the Ghost application yourself, that is a great benefit in my eyes, below is the official reference materials to develop your own theme:

Customizing your Ghost site even further
If you’re feeling a little more adventurous, there’s really no limit to what’s possible with Ghost.
Theme Customization

2.2 Move-to-Top button

This can be addressed by inserting code in the header and footer easily. First insert below code snippet into the header:


<!-- Reading progress bar -->
<style>
.reading-progress {
  position: fixed;
  top: 0;
  z-index: 999;
  width: 100%;
  height: 5px; /* Progress bar height */
  background: #c5d2d9; /* Progress bar background color */
  -webkit-appearance: none;
     -moz-appearance: none;
          appearance: none; /* Hide default progress bar */
}

.reading-progress::-webkit-progress-bar {
  background-color: transparent;
}

.reading-progress::-webkit-progress-value {
  background: var(--ghost-accent-color); /* Progress bar color */
}
</style>


<!--   Scroll Top Button  -->
<style>
    /*Scroll to Top CSS*/
    .scroll-top {
		position: fixed;
 		z-index: 50;
		padding: 0;
		right: 30px;
		bottom: 100px;
		opacity: 0;
		visibility: hidden;
		transform: translateY(15px);    
		height: 46px;
		width: 46px;
		cursor: pointer;
		display: flex;
  		align-items: center;
  		justify-content: center;
		border-radius: 50%;
  	transition: all .4s ease;
  	border: none;
  	box-shadow: inset 0 0 0 2px #ccc;
  	color: #ccc;
  	background-color: #fff;
	}

	.scroll-top.is-active {
		opacity: 1;
  		visibility: visible;
  		transform: translateY(0);
	}

	.scroll-top .icon-tabler-arrow-up {
  		position: absolute;
  		stroke-width: 2px;
  		stroke: #333;
	}

	.scroll-top svg path { 
		fill: none; 
	}

	.scroll-top svg.progress-circle path {
		stroke: #333;
		stroke-width: 4;
  		transition: all .4s ease;
	}

	.scroll-top:hover {
  		color: var(--ghost-accent-color);
	}

	.scroll-top:hover .progress-circle path, .scroll-top:hover .icon-tabler-arrow-up {
  		stroke: var(--ghost-accent-color);
	}
          
</style>

    <button class="btn-toggle-round scroll-top js-scroll-top" type="button" title="Scroll to top">
      <svg class="progress-circle" width="100%" height="100%" viewBox="-1 -1 102 102">
        <path d="M50,1 a49,49 0 0,1 0,98 a49,49 0 0,1 0,-98"/>
      </svg>
      <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-arrow-up" width="24" height="24" viewBox="0 0 24 24" stroke-width="1.5" stroke="cuurentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
        <path stroke="none" d="M0 0h24v24H0z" fill="none"/>
        <line x1="12" y1="5" x2="12" y2="19" />
        <line x1="18" y1="11" x2="12" y2="5" />
        <line x1="6" y1="11" x2="12" y2="5" />
      </svg>
    </button>

Then insert the code snippet into the footer:


<!--   Scroll Top Button  -->
<script>
const scrollTopBtn = document.querySelector('.js-scroll-top');
if (scrollTopBtn) {
  scrollTopBtn.onclick = () => {
    window.scrollTo({top: 0, behavior: 'smooth'});
  }
  
  const progressPath = document.querySelector('.scroll-top path');
  const pathLength = progressPath.getTotalLength();
  progressPath.style.transition = progressPath.style.WebkitTransition = 'none';
  progressPath.style.strokeDasharray = `${pathLength} ${pathLength}`;
  progressPath.style.strokeDashoffset = pathLength;
  progressPath.getBoundingClientRect();
  progressPath.style.transition = progressPath.style.WebkitTransition = 'stroke-dashoffset 10ms linear';		
  const updateProgress = function() {
    const scroll = window.scrollY || window.scrollTopBtn || document.documentElement.scrollTopBtn;

    const docHeight = Math.max(
      document.body.scrollHeight, document.documentElement.scrollHeight,
      document.body.offsetHeight, document.documentElement.offsetHeight,
      document.body.clientHeight, document.documentElement.clientHeight
    );

    const windowHeight = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);

    const height = docHeight - windowHeight;
    var progress = pathLength - (scroll * pathLength / height);
    progressPath.style.strokeDashoffset = progress;
  }

  updateProgress();
  const offset = 100;

  window.addEventListener('scroll', function(event) {
    updateProgress();

    //Scroll back to top
    const scrollPos = window.scrollY || window.scrollTopBtn || document.getElementsByTagName('html')[0].scrollTopBtn;
    scrollPos > offset ? scrollTopBtn.classList.add('is-active') : scrollTopBtn.classList.remove('is-active');

  }, false);
}
</script>

3 Conclusion

Through above improvement, the website will become more user friendly and accessible, hope it helps.

Appendix

In-depth Ghost Tutorials

Tutorials
A library of resources to help you to customize, build, and create beautiful Ghost sites
Ghost Official Tutorials