Mint ๐Ÿƒ: Routing

Szikszai Gusztรกv - May 29 '19 - - Dev Community

This is the seventh post in a series that showcases the features of Mint, you can find the previous posts here:

In this post I will show you how to set up routes for your application.


In JavaScript land you would use a third party routing library like react-router, vue-router or something similar (depending on the framework) to handle changes in the URL.

In Mint, routing is built into to language itself ๐ŸŽ‰ so there is one less dependency to worry about.

Defining routes

You can use the routes block to define routes:

routes {
  /path/to/match {
    /* Do something here... */
  }

  /an/other/path/to/match {
    /* Do something here... */
  }
}
Enter fullscreen mode Exit fullscreen mode

Basically you just define the path you want to match and in a block what should happen when that path is matched.

There two things to keep in mind:

  • routes are matched from top to bottom
  • only one route matches per navigation event

Matching parameters

You can use the standard colon parameters (:param) for path variables:

routes {
  /posts/:id (id : String) {
    /* Do something with the id here... */
  }

  /posts/:id/comments/:comment (id : String, comment : String) {
    /* Do something with the id and comment here... */
  }
}
Enter fullscreen mode Exit fullscreen mode

โ„น๏ธ The order of the variables does not matter but the names must match.

You can even match hash and query parameters:

routes {
  /posts?page=:page (page : String) {
    /* Do something with the page here... */
  }

  /#:hash (hash : String) {
    /* Do something with the hash here... */
  }
}
Enter fullscreen mode Exit fullscreen mode

โš ๏ธ Currently type coercion is not implemented in route parameters so everything is a String.

Matching all (not defined) paths

Using the * block matches all (non defined) paths:

routes {
  * {
    /* Matches anything. Useful for displaying a 404 page. */
  }
}
Enter fullscreen mode Exit fullscreen mode

โ„น๏ธ It does not matter where this block is, it will always match last.

Navigating to a new URL

In Mint the language takes care of the navigation, all you have to do is render normal anchor tags <a href="/path/to/navigate"></a> and the runtime will do the rest:

  • if the href attribute matches a route it will navigate to it and call the block without reloading the page, otherwise it will navigate to the URL normally
  • browser specific behavior is kept:
    • if the default behavior was prevented with perventDefault it does not navigate
    • ctrl click opens the URL in a new tab (if applicable)

โ„น๏ธ If you are interested in the actual implementation you can find it here.

Practical usage and example

In a real application what I usually do is to have an enum that represents all the pages that can occur like this:

enum Page {
  NotFound
  Register
  Initial
  Login
  Home
}
Enter fullscreen mode Exit fullscreen mode

I also have a store called Application with a state for the page:

store Application {
  state page : Page = Page::Initial

  fun setPage(page : Page) : Promise(Never, Void) {
    next { page = page }
  }
}
Enter fullscreen mode Exit fullscreen mode

Then in the Main component I use that state to render the different pages:

component Main {
  connect Application exposing { page }

  fun render : Html {
    <div>
      <div>
        <a href="/register">"Register"</a>
        <a href="/login">"Login"</a>
        <a href="/asdf">"404"</a>
        <a href="/">"Home"</a>
      </div>

      <hr/>

      case (page) {
        Page::Register => <div>"Register"</div>
        Page::NotFound => <div>"404"</div>
        Page::Login => <div>"Login"</div>
        Page::Home => <div>"Home"</div>
        Page::Initial => <div></div>
      }
    </div>
  }
}
Enter fullscreen mode Exit fullscreen mode

And in the routes set the pages accordingly:

routes {
  /register {
    Application.setPage(Page::Register)
  }

  /login {
    Application.setPage(Page::Login)
  }

  / {
    Application.setPage(Page::Home)
  }

  * {
    Application.setPage(Page::NotFound)
  }
}
Enter fullscreen mode Exit fullscreen mode

And that is pretty much it ๐ŸŽ‰ here you can find a repository with the actual code:

mint-example-routing

This is a repository to showcase the routing in Mint.

That's it for today, thank you for reading ๐Ÿ™


If you like to learn more about Mint check out the guide ๐Ÿ“–

In the next part I'm going to show how you can use environment variables ๐Ÿ˜‰ see you there ๐Ÿ‘‹

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Terabox Video Player