Elm spa example header with shared button (on Click) attribute

One way could be to render the header in the Main outside the page specific view (without using Html.map).

I think it is quite common for SPAs to render the layout of the app (header or app bar, footer, menu) this way in Main with Main messages, and then render the page only inside its container with Html.map.

Something like:

type Msg
    = HeaderClicked
    | ChangedUrl Url
    | ClickedLink Browser.UrlRequest
    | GotHomeMsg Home.Msg
    ...

view : Model -> Document Msg
view model =
    let
        viewer =
            Session.viewer (toSession model)

        viewPage page toMsg config =
            let
                { title, body } =
                    Page.view viewer page config
            in
            { title = title
            , body = viewHeader :: List.map (Html.map toMsg) body
            }
    in
    ...


viewHeader : Html Msg
viewHeader =
    div []
        [ button
            [ onClick HeaderClicked ]
            [ text "Click me" ]
        ]

and you would remove the banner view from each page.

2 Likes