Skip to content
This repository has been archived by the owner. It is now read-only.
Switch branches/tags

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time

Project is no longer maintained

This project is no longer maintained. It was created for Ghoost version 3, a version we (as of writing) have now surpassed by a whole major. Please only use this project as a stepping stone and not as a starter for your Ghost project.

Nuxt Ghost Blog

SSR blog generated by Nuxt.js using the Ghost Content API


This project is built on the foundation of Jacob Goodwin's nuxt-ghost-starter repo. However, this project contains a lot of features that doesn't come with nuxt-ghost-starter - besides the theme, of course. To mention some of them:

  • Fully hackable
  • Based on flexbox featuring Flexgrid
  • Mobile-first
  • Websafe fonts: Source Sans Pro for main text, Roboto Mono for code, inserted with nuxt-webfontloader including display=swap
  • Tags page (a collection of all the tags and post count)
  • Code injection for head/footer
  • Better vue-meta and structured data handling
  • Syntax highlight with highlight.js featuring the Nord color palette
  • Support for menu links to external/absolute URLs
  • Automatic RSS feed generation (defaults to /rss.xml)

Amongst other features, you'll find that this project utilises modern mode to serve either legacy javascript with polyfills for older browsers, or a modern bundle for the modern browser. By careful configuration, this is disabled while in dev mode to make development faster and easier.

Note: To get the /tags page to work, you'll need to create the route in your Ghost admin panel under "Design". Simply add a desired label for the tags page and append "tags" to the URL already pre-filled in the URL field, and hit save.


This project is not going to cover how to set up Ghost. They have their own, detailed documentation on how to install and setup a Ghost site.

Note: this project does not cover the new publishing and membership features in Ghost 3.

Content API

This project takes advantage of the Ghost Content API by using their client library to fill up a Vuex store. This is smart, as we don't have to juggle many different xhr calls and just grab the data from the store. Click the links to read the Content API documentation should you want to expand the configuration, as it's fairly easy to use.

API key

To get the Content API working, you'll need to get the API key for your blog. Instructions how to get your key can be found here. Copy this API key into the .env.example-file, along with the rest of the information like the URI and URL of the blog. Rename the .env.example to .env and the @nuxt/dotenv module will pick it up and load the variables into your project. The example file contains the public Ghost demo values.

Note: The GHOST_URI and the BLOG_URL can be either the same URL, or different URLs if you only use Ghost as an API.


If you want to deploy this on Netlify, you'll need to declare the environment variables for your Netlify site. You can checkout how to on the Netlify docs. You find the variables you need to declare in the .env.example file. It's a little duplication of work, but that's how Netlify wants it.

Example of another URL:

GHOST_URI= # URL of the Content API
GHOST_KEY=12345 # Look above on how to get your API key
BLOG_URL= # In case your API and blog aren't located on the same server/domain

Follow Nuxt.js's instructions on how to deploy your site on Netlify.


When you make changes to your blog Netlify won't automagically rebuild your page, and since it's staticly generated, your content won't be generated without using a webhook. Luckily Ghost have an integration available for us to almost plug-and-play.

You will need to follow Ghost's instructions on how to add a custom integration and set it up with Netlify. You can skip step 4.


As the theme shipped with this project is the theme, you obviously can't use the themes section of the Ghost admin panel anymore. However, you can customize this theme to bits, and if you're already using Netlify or another CI/CD, you have probably hooked this up with a Git repository. Thus, the easiest way to edit the theme is just to clone the repo and start editing. Once done, just commit and push, and your CI/CD will pick up your changes.

Layout-wise, you can edit the post layout in /components/Posts.vue, as this component is almost universal to how the posts are presented in this theme. With one exception. Since single posts are a bit different, I've had to split them up. However, as is, they use the same layout. Just remember to reflect your changes into /pages/_slug.vue as well.

Everything is made in SCSS and is compiled automagically with Nuxt.js upon build. All the styling, with very few exceptions, are placed in /assets/scss/. Everything should be named logically.

You can read up on how Nuxt compiles assets in the Nuxt.js docs, and they also have a nice guide to understand the directory structure. This is one of the features that I like the most about Nuxt.js.


Date formats are presented with Day.js which is a lightweight alternative to moment.js. If you need localication, please refer to their documentation.


This project is configured to act as a Progressive Web App (PWA), which means there is a worker that makes sure your site can both be installed as an app, and will work offline for repeating visitors. This is all automatically done via Nuxt.js's PWA module. It takes into account what values you've entered in your Ghost settings, like site name and description, and builds a manifest.json containing the values from your API. It also automatically compiles a favicon image into multiple, app-friendly icons.

If you want a different favicon, you simply replace the image found in /static/icon.png. You can read more about Nuxt.js's PWA module in their PWA documentation.

Other configuration

Inside /config/ you'll find different config files that are used to extend the Nuxt.js config while keeping it as clean as possible, and splitting the config files into relevant files instead. These are then imported into nuxt.config.js. Most relevant here is probably /config/ghost.js which handles how the Content API client library interacts with the Vuex store.

Development and build Setup

# Install dependencies
$ yarn install

# Serve with hot reload at localhost:3000
$ yarn dev

# Build for production and launch server
$ yarn build
$ yarn start

# Generate static project
$ yarn generate

You can of course use NPM as well.


PRs are welcome encouraged! If you see an error, fork, clone, fix, and send a PR my way. Credit will be given.

As this project is hooked up with both prettier and eslint, you'll likely bump into some errors once you start hacking, but will show you a friendly error message and how to fix it. Husky will lint your files before pushing to Git. These are only for your protection, and makes sure the code follows a certain standard.

This project use the standard Nuxt ESLint Config and will also lint your .vue files. Prettier will do the same, however, less strict as I haven't set up too many rules for it. And the .editorconfig-file will configure your editor to follow a certain set of standard rules that makes sure your code should look the same (if your editor supports editorconfig).

Happy hacking!




SSR blog generated by Nuxt.js using the Ghost Content API







No releases published


No packages published