top | item 17387103

Migrating from Jekyll to Hugo

134 points| dguo | 7 years ago |dannyguo.com | reply

91 comments

order
[+] slathrop|7 years ago|reply
I recently completed a pretty fun little website[1] for the U.S. freight rail industry using Hugo, Vue.js, Nuxt, Vuetify, Chart.js and Netlify. It is open source on GitHub[2].

It will soon replace an aging version of the site[3] that was built with Sitecore CMS, .NET, and SQL Server.

At first I considered using Hugo to generate the HTML for the site from git-backed JSON/YAML/TOML files. But the quantity and complexity of the Golang templates was clearly going to be tedious, inflexible, and tough to maintain.

So I settled on using Hugo to generate a read-only REST API instead[4], based on a nice blog post I had read[5][6].

This freed me to use any front-end framework I wished, and I chose Vue, Vuetify, and Axios for their simplicity and productivity on this solo-developer project.

In the end I was quite happy with this combination. Hugo was incredibly fast and productive for ranging over and manipulating all of the JSON/YAML/TOML data files to produce the final read-only REST API JSON... after the initial learning curve with Golang templates.

And the front-end really just boiled down to some key Lodash transformations of the JSON into the various shapes of data that were needed for tabular reports and Chart.js graphs.

[1] https://app.rrpm.run/ [2] https://github.com/railroadpm/site [3] http://www.railroadpm.org/ [4] https://api.rrpm.run/reports/bnsf/all [5] https://discourse.gohugo.io/t/build-a-json-api-with-hugos-cu... [6] https://forestry.io/blog/build-a-json-api-with-hugo/

[+] Avshalom|7 years ago|reply
Pretty sure you have conflated the abilities of the half dozen frontend frameworks you added (for simplicity) with the the backend you replaced. ".Net" (not actually a specific backend) and an rdbms are not in any significant way a friction against a REST api.

Mean while the only noticable difference between the sites is the front end.

[+] phawksworth|7 years ago|reply
Thanks for sharing this. Fascinating!

I'm a big fan of serving content APIs as static assets like you are doing here. Especially good for content which changes infrequently (a few times a day rather than many times a minute).

Static site generators typically make it simple to publish a structured data view like a JSON or XML feed of content alongside content pages as HTML (such a bonus!), but it is interesting to see that you've separated the API generation entirely as a Hugo build. (presumably for compile speed?)

I work at Netlify and am something of a JAMstack enthusiast. I'd love to learn more about the experience of designing and building this. If you'd be interested in doing more of a write up, or just sharing any of the learnings from along the way, I'd love to chat.

