Pull in typed Elm data to your pages

Whether your data is coming from markdown files, APIs, a CMS, or all of the above, elm-pages lets you pull in just the data you need for a page. No loading spinners, no Msg or update logic, just define your data and use it in your view.

module Page.Repo.Name_ exposing (Data, Model, Msg, page)
type alias Data = Int
type alias RouteParams = { name : String }
page : Page RouteParams Data
page =
Page.prerender
{ head = head
, routes = routes
, data = data
}
|> Page.buildNoState { view = view }
routes : DataSource (List RouteParams)
routes =
DataSource.succeed [ { name = "elm-pages" } ]
data : RouteParams -> DataSource Data
data routeParams =
DataSource.Http.get
(Secrets.succeed "https://api.github.com/repos/dillonkearns/elm-pages")
(Decode.field "stargazer_count" Decode.int)
view :
StaticPayload Data RouteParams
-> View Msg
view static =
{ title = static.routeParams.name
, body =
[ h1 [] [ text static.routeParams.name ]
, p [] [ text ("Stars: " ++ String.fromInt static.data) ]
]
}

Combine data from multiple sources

Wherever the data came from, you can transform DataSources and combine multiple DataSources using the full power of Elm's type system.

type alias Project =
{ name : String
, description : String
, repo : Repo
}
all : DataSource (List Project)
all =
Glob.succeed
(\projectName filePath ->
DataSource.map2 (Project projectName)
(DataSource.File.rawFile filePath DataSource.File.body)
(repo projectName)
)
|> Glob.match (Glob.literal "projects/")
|> Glob.capture Glob.wildcard
|> Glob.match (Glob.literal ".txt")
|> Glob.captureFilePath
|> Glob.toDataSource
|> DataSource.resolve
repo : String -> DataSource Repo
repo repoName =
DataSource.Http.get (Secrets.succeed ("https://api.github.com/repos/dillonkearns/" ++ repoName))
(OptimizedDecoder.map Repo
(OptimizedDecoder.field "stargazers_count" OptimizedDecoder.int)
)

SEO

Make sure your site previews look polished with the type-safe SEO API. `elm-pages build` pre-renders HTML for your pages. And your SEO tags get access to the page's DataSources.

head :
StaticPayload Data RouteParams
-> List Head.Tag
head static =
Seo.summaryLarge
{ canonicalUrlOverride = Nothing
, siteName = "elm-pages"
, image =
{ url = static.data.image
, alt = static.data.description
, dimensions = Nothing
, mimeType = Nothing
}
, description = static.data.description
, locale = Nothing
, title = static.data.title
}
|> Seo.article
{ tags = []
, section = Nothing
, publishedTime = Just (Date.toIsoString static.data.published)
, modifiedTime = Nothing
, expirationTime = Nothing
}

Optimized Data

The OptimizedDecoder module is a drop-in replacement for vanilla decoders. Just by using that module, elm-pages will strip out any untouched JSON values from your DataSource's.

import OptimizedDecoder
data : RouteParams -> DataSource Data
data routeParams =
DataSource.Http.get
(Secrets.succeed "https://api.github.com/repos/dillonkearns/elm-pages")
(OptimizedDecoder.field "stargazer_count" OptimizedDecoder.int)
{-
Full API response from https://api.github.com/repos/dillonkearns/elm-pages
{
"id": 198527910,
"node_id": "MDEwOlJlcG9zaXRvcnkxOTg1Mjc5MTA=",
"name": "elm-pages",
"full_name": "dillonkearns/elm-pages",
"private": false,
"owner": { ... },
.....
"stargazers_count": 394,
.....
}
Optimized data for initial page load:
{
"stargazers_count": 394
}
-}