# Introduction - [What is Mithril?](#what-is-mithril) - [Getting started](#getting-started) - [Hello world](#hello-world) - [DOM elements](#dom-elements) - [Components](#components) - [Routing](#routing) - [XHR](#xhr) --- ### What is Mithril? Mithril is a modern client-side JavaScript framework for building Single Page Applications. It's small (< 8kb gzip), fast and provides routing and XHR utilities out of the box.
See the Pen Mithril Scaffold by Pat Cavit (@tivac) on CodePen.
Mithril is also loaded onto this page already, so you can start poking at the `m` object in the developer console right away if you'd like! --- ### Hello world Let's start as small as we can: render some text on screen. Copy the code below into your file (and by copy, I mean type it out - you'll learn better) ```javascript var root = document.body m.render(root, "Hello world") ``` Now, let's change the text to something else. Add this line of code under the previous one: ```javascript m.render(root, "My first app") ``` As you can see, you use the same code to both create and update HTML. Mithril automatically figures out the most efficient way of updating the text, rather than blindly recreating it from scratch. #### Live ExampleSee the Pen Mithril Hello World by Pat Cavit (@tivac) on CodePen.
--- ### DOM elements Let's wrap our text in an `See the Pen Simple Mithril Example by Pat Cavit (@tivac) on CodePen.
Note: If you prefer `` syntax, [it's possible to use it via a Babel plugin](jsx.md). ```jsx // HTML syntax via Babel's JSX pluginSee the Pen Mithril Component Example by Pat Cavit (@tivac) on CodePen.
--- ### Routing Routing just means going from one screen to another in an application with several screens. Let's add a splash page that appears before our click counter. First we create a component for it: ```javascript var Splash = { view: function() { return m("a", {href: "#!/hello"}, "Enter!") } } ``` As you can see, this component simply renders a link to `#!/hello`. The `#!` part is known as a hashbang, and it's a common convention used in Single Page Applications to indicate that the stuff after it (the `/hello` part) is a route path. Now that we're going to have more than one screen, we use `m.route` instead of `m.mount`. ```javascript m.route(root, "/splash", { "/splash": Splash, "/hello": Hello, }) ``` The `m.route` function still has the same auto-redrawing functionality that `m.mount` does, and it also enables URL awareness; in other words, it lets Mithril know what to do when it sees a `#!` in the URL. The `"/splash"` right after `root` means that's the default route, i.e. if the hashbang in the URL doesn't point to one of the defined routes (`/splash` and `/hello`, in our case), then Mithril redirects to the default route. So if you open the page in a browser and your URL is `http://localhost`, then you get redirected to `http://localhost/#!/splash`. Also, as you would expect, clicking on the link on the splash page takes you to the click counter screen we created earlier. Notice that now your URL will point to `http://localhost/#!/hello`. You can navigate back and forth to the splash page using the browser's back and next button. #### Live ExampleSee the Pen Mithril Routing Example by Pat Cavit (@tivac) on CodePen.
--- ### XHR Basically, XHR is just a way to talk to a server. Let's change our click counter to make it save data on a server. For the server, we'll use [REM](http://rem-rest-api.herokuapp.com), a mock REST API designed for toy apps like this tutorial. First we create a function that calls `m.request`. The `url` specifies an endpoint that represents a resource, the `method` specifies the type of action we're taking (typically the `PUT` method [upserts](https://en.wiktionary.org/wiki/upsert)), `body` is the payload that we're sending to the endpoint and `withCredentials` means to enable cookies (a requirement for the REM API to work) ```javascript var count = 0 var increment = function() { m.request({ method: "PUT", url: "//rem-rest-api.herokuapp.com/api/tutorial/1", body: {count: count + 1}, withCredentials: true, }) .then(function(data) { count = parseInt(data.count) }) } ``` Calling the increment function [upserts](https://en.wiktionary.org/wiki/upsert) an object `{count: 1}` to the `/api/tutorial/1` endpoint. This endpoint returns an object with the same `count` value that was sent to it. Notice that the `count` variable is only updated after the request completes, and it's updated with the response value from the server now. Let's replace the event handler in the component to call the `increment` function instead of incrementing the `count` variable directly: ```javascript var Hello = { view: function() { return m("main", [ m("h1", {class: "title"}, "My first app"), m("button", {onclick: increment}, count + " clicks"), ]) } } ``` Clicking the button should now update the count. #### Live ExampleSee the Pen Mithril XHR Example by Pat Cavit (@tivac) on CodePen.
--- We covered how to create and update HTML, how to create components, routes for a Single Page Application, and interacted with a server via XHR. This should be enough to get you started writing the frontend for a real application. Now that you are comfortable with the basics of the Mithril API, [be sure to check out the simple application tutorial](simple-application.md), which walks you through building a realistic application.