(https://twitter.com/philhawksworth)

[+] Waterluvian|7 years ago|reply
What are lodash transformations?
[+] jaas|7 years ago|reply
We switched the Let's Encrypt website from Jekyll to Hugo. We did it primarily for i18n support (Jekyll does not support translation), but it would have been worth it just to avoid Jekyll's ruby dependency nightmare. Hugo is a single static binary, so simple.
[+] the_mitsuhiko|7 years ago|reply
I built the actix.rs website with hugo and while I generally like it it has some bizarre things that make development harder than necessary. Sometimes it randomly refuses to build pages that worked before, until you realize it has something to do with it now picking up other templates. But no error message.

And that you can't shell out to helper scripts makes it very restricted in so many aspects. I wanted to extract source examples from other code and preprocess it and the only way I could make it work was some really ugly go template code and that didn't even let me implement everything I want since they are so restrictive :(

I really wish one could shell out to an executable to fill the gaps.

As an example this is how code snippets are included. Sadly we cannot remove leading spaces on the lines to remove extra indentation, so now the source files look ugly :( https://github.com/actix/actix-website/blob/master/layouts/s...

[+] andy800|7 years ago|reply
Thank you! The LE site is terrific (as is LE itself). Because it is open-source, I essentially cloned it for a professional association. https://casinoanalytics.org Credit to LE is on the FAQ page. Thanks again.
[+] edem|7 years ago|reply
And it is full of implicit stuff, cryptic templates, and the whole thing is pretty unintuitive. You also cant write plugins for it. Jekyll has i18n support I dont know what you are talking about.
[+] nickjj|7 years ago|reply
I don't see myself moving from Jekyll for a long time.

And it's mainly because of Jekyll-Assets. It's just too useful for not only bundling assets but effortlessly md5 tagging everything for caching on the nginx side of things.

Hugo and others have nothing like this, and rolling your own set up isn't feasible for that because for it to be done right, it needs to be supported at the generator / plugin level so your template helpers know how to deal with looking things up from the untagged file name.

My site has about 170 blog posts and dozens of other pages and Jekyll's incremental reloader refreshes in a little over 2 seconds. That's about 1 second longer than I'd like to see a blog post get live reloaded in development, but it's good enough.

[+] biggestlou|7 years ago|reply
An asset pipeline (and templatized at that) is being added to Hugo as we speak. Just Sass support to begin with but more later. Once that’s added the reasons to use Jekyll, which is essentially abandonware, will shrink to zero.
[+] benatkin|7 years ago|reply
Having few assets is better than having a fancy asset pipeline. https://www.gatsbyjs.org/ supports code splitting and since it uses JavaScript, CSS generation libraries like styled-components, Glamourous, and JSS are available. That means only outputting the CSS and JS that are needed for the page. This is great for blogs where someone might only read one article. The Hugo community is working toward minimal assets too.
[+] kaushalmodi|7 years ago|reply
> rolling your own set up isn't feasible for that because for it to be done right

I do cache-busting > hugo > minification using a simple bash wrapper script. Though, in the coming week, Hugo might natively start supporting the cache busting and minification.

[+] woodruffw|7 years ago|reply
FWIW, I achieved something like live reloading in Jekyll using an additional config file.

_config_local.yml:

    html_refresh: true
    html_refresh_rate: 5
Then, I appended the config via:

    jekyll serve --config _config.yml,_config_local.yml --force-polling
And then did a check in my header include:

    {% if site.html_refresh %}
      <meta http-equiv="refresh" content="{{ site.html_refresh_rate }}">
    {% endif %}
You can find a working example in my blog's repo[1].

[1]: https://github.com/woodruffw/blog

[+] smoser|7 years ago|reply
I like the speed and flexibility of Hugo. It doesn't force you into the blog format like Jekyll does. Jekyll has collections but collections don't have all the features of posts. I keep coming back to Jekyll because of the relative link support that works across VS Code, Github, and Jekyll. Hugo added support then removed it.

https://github.com/gohugoio/hugo/issues/1921

[+] therealmarv|7 years ago|reply
I'm in the process of creating a new blog and site (I have python, vue, nuxt background) which maybe will have more non technical authors and dynamic content in the future and after many iterations (looking deeply at Hugo, Lektor, Forestry and even Wordpress [headless]) I will probably go to a

open source headless CMS Strapi https://strapi.io and Nuxt.js frontend.

If anybody knows a python and flask based headless CMS let me know!

[+] joeblau|7 years ago|reply
I have an interesting Jekyll performance story. I was trying to build a website [1] that was going to be the new destination for git information. The site is a static site and I figured that since Jekyll was integrated into GitHub, it would be simple. My script downloaded all of the git documentation from the linux kernel website, did some parsing of the HTML files adding front matter, and then tried to generate the site.

My Jekyll(Ruby) script was running over a day and never finished. Hugo(Go) ran in about 5 minutes. Granted there are over 10,000 pages being generated by Jekyll but it was so painfully slow, I couldn't possibly have a daily CI system that generated the site.

I'm still fixing some https issues with GitHub static site hosting, but it should be working soon.

[1] - https://github.com/dvcs/gitdvcs.com

[+] inputcoffee|7 years ago|reply
Speaking as a newbie (python and R mostly) who just wants the blogging software to blog, I use Jekyll because it’s the default choice. Yes there are python options but I don’t want to program the software - my programming energy is already spoken for.

I don’t care about the speed differential.

However if Hugo is actually easier somehow, well that would be tempting.

[+] hnarayanan|7 years ago|reply
It is significantly easier to setup because (in typical Go style) only requires you to download and install a single fat binary. You do not need to do what you're otherwise doing with the likes of Jekyll which involve a significant Ruby environment alongside to function.

I've been using it for over two years, and this is the thing I like most about it.

In addition:

* Yes, it's super fast.

* It allows for clean layout of code with different layouts for different sections: e.g. https://github.com/hnarayanan/harishnarayanan.org

* It's got a really friendly community for support.

[+] nyolfen|7 years ago|reply
as someone with relatively rudimentary skills who tried and failed two or three times to get jekyll working on a throwaway vps, hugo is indeed very, very easy.
[+] mattlondon|7 years ago|reply
I really like Hugo and use it for one of my websites. It is refreshing to get such a fast website.

Where I find Hugo lacking though is I have found it very difficult to theme. Hugo has a very particular way of doing things with sections, sub-sections, leaf nodes and branch nodes, and a very particular folder structure where having an index.md file does one thing, but an _index.md file means something totally different. This would be fine if the docs were extensive and explained this clearly but they are very light in this area and most knowledge seems to be burried in individual disqus posts and other people's heads. I am sure it makes sense to people already familiar to Hugo, but trying to grok it all as a new-comer has been difficult.

As a result working out how to do even trivial things such as listings of pages in grandchild-directories, or even just having a list of child pages with other textual content has been a terrible struggle for me. Existing themes are invariably horrendously out of date, so trying to learn from those is also difficult. To this day on my site, if you go to specific directory paths there is literally a blank page because for the life of me I cannot work out how to make Hugo display just a simple list of posts in grandchild directories. It is infuriating! Perhaps it is my fault for wanting a semantic directory structure (e.g. domain.com/subject1/subject2/actualContentInHere/ and the pages for subject1/ and subject2/ are literally blank).

TL;Dr - good but if you want to do more than CSS tweaks on an existing theme then you're in for a challenge.

[+] jotaen|7 years ago|reply
I second this. I built my own template from scratch and even though my layout structure is quite simple it consumed a lot of time to find out how where to put files in order to make things happen. I agree that better documentation would have helped, but it would be also great if Hugo was more (explicitly) configurable instead of purely relying on conventions.

(Once setup though, I continue to enjoy Hugo – it’s fast and mostly stays out of one’s way.)

[+] eevilspock|7 years ago|reply
Matt and jotaen, email me if you want to try out some changes I've made to Hugo that make it simple and easy without losing any power.
[+] otterpro|7 years ago|reply
Few months ago, I migrated to Hugo after several years on Jekyll, and I'm so glad I did. While Hugo does have many flaws, I love it for its simplicity, which is also the reason why I chose static website generation over Wordpress or CMS.

I still like Jekyll and I might use it for blogs that has more complex requirements for building the site. However, my blog is simple and I just wanted to generate my site quickly (and boy is it quick). Also using the template was very easy, and I was able to migrate my Jekyll theme to Hugo without too much trouble.

[+] baxtr|7 years ago|reply
We’re running our blog on Jekyll. Is there any good reason to migrate to Hugo? In the article I’ve found this comment:

Hugo’s key differentiators: 1. Ease of install 2. Speed (critical for large sites) 3. Integrated live-reload while editing in near realtime 4. Multilingual capabilities 5. Flexible 6. Very strong community 7. Very good & comprehensive documentation (but not perfect…yet)

Other than 3., all other points are valid for Jekyll as well. So why move, other than for the sake of just migrating (which can be fun too...)?

[+] Sir_Cmpwn|7 years ago|reply
I'm not sure you understand. That quote is not listing Hugo's limitations, but rather it's strengths compared to Jekyll.
[+] cryptos|7 years ago|reply
Hugo is a fantastic tool and I would choose it again. However there is a little annoying bug for years: If you let Hugo create a table of contents it adds an unnecessary level of nesting, if the highest level of content headings is h2. This is pretty common if you use h1 for the page title (that shouldn't be repeated in the table of contents).

But besides that Hugo is a feature rich, fast and easy to install tool.

[+] otterpro|7 years ago|reply
I don't know if this is the same issue, but there is a workaround in https://github.com/gohugoio/hugo/issues/1778. The TOC had been driving me crazy, and I had just learned to live with it for now, but I think the workaround can address some of the issue.
[+] pknopf|7 years ago|reply
I've used pretty much every product out there for static site generation, and I gave up.

So I created [0] Statik.

I dont mind manually building out the mardown/razor/etc. In the end, I get exactly what I want, with no overhead or heavy abstractions weghing me down.

[0] https://github.com/pauldotknopf/statik

[+] declnz|7 years ago|reply
I'm surprised nobody mentioned Hakyll [1] here - a great Jekyll alternative that's fast(ish) and supports hot-reloading. You do have to like / tolerate Haskell though (this polarises opinion pretty fast...)

[1] https://jaspervdj.be/hakyll/

[+] rammy1234|7 years ago|reply
I agree to most of your points. I too recently moved from jekyll to Hugo and I know I did not make a bad choice. It is awesome and making me to write more. Hosted on github pages. https://www.rammy.in
[+] dguo|7 years ago|reply
Hey, just giving you a heads up that the www version of your site gives me an SSL error. https://rammy.in works though.
[+] sytse|7 years ago|reply
If you want to use Hugo integrated with source control please know that our GitLab pages had support for our and 25 other static site generators.
[+] sandGorgon|7 years ago|reply
The momentum around static site builders is around the react based builders like Gatsby.

Since you are going to spend a huge amount of time writing js code for the front-end anyways, it makes sense for the whole stack to be js.

We moved from Hugo to Gatsby for primarily this reason. I can now handover the site to js folk ...instead of having them learn golang based templates.

[+] akerl_|7 years ago|reply
Why would I spend a huge amount of time writing JS for the front-end?
[+] slathrop|7 years ago|reply
I ended up with a hybrid approach where Hugo and Golang templates are only for building the data (TOML files) into the required JSON for a read-only REST API. The remainder of the solution is all JavaScript (in my case Vue and Nuxt instead of React and Next).

I came very close to switching to Gatsby early on, and I am very curious to know how my project[1] would have gone with Gatsby instead of Hugo.

I get the impression that for the data manipulation (avoiding complex Golang templates that generate HTML) and for build speed, Hugo takes it. Certainly if you are working in React the simplicity of a single framework is the way to go, as you did.

I also kind of felt a little more weird about mixing Gatsby and React with my preferred front-end framework, Vue, than I did about having to combine Golang template logic in one layer (API) with JavaScript in another layer (App).

[1] https://github.com/railroadpm/site

[+] bobwaycott|7 years ago|reply
> Since you are going to spend a huge amount of time writing js code for the front-end anyways...

My general goal in using an SSG is to have a static site. HTML and CSS. Maybe some images, of course. But I typically don’t reach for an SSG if I’m building something that requires a huge amount of time writing JS code. The goal is to have zero JS and zero backend. I know others may not care to create the smallest, fastest pages they can, but if I need a bunch of JS, that strikes me as the opposite of a static site.

[+] gschier|7 years ago|reply
I went this way too. If your site has a dynamic/interactive frontend, Gatsby makes it super easy to build a static-but-interactive site. Another huge plus with Gatsby is that it uses React's server-side-rendering to ensure that the site is still seo-friendly.

If you have more than a few snippets of JS on your site, Hugo comes up way short. It's great for simple things though.

[+] RobertRoberts|7 years ago|reply
Aaaaaand this is why I don't jump on the latest frameworks anymore... I can almost hold my breath long enough for a framework to go out of style.

The first time I read about Jekyll was here, and now already something better has come along, my brain just gave me that tiny little mental high-five on my decision to no longer live on the bleeding edge