Hugo, Tailwind, Svelte - luit.eu (2024)

Table of Contents
Overview pages Photo viewer

I'm paid to be back-end developer. I'm a lot better at that than at front-enddevelopment. Recently, I built a mostly front-end website – a photo album. Idid this using front-end technologies I knew and actually understand andmostly enjoy using. This post explains how and why I combined Hugo, Tailwindand Svelte to build the best front-end I've made so far.

This is a very quickly made write-up of this. If you have any questions, orwant to learn more about this, feel free to contact me, preferably on Twitterfor shorter things, e-mail for longer stuff (links at the bottom of the page).

The first part of this puzzle is the static site generator I've been a fan offor a while now. Back when I (re)made this site it was great, and it'scontinuously been improved since.

The site I was making is a photo album, and ImageProcessing was afeature I'd seen added to Hugo but hadn't used yet. It turned out to be one ofthe simpler parts of building the site.

Overview pages

I gave the site a home page, and four page bundles for the four categories ofphoto's I had. The index.md of the bundles at first didn't contain anythingother than the layout = "album"

{{ define "main" -}}<div class="flex flex-wrap justify-center min-w-full"> {{- range .Resources.ByType "image" }} <img sizes="(min-width: 1264px) 400px, (min-width: 964px) 300px, 200px" srcset='{{ (.Fill "400x400 Center q90").RelPermalink }} 400w, {{ (.Fill "300x300 Center q90").RelPermalink }} 300w, {{ (.Fill "200x200 Center q90").RelPermalink }} 200w'> {{- end }}</div>{{ end }}

With the srcset and sizes, I make sure at least 3 thumbnails showside-by-side, and they scale from 200 to 300 and finally 400 pixels square.Note: this configuration apparently isn't the prettiest on displays with highpixel density, because I didn't have a display to test that on. I'll probablyadd a few more sizes for 1.5x and 2x scaling.

Photo viewer

Next I needed to get Hugo to produce a few more sizes of the images to feedthese to the viewer application I wanted to make. So I added a JSON OutputFormat for the album pages, inwhich I built a mapping of files to formats. The JSON would have the followingshape:

