Contents

Build my own website by oxhugo+loveit+netlify

I am constantly searching for a simple way to maintain and update my personal website. Here is what I would like to achieve:

  • Updating the website without having to leave Emacs
  • Writing all content in org mode
  • Managing versions of my source code
  • Creating a static website with no database or dynamic content generation
  • Enabling full-text search
  • Allowing comments
  • Including LaTeX equations, charts/figures, and multimedia through plain text, which automatically renders on my website
  • Designing a beautiful website

Essentially, all I need to do to maintain my website is write some text and save it. All other updating tasks should be automatically processed by a machine.

Some may believe this workflow impossible to achieve, but I have discovered some Emacs tools that fulfill most of the above functions. While none are flawless, they are still impressive and only require one more step to reach perfection.

Finally, I have found the solution. I can use hugo, oxhugo, and netlify. If you are reading this blog on my website, then you know how well this solution works.

Below, I summarize my setup for this workflow. There are numerous steps, and I do not describe them all in detail. However, if you have a basic understanding of Emacs, org-mode, and web applications, I believe this tutorial could be helpful. So let's get started.

Step 1: install hugo

Hugo is known as

The world’s fastest framework for building websites – Hogo official website

For those who may not be familiar with Hugo, please check out its official website for more details. In Debian, you can easily install Hugo by

sudo aptitude install hugo

To get started using Hugo, follow the steps outlined in its documentation

$> hugo new site quickstart # make new project
$> cd quickstart # go into project folder
$> git init # start git
$> git submodule add https://github.com/theNewDynamic/gohugo-theme-ananke themes/ananke # add a theme
$> echo "theme = 'ananke'" >> config.toml # set theme name in config
$> hugo server # start a local hugo develop site

There are many themes available for Hugo at https://themes.gohugo.io/, allowing you to customize your project even further. You can edit the config.toml file to configure Hugo, but for more detailed information, please refer to the Hugo documentation.

Step 2: setup ox-hugo

