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 ():
| URL | Request |
|---|---|
/ | Request |
/about-us | Request |
/people/:name | Request.With { name : String } |
/posts/:post/users/:user | Request.With { post : String, user : String } |
Here's an example for a file at People/Name_.elm:
| URL | req.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.queryvalue!
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