Learning-HTMX/11-single-price-grid-component/README.org

4.1 KiB

Frontend Mentor - Single price grid component solution

This is a solution to the Single price grid component challenge on Frontend Mentor. Frontend Mentor challenges help you improve your coding skills by building realistic projects.

Overview

The challenge

Users should be able to:

  • View the optimal layout for the component depending on their device's screen size
  • See a hover state on desktop for the Sign Up call-to-action

Screenshot

/efim/Learning-HTMX/media/branch/master/11-single-price-grid-component/screenshot-desktop.png /efim/Learning-HTMX/media/branch/master/11-single-price-grid-component/screenshot-mobile.png

My process

Built with

  • Semantic HTML5 markup
  • TailwindCSS
  • Scalatags html generation on backend
  • Cask simple Scala web server, with annotations to mark routes and simple functions to process request
  • Mobile-first workflow
  • Nix for building the application, nix module for easy install to servers with NixOS, and docker image for other deployment

What I learned

Setting up Cask server to serve static resources

Previously in Vite the /public directory was just automagically made available to the production build. Now, with @cask.staticFiles("/public") the route /public would serve files from "public" directory

The path is relative, so directory from which the server is started is important. But the thing works.

First time installing TailwindCSS with cli, without the frontend bundler integration

https://tailwindcss.com/docs/installation

$ tailwindcss -i ./src/input.css -o ./dist/output.css --watch

Idea for this exercise was to generate `out.css` of the final TailwindCSS stylesheet into /dist directory, which would be in .gitignore

The problem I've encountered - the nix derivation doesn't like to have all of the files in the tmp build directory, so files are referenced and loaded by neat library function

    src = pkgs.nix-gitignore.gitignoreSource [ ] ./.;

Which only puts unignored files into store. So one time for the build step i'm using tailwind this way:

buildPhase = ''
    sbt assembly
    tailwindcss -i ./src/input.css -o ./output.css
'';

and then copy resulting file where the server expects it to be.

Written a NixOS module with Systemd service and a Nginx reverse proxy

on my NixOS server i just need to reference the flake by the repository url, import the module, and then

imports = [ inputs.htmx-examples.nixosModules.x86_64-linux.price-grid-app ];
services.priceGridService = {
  enable = true;
  host = "price-grid.frontendmentor.sunshine.industries";
  port = 12345;
};

setting up config values, and enable = true; makes the server instantiate the systemd service, which will cover restarts and logs, and nginx reverse proxy.

Found out about Workdir setting of systemd servcie and WorkingDir of docker image

Continued development

This was first app (exercise #11) in the experiment with learning SSR in Scala, i've already completed exercise #14, and in the following steps I'm learning Thymeleaf templating engine, and HTMX - the library for extending html to make pages that allow easier partial page updates.

Acknowledgments

My gratitude to render.com who are providing free tier for the service hosting from the docker image. Which was necessary for me to submit the solution into frontendmentor. And to DockerHub for hosting my docker images gratis as well. And to Nix for their documentation!