Integrate Netlify-CMS with Hexo
Table of Contents
Why Content Management System is needed for writing blogs?
People create blogs and start writing posts frequently in the beginning and stops it gradually to zero. I would say there are 3 types of people who write blogs.
- Who sees the platform as fresh, creates a blog starts writing a post or two then forget
- Who setup a blog, spending more time on tweaking the layout of the site than actually writing
- Who doesn’t create a blog, opt the ready-made one available in the market such as Medium
The people who setup static websites falls in the first two categories.
I feel there should be a medium to write something like a paper, notebook, diary to convert a thought that flash in our mind to a blog post. When thegap
increases in converting a thought into writing, probably it will never be written. The medium is the main obstacle that reduces the frequency of blog posts and makes to zero at the end.
I started writing in this blog in a text editor, push it to git. The main obstacle is that, I have to write it only on my personal computer, where git installed. When I don’t have a computer with git installed, thegap
increases. I want to get rid of this.
Found Netlify-CMS as the better alternate to write blog posts, preview then publish.
I would wanted to write my experience in setting up Netlify-CMS for this blog.
Create Hexo Blog and Deploy with Netlify #
There is an article written in Netlify’s website, that explains how to create a blog using Hexo and deploy with Netlify. Refer this link if you are going to setup a new blog using Hexo or going to use Netlify as CI for building your blog.
Enable Netlify-CMS #
The following steps to be enabled for enabling Netlify-CMS.
- Update
<head>
and<body>
tags - Enable Netlify Identity Services
- Enable Git Gateway
- Configure CMS admin panel
- Build Site without Bugs
- Cloudinary as CDN for media
Update<head>
and<body>
tags #
There would be few lines of codes to be added in<head>
and<body>
sections, in order to enable Identity services.
There are multiple ways to do it, I prefer the easiest way by updating it in the netlify settings. Go to https://app.netlify.com/ select yourproject name
>Site Settings
>Build & Deploy
>Post processing
>Snippet injection
>Add Snippet
, then add the following codes in Head and Body sections.
Head Section<head>
#
<script src="https://identity.netlify.com/v1/netlify-identity-widget.js"></script>
Body Section<body>
#
<script>
if (window.netlifyIdentity) {
window.netlifyIdentity.on("init", user => {
if (!user) {
window.netlifyIdentity.on("login", () => {
document.location.href = "/admin/";
});
}
});
}
</script>
The outcome should look like this.
Enable Netlify Identity #
Netlify Identity Services to be enabled for adding users and to enable authentication to them. Go toSettings
>Identity
>Enable Identity
You may add Github / GitLab / BitBucket / Google as external providers, if you or your users want to login any of these services for writing posts.
Enable Git Gateway #
Git Gateway connects the site to the git provider’s API. This should be enabled in theIdentity
>Services
section.
Modify the Site Contents #
There would be small changes required in the site contents, which would help to setup the Front-matter.
Configure CMS Admin Panel #
Create a folder calledadmin
under the source folder and add the following two files in it.
index.html #
This file is used for displaying the content management system. Copy the following code and put it inindex.html
file, without making any changes.
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Content Manager</title>
</head>
<body>
<!-- Include the script that builds the page and powers Netlify CMS -->
<script src="https://unpkg.com/netlify-cms@^2.0.0/dist/netlify-cms.js"></script>
</body>
</html>
config.yml #
This file is used to configure the Front-matter of the blog posts. There are few modifications needed on the code, based on your requirement.
backend:
name: git-gateway
branch: source # Branch to update (optional; defaults to master)
publish_mode: editorial_workflow
media_folder: "source/images" # Media files will be stored in the repo under static/images/uploads
public_folder: "/images" # The src attribute for uploaded media will begin with /images/uploads
collections:
- name: "posts" # Used in routes, e.g., /admin/collections/blog
label: "Post" # Used in the UI
folder: "source/_posts" # The path to the folder where the documents are stored
create: true # Allow users to create new documents in this collection
slug: "{{slug}}" # Filename template, e.g., YYYY-MM-DD-title.md
fields: # The fields for each document, usually in front matter
- {label: "Title", name: "title", widget: "string"}
- {label: "Publish Date", name: "date", required: true, widget: "datetime"}
- {label: "Edited Date", name: "updated", required: true, widget: "datetime"}
- {label: "Categories", name: "category", required: true, widget: "list"}
- {label: "Tags", name: "tags", required: false, widget: "list"}
- {label: "Keywords", name: "keywords", required: false, widget: "list"}
- {label: "Body", name: "body", widget: "markdown"}
- {label: "Display Comments", name: "comments", required: false, widget: "boolean", default: true}
I have tried explaining each part of the above code, which may helpful.
Parameter | Description |
---|---|
name | Keep it default asgit-gateway unless you want to enable different authentication backends |
branch | Update thebranch name where the site contents / source code is saved. |
publish_mode: editorial_workflow | Refer this link for detailed explanation. Editorial Workflow works only for GitHub as of now. Comment or delete this line if you are using other hosts such as GitLab or BitBucket. |
media_folder | This is where the images are stored in the source of the site. The default folder for hexo is located atsource/images |
public_folder | This is where the images are available after building the site. The default folder for hexo is located at/images |
collections | Collections are explained very well here. You can keep the source code without any changes, which works well for almost all the hexo themes. You may add additional collections based on the requirement. |
Netlify CMS is following different way in creating a draft post and preview it usingeditorial_workflow
than Hexo is designed for drafting a post. It creates a pull request from the existing repo for each blog post. It builds the site immediately and available for preview in a unique URL. Once the post is madeReady
andPublished
, Netlify-CMS closes the pull request by merging the changes to the branch where the source is saved and deleting the branch made by pull request.
Building Sites #
You might have usedhexo g
orhexo generate
command to build the site. Though, the CMS wouldn’t load. Refer the following portion that fixes a bug.
Fixing Bug in rendering CMS Admin #
I had an issue after making all the above configurations and I was unable to access the CMS page by visiting /admin page. Found that, thesource/admin/config.yml
is renamed aspublic/admin/config.json
with some modification after building the site. This can be fixed by adding admin folder contents in theskip_render
option of hexoconfig.yml
file.
skip_render: admin/*
Configure netlify.toml for Building Sites #
You can add build commands in the Site settings of Netlify page. However, you may configure additional steps by creatingnetlify.toml
file in the root of the site folder.
[build]
publish = "public/"
command = "hexo clean && hexo g"
environment = {NODE_ENV = "8.10.0"}
This file would override the settings, that you mention in the netlify setting page.
Use Cloudinary as Media Folder #
Hosting images in the git repo is a bad idea, as the repo size would gradually increase when new posts are added with new images. Also GitHub started providing free private repositories, you might want the source of your site contents to be hidden from others. So, I would suggest using https://cloudinary.com for hosting the site images.
You need to create a free account from cloudinary and get the required details from the dashboard page. Then configure thesource/admin/config.yml
file as like below; refer lines between 7 and 13.
Documentation on configuring netlify with clouodinary is available here, if you wish to tweak further.
backend:
name: git-gateway
branch: source # Branch to update (optional; defaults to master)
publish_mode: editorial_workflow
media_library:
name: cloudinary
output_filename_only: false #false = bring the file name with entire path true = bring file name only
config:
cloud_name: # your cloudinary name available in the dashboard
api_key: # api key that you get from cloudinary dashboard
username: # the user id, which is used to create the cloudinary account
collections:
- name: "posts" # Used in routes, e.g., /admin/collections/blog
label: "Post" # Used in the UI
folder: "source/_posts" # The path to the folder where the documents are stored
create: true # Allow users to create new documents in this collection
slug: "{{slug}}" # Filename template, e.g., YYYY-MM-DD-title.md
fields: # The fields for each document, usually in front matter
- {label: "Title", name: "title", widget: "string"}
- {label: "Publish Date", name: "date", required: true, widget: "datetime"}
- {label: "Edited Date", name: "updated", required: true, widget: "datetime"}
- {label: "Categories", name: "category", required: true, widget: "list"}
- {label: "Tags", name: "tags", required: false, widget: "list"}
- {label: "Keywords", name: "keywords", required: false, widget: "list"}
- {label: "Body", name: "body", widget: "markdown"}
- {label: "Display Comments", name: "comments", required: false, widget: "boolean", default: true}
Conclusion #
- Having a proper CMS setup would help to make the writing easy and spontaneous.
- Need not to depend on the personal computer with
git
andhexo
configured to push the commits or previewing the changes. - It helps to focus more on writing than tweaking the existing layouts.
Next Steps #
- I might need to explore the options to create custom widgets to include Tag Plugins for Hexo and Tag Plugins for Next
- I might need to find a way to tweak the preview of markdown in the CMS portal, which is not in sync with the site.