Customizable Landing Page in Elm

We have both the Fission home page (Github) and the more relevant one page swag form as examples of landing pages.

Taking advantage of the Fission webnative SDK and platform, the goal is to make a landing page app that is easily customizable / remixable / cloneable.

Description

A landing page skeleton that is optimized to make a single public page whose content / design can be edited by relatively non technical users directly through the browser.

The “backend” can start as a YAML file, where the user edits it as a basic text file (e.g. with Fission Drive, as we’d like to include basic text editor there).

It can be extended on over time to include other backends and integrations, or simply embed HTML for widgets etc.

The RSVP for Events is an example of a widget / backend that could be included in such a landing page.

The swag landing page currently uses Send in Blue as the “back end”.

User Impact

Who would want to use this and why?

Making single web pages for forms, portfolio, about me, events, notices, and so on. Carrd is an example of a commercial service that does this today.

Can be built on by designers (make custom designs, sell them to clients), developers (add a new widget / backend), and users.

Features

  • basic single page design
  • configurable / editable elements – hero image / logo, headline, body text – in a YAML file
  • build on tailwindcss
  • editable user styles (stretch) – have some logic that looks at userstyles.css or similar
  • support for Fission customize / remix feature (TBD)

Future

  • Forms backend – RSVP for Events is a minimal version of that; building a form builder is out of scope – being able to use the webnative SDK to submit form data to / notify the page owner would be ideal

Thinking about the metadata in particular a bit more. These tags will only work when the tags are served, so it really is a special case compared to something like user styles. I like @boris’s idea of changing these fields directly in IPFS.

The easy part is changing the content. That’s a matter of parsing the <head>, finding the right tag, and changing the content, and updating the data root. We can do that client side for sure.

The question is, of course: where does the HTML wrapper of an app live? Well, we’re already doing a bunch of guessing build directories, and letting users pick other locations. Why not do the same? If we infer that it’s Gatsby, use the default location for Gatsby. If elm-pages, use the expected location of the build dir’s index.html. We can always prompt for user help and cache their answer.

I’m trying to infer the exact requirements for this idea.

The first requirement I can gather is:
We need to store the landing page’s .html file in ipfs with meta tags.

The second requirement is a little less clearly defined:
We don’t want the user to have to download something outside their browser.
So, something that requires a build, e.g. elm-pages gets a lot harder to do.

Here are some requirements that one might want, but I’m not sure we’re aiming for:

Do we want to have pre-rendered page content? This might lead to better SEO and UX, since the time to first render is smaller.

Do we want to purge css? By knowing which styles an application uses in advance, the tailwind css files can be reduced by a lot. Note that for this we’d need a tailwind build process somewhere.

Do we want to have static sites only, or also dynamic sites? The fission landing page and swag page both have quite some custom interactivity. This way we e.g. don’t reload the whole page when clicking on links, provide form errors in a matching style or don’t have to load another page when submitting a form.


With these requirements in the back of my mind, I’m thinking of following design:

We have these artifacts:

  • The fission drive (it’s already built) and everything that allows us to read and write to it from an Elm application (the webnative/webnative sdk?)
  • The landing page builder (built by us):
    An Elm app landing page site builder/editor. It renders normally using elm. It can also render the landing page that the user configured itself. This landing page is supposed to be 90% static. So after rendering, it’s possible to inspect the virtual dom from javascript and render that to an .html file. In this step, it’s possible to add meta tag information.
  • The aforementioned html file, the landing page itself:
    It’s built by some javascript from the landing page builder and saved to the user’s fission drive using the webnative sdk.
  • Webcomponents for interactive elements in the landing page:
    Though most elements in the landing page are static, some will require interactivity. For these, we’ll use webcomponents. They can be written in elm and be used for things like:
    • wrapping forms, so they don’t reload on submission
    • custom form input elements which show styled error messages when validation fails

The webcomponents can just be added as script tags added by our landing page builder’s virtual-dom-to-html renderer.

I’d specifically not recommend elm-pages for following reasons:

  • Elm-pages requires a build process outside the browser. Deep down in it’s dependencies is puppeteer, essentially a headless chromium for running a browser window with the Elm page running inside, waiting for the first render to finish and grabbing all html. It’s possible but infeasible to run this within the browser.
  • Elm-pages is not built for this: It cares about developer experience. But we don’t want any developers, we want to use it as a tool.
  • Elm-pages has lots of feature we don’t need for this:
    • a preconfigured webpack for elm and content files
    • ‘StaticHttp’: The ability to run http requests to fetch data for the pages at build time. We don’t really want a build process. If we want the user to fetch data from http before publishing the page, we’d just do this in the builder. I should note, however, that the landing page uses StaticHttp to fetch the latest blog posts.
    • generating a metadata.json (with a required configuration) so that the app can be added as PWAs on mobile devices.

Let me know what you think. Does this help?
I feel most uncertainty around webcomponents at the moment. What do they look like when the browser hasn’t loaded javascript yet? How good is SEO?