Hello everyone!
As I’m nearing the elm-pages v3 release, I’m building a few examples to showcase some of the new features. Since elm-spa-example
is the canonical Elm app, I went ahead and created a version of that with elm-pages
.
I started with the code from GitHub - ryannhg/elm-spa-realworld: The RealWorld example app built with elm-spa! since elm-pages and elm-spa both have file-based routing, so that was a more similar starting point to fork from.
Here’s the live demo (runs on Netlify with server-rendered HTML running on serverless functions - you can even disable JavaScript in your browser and try it out, including login, favoring, article creation, etc.).
https://elm-pages-realworld.netlify.app/
And the code is here:
I wanted to keep the functionality as similar as possible to the elm-spa-example
and realworld spec, so I refrained from adding some of the things that elm-pages
is best at, like pending/optimistic UI, adding meta tags using resolved data for a given route, doing dynamic client-side validations, and directly making database queries in the data
function. This is actually kind of cool in a way because it leaves those features as an exercise with the baseline being more simple. Might be the topic for a workshop exercise in the future or a video demo!
The only places where I deviated from the elm-spa-example behavior where places where writing idiomatic elm-pages
server-rendered code would require me to make a change. For example, I used Forms whenever possible, including GET
forms, which navigate to a URL with a query parameter when you submit them (this is how I handle pagination and tag filters). So the elm-spa-example doesn’t use URL query params to manage this, but I made this slight change here. I prefer this because it makes these URLs sharable, but it also lets you leverage elm-pages form features to reduce the amount of work to wire things up.
A few things to notice:
- None of the routes use
Model
,init
, orupdate
whatsoever! - There are no loading spinners - loading states are handled on the server (the
data
BackendTask’s are resolved before the initial page HTML is sent over). This often works out nicely because your server can make faster round-trips to fetch data since it’s in the same data center (as opposed to making round trips between the user’s Browser and your data center, which may be far apart). In the case of the realworld API that I’m hitting here, it’s pretty slow so this might not be ideal, but that’s the general idea. I might make a full-stack version of this demo that implements the backend as well - it turns out, this won’t be a lot more work than reaching out to an external API, and it will give us more control over the performance as well.
There’s a lot more to share about the upcoming elm-pages v3 release, so stay tuned! Feel free to share questions or feedback here, or join the #elm-pages
channel in the Elm Slack. You can try out the v3 beta with this starter repo as well. Cheers!