Lately there has been some interesting discussion about Modern Web.
I personally think that
- Single Page Applications (SPAs) have been (ab)used in places where a more traditional server side approach could have been a better fit
- SPAs require extra care (navigation, scrolling, accessibility, SEO, etc.)
- There are many SPAs that are not well crafted but when they are well made, SPAs can very much enhance the user experience
- The browser feels like the natural place where to handle complex UIs, not the Server
- As developers, I (we?) like to keep using my best tools to improve the Developer Experience
Related to the last point I feel that the Elm language come with a curse:
"Once you are in Elm, you want to stay in Elm"
This is not happening only with Elm, but with any compiled-strictyly-typed-inferred-immutable-purely-functional-with-nice-errors language.
So to alleviate some of these issues I made a small script to convert Elm SPAs into Statically Generated Progressive Web Applications (PWAs), called
(Yes, another one)
The goal is to have a tool that
- Is mainly written in Elm (see the curse mentioned above)
- Supports the majority of Elm libraries (elm-ui, elm-spa, etc.)
- Relatively simple to use
- Can be used to bootstrap a new app or to convert an existing one
- Is not invasive and can be removed at any time
The resulting PWA should have these characteristics
- Works off-line
- Is installable on mobile/desktop
- Is friendly to bots (SEO)
- Supports preview cards
- Renders fast (gets high scores in Lighthouse)
The classic Lighthouse screenshot with confetti 🎉
Preview cards in Slack:
- Generates all the needed files for a PWA
- Centralize in one "single-source-of-truth" all metadata
- Generates static pages
This is all. Quite simple!
There are 3 demos made with
Note that the page transition is made with CSS transition applied to SVG. I realized too late that this is only supported in Chrome and I didn't have the time to change it, but you get the picture.
This is the classic Todo MVC, the one that I used extensively to compare different frameworks in a past article.
It was originally coded by Evan Czaplicki, I just adjusted it to fix some accessibility issues.
The preview card on Slack:
This example shows a possible synergy between elm-spa, a nice way to create complex SPAs that take care of several things for you through automatic Elm code generation. For example, to create new pages you simply run a command in the terminal and this creates the right files, routes and logic for you.
elm-starter can then take over and transform it in a PWA, statically generating all routes.
The preview card on Slack:
All files are generated by Elm code:
HTML: Generated using a modified version of zwilias/elm-html-string. For example Index.elm generates
JSON: Generated using elm/json. For example Manifest.elm generates
CSS: Generated from strings. I know, this is not ideal. rtfeldman/elm-css, that is CSS with the type-safety of Elm, seems not exposing the
toStringconverter. The quantity of CSS necessary in
elm-starteris very small anyway so I kept it as a string. For example SnippetCss.elm.
- HTML: Generated using a modified version of zwilias/elm-html-string. For example Index.elm generates
All static pages and snapshots are generated using Puppeteer.
This is a snapshot of Index.elm that generates
This is how Google indexed the
elm-starter demo after few days from its launch:
These are other excellent projects that can be used to bootstrap an Elm application or to generate a static site:
To get more insights about the debate mentioned at the beginning of this post:
- The disadvantages of single page applications by Adam Silver
- The Return of the 90s Web by Max Böck
- Server-Side Rendering is a Thiel Truth by Tim Ruffles
- The Architecture No One Needs by Greg Navis
- Why I hate your Single Page App by Stefan Tilkov
- Second-guessing the modern web by Tom MacWright
- In defense of the modern web by Rich Harris
- “The Modern Web” by Chris Coyier
You can find
elm-starter at github.com/lucamug/elm-starter.
The fastest way to start using it is by clicking this button:
This will automatically
- Create a repository containing
elm-starterinto your Github account
- Deploy it live using your Netlify account
To modify the app simply clone the new repo on your computer and run:
$ npm install $ npm start
Now you can edit
src/Main.elm and, after confirming the result at http://localhost:8000, commit your modifications to Github.
The new app will be published live automatically by Netlify in seconds, including re-generating all static pages.
More information available in the README.
This is all, thank you for reading! ❤️
Cover image: Mount Fuji seen from Kawaguchi lake by WorldInMyEyes from Pixabay