I am gradually leaving the undemanding CMS GetSimple and switching to the static web generator Hugo. Why am I doing it? The more websites I have the more time I need to do a check of safety updates of the systems I work with. And I am glad to save myself the trouble sometimes.
Hugo conveniently generates static HTMLs for me and offers a certain level of comfort for content creating at the same time. The fact that I work on a web without a CMS doesn’t necessarily mean I jam everything in there in the HTML coding. Hugo works with files in markdown and they are easy to edit in various text editors, including the syntax highlighting.
The last time I got down to work on a simple web on the Croatian resort Njivice. And because last year before Christmas the utility-first CSS framework Tailwind caught my attention, I decided to rebuild the web using it. Then I added page transitioning with Swup. It’s a transition library that causes only the changing parts of pages to load and that improves the final impression of a web speed.
CSS framework Tailwind – my first impressions
The very beginnings of my work with Tailwind were a roller-coaster. From the euphoria of feeling like I have always searched for exactly this to reading several defaming articles saying that it is only good for few things. A big disappointment was finding out that I don’t have to write my own stylesheet but the one from Tailwind has the size of over two megabytes.
Everything fell into place in the end, I realized I have to study more information. I was getting to know the framework more and I found the purge function that will toss all the unused definitions while completing a web for production and prepare a really tiny resulting stylesheet.
I’m not that type of a person who devours theory and is immediately ready to write his own code. I like to study finished components, step by step edit them and then look at the results of particular changes. To spice up the process of getting to know Tailwind I bought Shuffle.dev service with which you can click together whole pages from various components, generate their code and then further edit it. It can also work with Bootstrap or Bulma framework.
Tailwind has several expansions. I have used two of them:
- Tailwind Typography, that deals with spaces, distances and other text stuff. Nobody wants to write classes to every paragraph all the time, that is also unrealistic.
- Tailwind Aspect Ratio – a great gadget that with two added classes ensures the right responding of inserted iframes, for example from a YouTube video. It can maintain the demanded side ratio.
I am curious how convenient will it be to work with Tailwind when I will start to code based on a particular graphic design. All this was an étude so far, I didn’t have to figure out how to actually do something. I just took a component in the aforementioned builder. But I think it is going to go well.
I write all the coding in PhpStorm that communicates well with Tailwind and offers classes completing.
If you were to examine that web code, please be benevolent. Experienced tailwinders would probably scold me that repeating the same classes several times with more than one component is a nonsense and I should use the directive @apply. I’m still learning but I needed to launch the web in a certain phase.
Hugo + Tailwind
I have already introduced the static web generator Hugo on Maxiorel in my article XXXXXXX . When I wanted to get down on Njivica website with it I had no idea that connection to Tailwind will be so simple. Well, when you want something more than connecting one CSS to an HTML.
Hugo actually can launch the purge process in Tailwind while generating a web, apply PostCSS and create a tiny resulting file. In the Tailwind configuration you can also easily set up where you can find HTML templates from which it will pick out used CSS classes before the purge.
The article Install Tailwind on Hugo helped me. You start with preparing a simple template for Hugo, creating HTML files with the template and then using npm and two commands install Tailwind to the project.
npm init
npm install tailwindcss@latest postcss-cli@latest autoprefixer@latest --save
Then you initialize Tailwind using:
npx tailwindcss init -p
A configuration file of a framework will be created and you will add following into it in the purge section:
purge: { content: ["./layouts/**/*.html", "./content/**/*.md", "./content/**/*.html"], "./themes/YOURTHEME/**/*.html" }
To the file assets/css/main.css you will add three lines and you are done:
@tailwind base;
@tailwind components;
@tailwind utilities;
As soon as you launch a local server with Hugo, Tailwind should start to work. After the production all you need to do is to edit a variable in node and start a web generating in this form:
NODE_ENV=production hugo --minify -b https://www.domain.tld/ -D
The simplicity of the implementation really surprised me.
Tips for Hugo
I don’t intend to create a manual for Hugo in this post but I have come across a few things that have slowed me down a bit. If I knew before, the project would flow much smoother. Maybe these tips will be useful for you, too.
I didn’t like that with the default shortcode for the figure tag Hugo uses in the tag figcaption h4 for an image description. I didn’t want to deal with my own new template but only with this little edit. Good news is that default templates for built-in shorcodes you can find here on GitHub. It is enough to download the selected file to a visual theme and the folder layouts/shortcodes and edit there.
Transition library described below needs a complete URL in links which ensures adding of settings to config.toml:
canonifyURLs = true
If you want to use shortcodes in a text, don’t forget to also add the following line into the configuration Hugo file:
enableInlineShortcodes = true
How to get rid of tags and categories? Hugo normally expects them to be there and generates links to pages with a list of terms even in case you don’t actually use them on the web. It will mess up sitemap.xml then. Suppressing means to add the following line into the configuration:
disableKinds = ["taxonomy", "taxonomyTerm"]
Swup
I noticed the transition library Swup on Symfony World Online 2020 conference for the first time. What interested me were the examples of its implementation when connected to Symfony UX. And because it is just JavaScript I wanted to try it out on a smaller project before I incorporate it into something bigger.
First impressions? It is nice but the documentation is confusing for a beginner. When combining it with Tailwind I came across a problem when after clicking on a link data loading from another subpage went well but it didn’t display. Because Swup collides with Tailwind prefixes and it was necessary to edit the Swup configuration a little:
const swup = new Swup({
animationSelector: '[class*="swup-transition-"]',
plugins: [new SwupSlideTheme(), new SwupGaPlugin(), new SwupScrollPlugin()],
containers: ["#swup", "#header-text"],
});
So for animation I set instead of transition-* selector a new one, named swup-transition-*.
On the web you can notice that the content part and the heading text are changing while the background of the heading stays the same. The two container definition in Swup is a piece of cake. I also used the event processing contentReplace in order to connect a click-through in the image gallery correctly.
I have expanded the base with these three plug-ins:
- SwupSlideTheme creates a nice effect of arrival of the edited content
- SwupGaPlugin ensures the right counting of PageViews in Google Analytics
- SwupScrollPlugin I have set up for going to the beginning of a text after a page change from the lower menu
If you plan to have an anchors for the page scrolling, enter them also with the full address with a hashtag in the end. Otherwise such links after a page change with Swup won’t work.
Tips for speeding up a web
I set up the (from my point of view) finished web and tried to run it through the online version of Lighthouse on web.dev. What a disappointment when I saw red numbers with a pure HTML! Of course, the problem was on the Google’s end, as usual. It really likes to assess another people’s websites and sees its own codes as the biggest problem.
In my case there were about 50 points deducted for a YouTube video. A simple inserted iframe with lazyloading. It allegedly loads a needless amount of JavaScript. Well, that’s true, but what to do about it?
I used a nice tip from aryaziai who is a developer and describes that tip in the post Improve Speed with Lazy-Loaded Youtube Videos (+Autoplay) . You basically use an edited iframe (instead of the common one), changed as following: there will be the srcdoc attribute in it, including the link to the embedded video and a “play” icon. Into the background there will be loaded only a video thumbnail. Until a user will click on the “play” icon there won’t be any YouTube scripts downloaded and Google itself won’t be frowning on slow loading.
I will start to use this process also on other webs. In case of Hugo, where I insert a video into markdown using shortcode this meant to download the default template from GitHub again and edit it according to the mentioned manual.
Also in Lighthouse there was a problem with H4 in figcaption and the repair I have already described above. Because I have a page template generated by a builder, I also came across an obstacle - loading of a font from somebody else’s domain. I have replaced it with Google Fonts and the link for the font loading I have placed into the web foot where it can be eventually transposed by JavaScript when the page will be downloaded.
The final assessment is almost OK. In only remains to resolve WebP instead of JPEG photos and I will be in green numbers completely. At this moment this is more than enough of trying out the combination of these three “technologies” for me.