Working With Hexo
Table of contents

Learn how to spin up a site using Ghost as a headless CMS and build a completely custom front-end with the static site generator Hexo. The following sections cover how to source content from Ghost and feed it directly in a site created with Hexo.

Prerequisites

This configuration of a Ghost publication requires existing moderate knowledge of JavaScript. You'll need an active Ghost account to get started, which can either be self-hosted or using a Ghost(Pro) account.

Additionally, you'll need to install Hexo via the command line:

npm install -g hexo-cli

This documentation also assumes Ghost will be added to an existing Hexo site. creating a new Hexo site can be done with the following command:

hexo init my-hexo-site

Running the Hexo site locally can be done by running hexo server and navigating to http://localhost:4000/ in a web browser.

More information on setting up and creating a Hexo site can be found on the official Hexo site.

Getting started

Firstly, create a new JavaScript file within a scripts folder at the root of the project directory, for example ./scripts/ghost.js . Any script placed in the scripts folder acts like a Hexo script plugin, you can find out more about the Plugins API in the Hexo documentation.

Next, install the official JavaScript Ghost Content API helper using:

yarn add @tryghost/content-api

Once the Content API helper is installed it can be used within the newly created ghost.js Hexo script:

const ghostContentAPI = require("@tryghost/content-api");

const api = new ghostContentAPI({
  url: 'https://demo.ghost.io',
  key: '22444f78447824223cefc48062',
  version: "v3"
});

Change the url value to the URL of the Ghost site. For Ghost(Pro) customers, this is the Ghost URL ending in .ghost.io, and for people using the self-hosted version of Ghost, it’s the same URL used to view the admin panel.

Create a custom integration within Ghost Admin to generate a key and change the key value.

Ghost Admin new Integration view

For more detailed steps on setting up Integrations check out our documentation on the Content API.

The code

Once the API integration has been setup, content can be pulled from your Ghost site. To get all posts, use the api.posts.browse() endpoint:

// Store Ghost posts in a 'data' variable
const data = await api.posts
  .browse({
    limit: "all"
  })
  .catch(err => {
    console.error(err);
  });

This post data can then be used to create posts within Hexo. Creating posts can be done with the hexo.post.create() function. The instance of hexo is already globally available inside of Hexo script files.

data.forEach(post => {

  // Create a 'Hexo friendly' post object
  const postData = {
    title: post.title,
    slug: post.slug,
    path: post.slug,
    date: post.published_at,
    content: post.html
  };

  // Use post data to create a post
  hexo.post.create(postData, true);
});

Promise based API

The Ghost Content API is 'Promised based' meaning the JavaScript library will wait for all the content to be retrieved before it fully completes. Due to this the whole script needs to be wrapped in an async function. Here's a full example:

const ghostContentAPI = require("@tryghost/content-api");

const api = new ghostContentAPI({
  url: "https://demo.ghost.io",
  key: "22444f78447824223cefc48062",
  version: "v3"
});

const ghostPostData = async () => {
  const data = await api.posts
    .browse({
      limit: "all"
    })
    .catch(err => {
      console.error(err);
    });

  data.forEach(post => {
    const postData = {
      title: post.title,
      slug: post.slug,
      path: post.slug,
      date: post.published_at,
      content: post.html
    }

    hexo.post.create(postData, true);
  });
};

ghostPostData();

For the changes to take affect the Hexo site needs to be restarted using hexo server in the command line and navigate to http://localhost:4000/ in a web browser.

Next steps

The example code above is the most straightforward approach to using Ghost with Hexo. To use other content such as pages, authors and site data check out the JavaScript Content API documentation. As well as our documentation there's the official Hexo documentation which explains other ways Hexo can accept data.