dillonkearns/elm-pages/5.0.2

NOTE: the latest version is 12.3.0

Pages.Platform

Configure your elm-pages Program, similar to a Browser.application.

This is the entry point for your elm-pages application.

This is similar to how you set up a regular Elm application using Browser.application, but with a few differences.

  • view has access to StaticHttp data (see Pages.StaticHttp).
  • view is able to set head tags which can be used for site metadata and SEO data.
  • manifest lets you configure the manifest.json for your PWA (Progressive Web App).
  • canonicalSiteUrl is the default domain for your <head> tags for SEO purposes (you can override it with canonicalUrlOverride, see <Head.Seo>. Learn more about canonical URLs and why they are important in this article.
  • internals is an opaque data type with some internal boilerplate from your elm-pages content. You should pass it internals = Pages.internals.

Otherwise, you have a standard Elm app which

elm-pages Lifecycle

It's helpful to understand the elm-pages lifecycle and how it compares to a vanilla elm app (i.e. a Browser.application).

Generate Step (elm-pages build)

Whereas a vanilla Elm app simply compiles your Elm code at build time, elm-pages performs some lifecycle events at this stage.

  • Performs all StaticHttp.Requests (see <Pages.StaticHttp>) for every static page in your app. The StaticHttp Responses are stored in JSON files called content.json (one JSON file for each static page in your site).
  • Pre-renders HTML pages, including the <head> tags for the page from your view's head.
  • Optimizes image assets and copies over files from static folder to the dist folder.

Initial Load (from user's browser)

The user will see the pre-rendered HTML when they initially load a page on your elm-pages site (unless you are in dev mode, i.e. elm-pages develop, in which case there is no pre-rendering).

Hydration

  • Fetch all the StaticHttp responses and page data (the content.json file for the current page).
  • The Elm app hydrates and starts executing and running your Elm app's init function and update loop (not just the pre-rendered HTML content). At this point, all of your subscriptions, etc. will behave as they would in a regular Elm application.
  • The app will now run as a single-page app. When you hover over a link to another static page on your current site, it will pre-fetch the page data (content.json file), so that the page load is instant.

Basic application config

type Builder pathKey model msg metadata view

You can init a Builder, and then turn it to a Program with toProgram.

That gives you the basic options, then you can include optional configuration.

{ init :
Maybe
{ path : PagePath pathKey
, query : Maybe String
, fragment : Maybe String
}
-> ( model, Cmd msg )
, update : msg -> model -> ( model, Cmd msg )
, view :
List ( PagePath pathKey, metadata )
-> { path : PagePath pathKey
, frontmatter : metadata
}
-> Request
{ view :
model
-> view
-> { title : String
, body : Html msg
}
, head : List (Tag pathKey)
}
, subscriptions : model -> Sub msg
, documents :
List
{ extension : String
, metadata : Decoder metadata
, body : String -> Result String view
}
, onPageChange :
Maybe
( { path : PagePath pathKey
, query : Maybe String
, fragment : Maybe String
}
-> msg
)
, manifest : Config pathKey
, canonicalSiteUrl : String
, internals : Internal pathKey
}
-> Builder pathKey model msg metadata view

Pass the initial required configuration for your elm-pages application.

Here's a basic example.

import Pages.Platform


main : Pages.Platform.Program Model Msg Metadata View
main =
    Pages.Platform.init
        { init = init
        , view = view
        , update = update
        , subscriptions = subscriptions
        , documents =
            [ { extension = "md"
              , metadata = Metadata.decoder
              , body = MarkdownRenderer.view
              }
            ]
        , onPageChange = Just OnPageChange
        , manifest = manifest
        , canonicalSiteUrl = canonicalSiteUrl
        , internals = Pages.internals
        }
        |> Pages.Platform.toProgram
Builder pathKey model msg metadata view
-> Program model msg metadata view

When you're done with your builder pipeline, you complete it with Pages.Platform.toProgram.

type alias Program model msg metadata view =
Program model msg metadata view

The Program type for an elm-pages app.

type alias Page metadata view pathKey =
{ metadata : metadata
, path : PagePath pathKey
, view : view
}

Additional application config

List (Tag pathKey)
-> Builder pathKey model msg metadata view
-> Builder pathKey model msg metadata view

Add some head tags that will be included on every page of your elm-pages site.

( List
{ path : PagePath pathKey
, frontmatter : metadata
, body : String
}
-> Request
(List
(Result
String
{ path : List String
, content : String
}
)
)
)
-> Builder pathKey model msg metadata view
-> Builder pathKey model msg metadata view

Include files to be generated. Any Err values will turn into a build error.

You can use StaticHttp data here, and it won't be included in your production build (it will just be fetched as needed during the build step). You also have access to all of your site's pages, with their path, metadata, and body.

Some use cases are to generate

  • A sitemap
  • An RSS feed
  • A robots.txt file
  • Podcast feeds
  • Configuration files (e.g. Netlify CMS config)
    import Pages.Platform

    withRobotsTxt builder =
    builder
        |> Pages.Platform.withFileGenerator
            (\siteMetadata ->
                StaticHttp.succeed
                    [ Ok
                        { path = [ "robots.txt" ]
                        , content = """
User-agent: *
Disallow: /cgi-bin/
                        """
                        }
                    ]
            )