Basic HTML construction with WebSharper

Joel Bjornson

Joel Bjornson

Dec 10, 2009

Reading time:

3 mins

Share via:

Regardless the level of sophistication of a web framework, it boils down to the task of generating HTML to be rendered on the client. Therefore I think basic HTML construction is one of the most important things to get right. Plenty of approaches exist, among others:

  • Writing plain HTML
  • Using server side components to be translated into HTML
  • Using XML based markup languages
  • Using JavaScript to generate HTML dynamically

In my opinion, neither of these alternatives are completely satisfactory, either because they are not powerful enough, don't compose well, requires an overhead of syntax or lack type safety. Let's have a quick look at the WebSharper approach. Below is an example of how to construct an HTML node using combinators from the HTML module.

[<JavaScript>]
let MyBook : Element =
    Div [Class "Book"] -< [
        H1 ["The Picture of Dorian Gray"]
        P ["In this book..."]
    ]

When compiled with WebSharper, this translates to a JavaScript function for building up the corresponding DOM nodes. Creating reusable templates comes at a very low cost. They are simply defined programatically as functions from a set of parameters to a value of type Element:

[<JavaScript>]
let ShowBook (header: string) (body: Element) : Element =        
    Div [Class "Book"] -< [
        H1 [header]
        P [body]
    ]

and naturally may be composed with other HTML generating functions:

[<JavaScript>]
let Content =
    Body [
        H1 ["My Books"]
        P [
            ShowBook "The Picture of Dorian Gray" (Span ["..."])
            ShowBook "Bleak House " (Span ["..."])
        ]
    ]

Since everything is pure F#, they may also be intermixed with standard F# functions. Here is an example of using Seq.map for applying ShowBook to a sequence of Book elements.

[<JavaScript>]
let Content2 : Element =
    Body [
        H1 ["My Books"]
        P (
            AllBooks()
            |> Seq.map (fun b ->
                ShowBook b.Title b.Description
            )
        )
    ]

Read more from

Can’t find what you were looking for? Drop us a line.

Joel Bjornson
Found a typo?

This blog post is hosted on GitHub here. Feel free to file a ticket or send a PR.

Newsletter

We will not spam you or give your details to anyone.