I assume that you are familiar with Emacs and org mode, or at least you use Emacs for your daily work. If you are not an Emacs user, then this article may not be for you. :-(

ox-hugo is an org exporter that exports org files to Hugo markdown files. To install ox-hugo, use package-install and add the following to your .emacs file:

(require 'ox-hugo)

Then you will be ready to go!

“Create a folder within your hugo project folder, such as ‘content-org’ or any name you prefer. There are two ways to write org files for Hugo: one post per file or one post per subtree. The latter is recommended by ox-hugo due to its flexible content exporting and use of inherited tags.

To facilitate exporting to Hugo, ox-hugo uses PROPERTIES in the org file to specify what and how to export to Hugo markdown files. Here are some examples:

:EXPORT_HUGO_SECTION: sectionname
:export_file_name: index
:export_date: 2023-04-04

I created Yasnippet snippets to simplify the process of writing these properties, but you can also create your own to make your life easier.

If you want to add shortcode for theme in ox-hugo, check ox-hugo's shortcode document.

For a detailed usage guide of Ox-Hugo, please refer to its official website.

Step 3: setup theme of hugo

Setting up a Hugo theme may be the most important step in creating a website. There are many themes available on Hugo's theme website, and you can select any theme you like. However, it's important to note that a configuration for a specific theme may not work well for another. Therefore, it's important to carefully choose a theme before publishing your website to avoid problems when transferring themes.

I choose LoveIt theme for my website, which I think it is simple and beautiful. I believe you can also find theme you like most. Most themes have very detailed configure document. The simplest way to make your own config file is to copy theme's example config file and modify it.

  • Shortcode To embed equations or multimedia in you website, shortcode is what you have to check. It is very easy to add chortcode in Loveit, check here for details

  • Search I believe that the most important function for a static website is the full-text search. Most themes can add a search function by using online search services such as Lunr or Algolia. In my opinion, Lunr is easier to use than Algolia because it can be used locally without uploading an index file to its website, on the other hand, one has to upload an index file to Algolia to keep the search index updated. However, the downside of Lunr is that it cannot search CJK characters well, which prevented me from using it on my website. Instead, I use Algolia for my search backend.

    Fortunately, as I will mention later, if you host your website on Netfily like I do, the Algolia plugin for Netfily will take care of uploading the index for you, making use Algolia as simple as Lunr.

    I will come back to this topic on how to configure Algolia in Hugo in the next section of Netlify.

Step 4: setup website hosting

The final step in building your website is to select a website hosting service. Since we are discussing building a website using Hugo, the chosen website hosting service should be Hugo-focused. Currently, I believe Netlify is one of the best website hosting services for a Hugo-based website.

Go to Netlify and sign up for an account. Once you've signed up, log in to your account and select a plan. For a simple personal webpage like mine, which doesn't involve large file transfers, I recommend choosing the free starter plan, as it should provide everything you need.

Under the personal account page, one can set up website hosting by clicking on “Add new site”. As the website source code is hosted on the Git server, the best way to add a new site to Netlify is by “Importing an existing project”. You can then choose the Git server where the source code is located. Follow Netlify's instructions and select the repository of the website's source code and other settings. After site settings, the next step is to link your domain to Netlify. This can be done easily by following Netlify's instructions. If you don't have your own domain, you can access your website through Netlify's subdomain with a URL like “accountname.netlify.app” where “accountname” is the site name of your web hosting on Netlify that was set during site setting. It's recommended to set up an SSL/TLS certificate for your website if your domain already has one.

To ensure that the domain is fully functional for web hosting, it is necessary to verify that the DNS settings have been updated on your domain management service with the NDS servers recommended by Netfily. Additionally, it is important to ensure that the ‘baseURL’ parameter in the ‘config.toml’ file of Hugo is correctly set to your domain address.

If you also host your domain's email on a domain service like Google Domain, you have to migrate the email DNS record to Netlify, or else your email system may crash. For a complete migration to Netlify, follow the steps outlined by this website and this website:

  • Access your Netlify account page's “Domain” setting and add a new DNS record.
  • Go to your current domain service website, such as Google Domain. In the DNS settings under “Google Workspace” and “Default name servers,” you will see DNS records like MX, SPF, and TXT.
  • Refer to the information above, return to your Netlify account, and add the new DNS records for MX, SPF, and TXT one by one.
  • After adding email DNS records, it's time to set the domain pointing to Netlify. In the DNS settings of Google Domain, activate “Custom name servers,” then add Netlify's name servers, found on the “Name server” list in the “Domain” setting on Netlify.
  • Add your domain as the primary domain in the “Domain” setting on Netlify.
  • Finished. The setting may take time to take effect, usually 10 minutes to a few hours, although Google claims it can take up to 48 hours to change.”

Step 5: add search fuction

Here comes the last configuration - to me, the most important function needed by my website: searching. As I mentioned in the last section, I use Algolia service for search. Regardless of the service you use, Lunr or Algolia, the basic steps to add a search function to Hugo are the same. Go to the service website, sign up for an account, log in to the service, retrieve your service's API information such as appID and API token, and configure the config.toml of Hugo to enable connection with the service via its web API.

Since I mentioned that using Algolia requires uploading an index file whenever the content to be indexed is updated, it is possible to create a script for automation to avoid having to do it manually. However, the best solution is to use Algolia's Netlify plugin, which automatically uploads the index file to Algolia as soon as the website on Netlify is updated.

Thus, adding a search function using Algolia involves the following steps:

  • Signing up for an Algolia account and logging in
  • Following the tutorial on how to add a crawler for Netlify on the Algolia website
  • Editing the config.toml file to add Algolia parameters The format of the configuration may depend on the Hugo theme being used. Refer to the theme's documentation to find out how to configure search parameters. In my case, I use LoveIt theme, the basic configuration may look like the following.
    [params.search]
      enable = true
      type = "algolia"
      contentLength = 4000
      placeholder = "search my website"
      maxResultLength = 10
      snippetLength = 30
      highlightTag = "em"
      absoluteURL = false
    [params.search.algolia]
      index = "indexname"
      appID = "ID"
      searchKey = "xxxxxxx"
      siteID = "xxxxx"
    

    Where “index” refers to the name of your Algolia indexing, which can be found on the “Crawler Netfily” application setting page on Algolia. “appID” is the ID of the “Crawler Netfily” application, “searchKey” is the “Search-Only API Key” for “Crawler Netfily”, and “siteID” is the “Site ID” of the Netfily web hosting. You can find the “Site ID” in the “Site Details” section of the site settings on Netfily.

Workflow

Great news! The website construction is now complete. Here's how you can post new content or add a new blog post to your website:

  1. Open the org file, which is the source for your website. Write your content along with the necessary properties for ox-hugo.
  2. Use the keybinding “C-e H” to export your content to a Hugo md file using the ox-hugo exporter of org mode.
  3. Commit the new content to git and push it to your hosting git repository.
  4. That's it! Your website will be updated in a few seconds, and Algolia will also update its index for you.

Tips

  • If the website is hosted on Netlify, you don't need to push the “public” folder to the Git server as Netlify will compile the md files and generate static HTML files for you. It's recommended to add ‘public’ to .gitignore. When using ‘hugo server’ to preview changes on your local machine, Hugo will generate HTML files under the ‘public’ folder. Ignoring it in Git is a good idea.
  • I didn't do this, but it's possible to add hook functions to make the process from ox-hugo exporting to Git commit and push fully automatic. This could simplify the workflow: edit the org file, save it, and you're done!
  • Using Yasnippet snippets can make adding properties to org files very simple.
  • Learn to use shortcodes in org files to make the website more beautiful and functional with multimedia. There are various methods to directly handle shortcodes in ox-hugo's org file. Consider the example given below:
    • Firstly, add a header to the org file:
      #+HUGO_PAIRED_SHORTCODES: admonition
      
    • Then, you can add the admonition shortcode in the org file as follows:
      #+begin_admonition :type tip :title: "Note:" :open open
        This is my tip.
      #+end_admonition
      
    • You can use the above steps to include other shortcodes. In the code above, “type”, “title,” and “open” are parameters of the admonition shortcode.
    • For more details, please refer to this website and this website.
  • Enabling comments on the website is easy using comments services like Disqus or Gtalk. Please check LoveIt's documentation for details.
  • To easily add a new post, you can configure an org template and add your website source org file to the re-file target. Then, you are able to start writing a post anywhere within Emacs. After writing, simply submit the template or refile it to the website source code. However, I haven't done this yet. :-)