{ "#images/001.jpg": { "600x400": "path/to/resized/001_600x400.jpg", "960x640": "path/to/resized/001_960x640.jpg", "1200x800": "path/to/resized/001_1200x800.jpg", // more sizes }, "#images/002.jpg": { // sizes }, // ... many more images}

Generating these links is done by Hugo's image pipelines as well, with asimple {{ (.Fit "1200x800 q95").RelPermalink }} for each resolution.

To be able to open the viewer, I added links to a hash identifier that matchedthe identifiers in the JSON.

{{ define "main" -}}<div class="flex flex-wrap justify-center min-w-full"> {{- range .Resources.ByType "image" }} <a class="block px-2 py-2" href='#{{ .Name | safeURL }}'> <img sizes="(min-width: 1264px) 400px, (min-width: 964px) 300px, 200px" srcset='{{ (.Fill "400x400 Center q90").RelPermalink }} 400w, {{ (.Fill "300x300 Center q90").RelPermalink }} 300w, {{ (.Fill "200x200 Center q90").RelPermalink }} 200w'> </a> {{- end }}</div>{{ end }}

And finally, added the script and CSS of my viewer built using Svelte:

{{ with .OutputFormats.Get "json" -}}<link rel='stylesheet' href='{{ (resources.Get "photo-viewer/bundle.css").RelPermalink }}'><script defer src='{{ (resources.Get "photo-viewer/bundle.js").RelPermalink }}' data-photo-viewer='{{ .RelPermalink }}'></script>{{ end -}}

With this, I can use the script[data-photo-viewer] selector to find the URLfor my photo viewer data.

Before I go on about the viewer, first let's look at Tailwind.

Layout is an art in and of itself, and one I don't do well in. Tailwind hashelped me through this by simplifying it a lot for me. Additionally, I wasn'tthe first to use Tailwind combined with Hugo, so I could copy from myneighbors and get a passing grade without much studying.

To combine the two, I used Hugo'sPipes, and more specifically:Hugo's PostCSS processing capability.My root folder contains a package.json with postcss-cli and tailwindcssdependencies, a simple postcss.config.js and a tailwind.config.js. Thatwas all I needed to be able to process assets/main.css into the stylesheetthe site uses. To reduce the size of the stylesheet, I added PurgeCSS too.

On to the hardest part: JavaScript!

I've always had trouble working with JavaScript, but no single thing hassimplified it as much for me as Svelte has. It's not made it easy, but atleast I can now manage to build something useful out of it.

The goal was, relatively, simple: intercept some links in a document to open aphoto viewer instead of the link, and display an image with some invisibleoverlays to click on to navigate to the next or previous images, and somekeybindings for that same purpose.

For that I made two components: <Viewer> to manage the data andinteractions, and <Image> to display the right sized image. Thanks to thesrcset and sizes attributes, the latter is really quite simple. With a fewArray.map invocations the input data is manipulated into what in the endis beautifully just <img {alt} {sizes} {srcset} />.

Still, even though <Viewer> is the more complex one, it's still far fromcomplicated. I had more trouble with the styles than with any of the script.

The code can be foundherein its own repository, because there's no clean integration in Hugo forsomething that can compile and bundle a Svelte app for you. This brings us tothe final section of this post.

This is the part I'd love to see some improvements. To use the Svelte-basedphoto viewer in my Hugo-based site, I made some decisions I wish I didn't haveto make.

  1. I could have built everything in one repository, but that would mean addingmore tooling around Hugo which would have to run in parallel with hugo serve for development, and in order when building the site for publishing.Because of this, I also had to commit the generated bundle.js andbundle.css instead of only the sources, otherwise I would have still neededthe tooling for Svelte in the Hugo repository.

  2. With the relatively new Hugo Modules Icould add the photo viewer without having to struggle with git submodules,so I quickly decided to use that. Sadly, when I got to deploy the site toZEIT the modules wouldn't work in absence of a Gotoolchain. This was quickly fixed by vendoring the modules, but I'd prefernot to have to do that.

  3. Having both Hugo and Svelte use Tailwind was too much of a challenge forme, so I used Tailwind just for the Hugo part. The CSS in de Sveltecomponents was simple enough to just use plain CSS for, but if I ever buildsomething more complex or integrated, I'd love to combine this.

To improve on this setup, I'd prefer to see some way to transform Sveltecomponents in a way similar to how PostCSS can be invoked to transform andbundle assets. I have no idea how exactly, but I think I'll start aconversation about that in Hugo's communitysomewhere soon.

Hugo, Tailwind, Svelte - luit.eu (2024)
Top Articles
Funfetti Pudding Pops Recipe
Poor Things movie review &amp; film summary (2023) | Roger Ebert
Citibank Branch Locations In Orlando Florida
Team 1 Elite Club Invite
La connexion à Mon Compte
Rek Funerals
Fully Enclosed IP20 Interface Modules To Ensure Safety In Industrial Environment
Santa Clara College Confidential
THE 10 BEST River Retreats for 2024/2025
The Haunted Drury Hotels of San Antonio’s Riverwalk
83600 Block Of 11Th Street East Palmdale Ca
Derpixon Kemono
Danielle Longet
Jet Ski Rental Conneaut Lake Pa
Wilmot Science Training Program for Deaf High School Students Expands Across the U.S.
Define Percosivism
Sni 35 Wiring Diagram
Whitefish Bay Calendar
CVS Near Me | Columbus, NE
Magic Seaweed Daytona
Zillow Group Stock Price | ZG Stock Quote, News, and History | Markets Insider
Cain Toyota Vehicles
Apartments / Housing For Rent near Lake Placid, FL - craigslist
4 Times Rihanna Showed Solidarity for Social Movements Around the World
Kitchen Exhaust Cleaning Companies Clearwater
Relaxed Sneak Animations
Mcclendon's Near Me
La Qua Brothers Funeral Home
Http://N14.Ultipro.com
The Hoplite Revolution and the Rise of the Polis
Fox And Friends Mega Morning Deals July 2022
Beth Moore 2023
How to Watch the X Trilogy Starring Mia Goth in Chronological Order
Royals op zondag - "Een advertentie voor Center Parcs" of wat moeten we denken van de laatste video van prinses Kate?
Foolproof Module 6 Test Answers
New Gold Lee
Pinellas Fire Active Calls
Troy Gamefarm Prices
Poe Flameblast
RALEY MEDICAL | Oklahoma Department of Rehabilitation Services
Lyca Shop Near Me
The Thing About ‘Dateline’
Skip The Games Grand Rapids Mi
Craigslist Mexicali Cars And Trucks - By Owner
What Is A K 56 Pink Pill?
Booknet.com Contract Marriage 2
Unit 11 Homework 3 Area Of Composite Figures
Meet Robert Oppenheimer, the destroyer of worlds
Mega Millions Lottery - Winning Numbers & Results
Sapphire Pine Grove
Autozone Battery Hold Down
Dumb Money Showtimes Near Regal Stonecrest At Piper Glen
Latest Posts
Article information

Author: Laurine Ryan

Last Updated:

Views: 6012

Rating: 4.7 / 5 (57 voted)

Reviews: 80% of readers found this page helpful

Author information

Name: Laurine Ryan

Birthday: 1994-12-23

Address: Suite 751 871 Lissette Throughway, West Kittie, NH 41603

Phone: +2366831109631

Job: Sales Producer

Hobby: Creative writing, Motor sports, Do it yourself, Skateboarding, Coffee roasting, Calligraphy, Stand-up comedy

Introduction: My name is Laurine Ryan, I am a adorable, fair, graceful, spotless, gorgeous, homely, cooperative person who loves writing and wants to share my knowledge and understanding with you.