Announcing elm-pages 📚 - a type-centric static sites generator

I’m very pleased to announce elm-pages. It’s a new Elm static site generator. Some of the project’s goals are:

  • Make SEO (and nice Slack/Twitter/Discourse previews like you see above) dead simple!
  • Let you use nice Elm types to set up your SEO and render your pages
  • Pure Elm configuration
  • Generate a performant single-page app from your markup

If you give it a try, I’d love your feedback! Here’s a starter repo you can use to get up and running quickly.

34 Likes

Congratulations!
This will allow me to use Elm for a set of pages it was simply not very well suited before!

I am especially curious how you are going to design the interface for build time data fetching. It would be great for some of my usecases to be able to both specify some kind of a fallback in case of failure or pass the failure through, stopping the build process altogether and keeping the last working version around.

2 Likes

Thank you @brasilikum! Yes, it is really fun exploring some of these use cases that elm-pages can help with.

CMS options that already work with elm-pages

It’s worth noting that elm-pages already works quite nicely with git-based CMSes. Netlify CMS is a git-based option that has a really great all around experience.

elm-pages-netlify-starter

You can try out Netlify CMS with this starter kit I put together. There’s a one-click “Deploy to netlify” button on the page that will automatically fork the repo for you, deploy the site to Netlify, and configure the CMS for you so you can use the nice UI to add new pages and blog posts! Really neat workflow.

And hey, why not, I’ll add the magical button here, too. It’s quite impressive how easy they make it!

:point_down:

Deploy to Netlify

The one thing I recommend setting up Github as an authentication provider in their console after using the “Deploy to netlify” button: https://www.netlify.com/docs/identity/#external-provider-login.

Future ideas for fetching API data at build-time

To your question about what that workflow might look like, I have a few ideas.

In a nutshell, what I’m imagining is a that the view function (as well as head which gives you the <head> tags for a given page) would have access to the current page’s “static Http response data” (static meaning that it’s from a request that is captured at build-time):

-- given both
-- 1) all pages' metadata
List ( PagePath PathKey, parsedFrontmatter )
-- and 2) the current page's metadata
-> ( PagePath PathKey, parsedFrontmatter )
->
    -- tell me the
    -- static HTTP request(s) for current page
    ( StaticHttp httpResponse
      -- and given the HTTP response (guaranteed to be present and success)...
    , httpResponse
      -- ...what should the current page's `<head>` tags and `view` be?
      ->
        { view :
            model
            -> pageView
            -> { title : String, body : Html userMsg }
        , head : List (Head.Tag PathKey)
        }
    )

Or, in English:

I will give you the parsed frontmatter for a given page, and you tell me a list of HTTP requests to make for that page.

Then, given the data from those HTTP requests, and your model, tell me how to render the view.

The Pages.HttpRequest type

You may have noticed the type I referenced above called Pages.HttpRequest. Here’s the reason it’s not just a Cmd, in case you’re curious!

Image a drop-in replacement for the Http package that returns type Pages.HttpRequest a. This drop-in replacement allows me to pull apart the internals, in addition to actually building up a full HTTP request and executing it during the build step. Since I can pull apart the internals, I can look at the URL and headers and create a unique hash based on that data which I can use to lookup the data and avoid refetching identical data. I can also take the JSON decoder and use it separately from the HTTP request (so I can do the HTTP request at runtime, make sure it can be decoded successfully, but then only run the decoder at build time and not the HTTP request).

Feedback welcome!

Thanks for the question. I would love to hear more about your use case and whether Netlify CMS would do the trick, or if a design like I described above would be helpful.

And as always, I love getting feedback, so I’d love to hear thoughts from anyone in the community.

8 Likes

Dillion, this is really great work! Thank you so much for this! Now that I’ve played around with it a bit, I have to say that this is exactly what I’ve been waiting for in the Elm ecosystem.
Being able to build Elm apps on Netlify is a blast. I’ve been looking into JAMstack for a while, but wanted to work with Elm at all costs.
And as much as I love elmstatic, there is definitely an even greater need for fully interactive Elm apps with serverside rendering.
The only other solution I’ve found so far is Spades (https://github.com/rogeriochaves/spades). What I like about Spades is the code generator to add components and routes. But your simpler approach has its advantages as well.
I’m sure I’ll come back to you with feature requests as soon as I’ve set up some production apps ;-). Especially building an e-commerce shop based on elm-pages is something I’m interested in.
Keep up the good work. I hope to see future releases with more awesomeness.

2 Likes

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.