[ANN] finch - static site generator

Announcing finch, a simple static site generator. It uses content written as Markdown plus YAML frontmatter like Jekyll/Hugo etc. and produces output with Jingoo templates. It also has some integrations with React (as in the JS library) in the form of Jingoo filters: the motivation behind it was to make it easier to develop sites that use React just for some in some parts rather than structuring the whole site as a single page application.

9 Likes

opam install finch-> doesnt look like its on opam yet.

It should be - maybe try opam update first?

2 Likes

Of course. Keep forgetting that. Thank you.

1 Like

For what it’s worth, you don’t have to structure your app as a SPA to use React as a templating engine. Of course, renderToStaticMarkup requires using Node while Jingoo is native, but that’s another story.

So there are two different kinds of rendering React that finch can do: using renderToStaticMarkup to be able to use React essentially just for templating, and using renderToString so you can have some HTML containing the output of renderToString(some_component) and also some JS that calls ReactDOM.hydrate() on that element. The idea is that you can have a traditional site consisting of multiple HTML pages rather than one big JS bundle, where React is used for some components but it’s not a React-controlled SPA (this is how e.g. Facebook use it). And furthermore by doing renderToString at compile time then hydrating at runtime rather than rendering at runtime, the HTML for your components will be visible as soon as the HTML of the page is loaded rather than after the JS is loaded and executed.

This second part was what I was talking about in terms of the motivation. As far as I can tell, the only existing options for doing this were calling renderToString manually and copying and pasting the result into your HTML, or using a framework like Next.js. I didn’t really want to learn/use a whole JS framework just for this, plus most frameworks seem to use “server side rendering” where you have to serve your frontend from a Node server whereas I like my frontend to be entirely static so it can be served from blob storage/a CDN. So I basically made this to automate the manual process (the relevant filter does just call React functions via Node; I didn’t reimplement them in OCaml). Then since I’d written a filter for renderToString I thought I might as well do one for renderToStaticMarkup – not sure there is much call for it since it is redundant with finch’s own templating system, but it’s there if anyone wants it!

2 Likes

Oh, I didn’t read the filter docs before I’ve posted my comment. Somehow I thought React can only be used on client, whereas in reality what happens on client is not finch’s concern at all. My bad.

And of course, you’re right that rehydrating requires renderToString, not renderToStaticMarkup.

As for SSR with React, you’re right that it’s mostly used with a Node server and most probably involves numerous DB queries. In most of the cases those queries are initiated by the components independently (during render), which is good for the app maintainability, but begets a hard problem of how to tell when all of the data for the page is there. So it’s probably way beyond the scope of generating html files from markdown or json.

By the way, I thought of adding React to my statically-built site hosted on Netlify (haven’t move beyond converting the templates from Pug to ReasonReact though), and I think that if you want a lib like React, you probably do want an SPA, and so to navigate to another page without a page reload, you would at least need a json with that page’s model (probably put next to that page’s index.html. But I haven’t really thought this through. Like how you tell the page template just by a link? Maybe you need to put it in the page model too. Etc.