Skip to content



The View module is returned by pages and layouts to tell Elm what to render on the screen. By default, the value of View msg matches Elm's Browser.Document type. This allows us to specify what to render in the tab title, and within the page:

type alias View msg =
    { title : String
    , body : List (Html msg)

For many applications, this type is all you need. But you can also change this type to use different Elm UI packages!

Custom views

Some folks in the Elm community prefer to build their UI in things other than the core elm/html package.

Here are some popular alternatives:

mdgriffith/elm-ui"Layout and style that's easy to refactor, all without thinking about CSS."
rtfeldman/elm-css"Typed CSS in Elm."
matheus23/elm-default-tailwind-modules"The default tailwind classes as elm-css, generated using elm-tailwind-modules."

Each of these packages don't use the Html type. By customizing Elm Land's View type, we make it easier to work with them across pages and layouts.

If you'd like to use an alternative Elm UI package, you can do this with the elm-land customize command.

Use mdgriffith/elm-ui:

elm-land customize view:elm-ui

Use rtfeldman/elm-css:

elm-land customize view:elm-css

To use an arbitrary custom UI package, start with the default View module and adjust it as needed:

elm-land customize view

Looking for examples?

As a starting point, we have some official examples of working with Elm UI and Elm CSS in the official repo's examples/ folder.

Be sure to check those out if you're planning to use either UI package with Elm Land!


Used internally by Elm Land to create your application so it works with Elm's expected Browser.Document msg type.

Example (for Elm UI)

toBrowserDocument :
    { shared : Shared.Model.Model
    , route : Route ()
    , view : View msg
    -> Browser.Document msg
toBrowserDocument { view } =
    { title = view.title
    , body = [ Element.layout view.attributes view.element ]

Used internally by Elm Land to connect your pages together.

Example (for Elm UI)

map : (msg1 -> msg2) -> View msg1 -> View msg2
map fn view =
    { title = view.title
    , attributes = (Element.mapAttribute fn) view.attributes
    , element = fn view.element


Used internally by Elm Land whenever transitioning between authenticated pages.

Example (for Elm UI)

none : View msg
none =
    { title = ""
    , attributes = []
    , element = Element.none


If you customize the View module, anytime you run elm-land add page, the generated page will use this when adding your view function.

That way your app will compile after adding new pages, and you can see the new page working in the web browser!

Example (for Elm UI)

fromString : String -> View msg
fromString moduleName =
    { title = moduleName
    , attributes = []
    , element = Element.text moduleName

Made for you with ❤️