Search code examples
elm

Each page of simple page application as a separate app


Currently, I have no way to structure my pages as separate apps. The way I am currently thinking is as follows:

  • The App / Main file is the bootstrapper which provides the routing.
  • The blog is a seperate app with its own update, models and REST calls.
  • When switching to another route (e.g. photo albums), it will start up another Elm app with its own update, modes, et cetera.

Is there a way to achieve this?


Solution

  • Well, there are different ways to achieve this:

    1. One Elm app, with each page as a separate component

    In that case, you create one "root" elm module, which imports your photo Model, Msg, init, update, view. And same for your blog.

    Then you have 1 elm app. This is the approach I would take: Allows you to manage global front-end state, like user-info in one place and across photo and blog.

    Your main elm file would then look something like this:

    import PhotoPage
    import BlogPage
    
    type alias Model =
      { photo : PhotoPage.Model
      , blog : BlogPage.Model
      , currentPage : Page
      }
    
    type Page = Home | Blog | Photo
    
    init = 
      { photo = PhotoPage.init
      , blog = BlogPage.init
      , currentPage = Home
      }
    
    type Msg =
      GoHome
      | PhotoMsg PhotoPage.Msg
      | BlogMsg BlogPage.Msg
    
    update msg model =
      case msg of
        PhotoMsg photoMsg ->
          let
            (newPhoto, photoCmd) = PhotoPage.update photoMsg model.photo
          in
            { model | photo = newPhoto }
            ! [ Cmd.map PhotoMsg photoCmd ]
    

    2. Completely separate elm apps

    Build 3 completely independent apps/ websites, each with own index.html, and own elm app.

    And you use default browser navigation to navigate between your different Elm apps.

    This could work if you have some way to manage global state at server/ session level.

    Your view function in your home.elm file could then look something like this:

    view model =
      div []
       [ h1 [] [ text "I am the homepage"]
       , a [ href "/photo" ] [ text "go to photo page" ]
       ]