Requests

Every page in your application gets access to a Request value, containing details about the current URL.

page : Shared.Model -> Request -> Page
page shared req =
    ...

This might be useful when you need to show the active link in your navbar, or navigate to a page programmatically. Let's look at the properties on req that you might find useful!

req.params

Every dynamic route has parameters that you'll want to get access to. For static routes, those parameters will be ():

URLRequest
/Request
/about-usRequest
/people/:nameRequest.With { name : String }
/posts/:post/users/:userRequest.With { post : String, user : String }

Here's an example for a file at People/Name_.elm:

URLreq.params
/people/alexa{ name = "alexa" }
/people/erik{ name = "erik" }
/people/ryan{ name = "ryan" }

req.query

For convenience, query parameters are automatically turned into a Dict String String, making it easy to handle common query URL parameters like these:

/people?team=design&ascending
Dict.get "team" req.query == Just "design"
Dict.get "ascending" req.query == Just ""
Dict.get "name" req.query == Nothing

If you need ever access to the raw query string, you can with the req.url.query value!

req.route

The req.route value has the current Route, so you can safely check if you are on a specific page.

All the routes generated by elm-spa are available at Gen.Route.

-- "/"
req.route == Gen.Route.Home_

-- "/about-us"
req.route == Gen.Route.AboutUs

-- "/people/ryan"
req.route == Gen.Route.People.Name_ { name = "ryan" }

req.url

If you need the port, fragment, or anything else, req.url contains the original elm/url URL value.

type alias Url =
    { protocol : Protocol
    , host : String
    , port_ : Maybe Int
    , path : String
    , query : Maybe String
    , fragment : Maybe String
    }

This is less commonly used than req.params and req.query, but is useful in specific cases.

Programmatic Navigation

Most of the time, navigation in Elm is as easy as giving an href attribute to an anchor tag:

link =
  a [ href "/guide" ] [ text "Guide" ]

With the generated route code, we can even prevent the need for string URLs. This is great for refactoring and catching typos:

import Gen.Route as Route

link =
  a [ href (Route.toHref Route.Guide) ] [ text "Guide" ]

Other times, you'll want to do programmatic navigation – navigating to another page after some event completes. Maybe you want to redirect to a sign in page, or head to the dashboard after signing in successfully.

In that case we store req.key in order to use Request.pushRoute or Request.replaceRoute. Here's a quick example of what that looks like:

type Msg = SignedIn User

update : Request Params -> Msg -> Model -> ( Model, Cmd Msg )
update req msg model =
  case msg of
    SignedIn user ->
      ( model
      , Request.pushRoute Gen.Route.Dashboard req
      )

When the SignedIn message is fired, this code will redirect the user to the Dashboard route.


Next up: Shared state