The website handler allows your to create themed web applications in a simple manner.

NOTE New websites can quickly be created by using a project template.

Creating a Website

The following code snippet will start a very basic web application with two pages:

var project = Layout.Create()
                        .Index(Page.From("Home", "Hello World!"))
                        .Add("legal", Page.From("Legal", "This is the legal page"));
    var website = Website.Create()

After starting the project, you can access the web application by entering http://localhost:8080 in the address line of your browser.


The GenHTTP SDK ships with some default themes that can be used with the website handler.

After installing the theme you would like to use, configure and pass a theme instance to the Website builder:

var theme = Theme.Create()
                     .Title("Website Title");
    var website = Website.Create()

Depending on the theme, there will be different features availabe for configuration (such as footer menus or social buttons).

To provide a custom theme, you will need to implement the ITheme interface.

The main component of every theme is the template that is used to embed the generated pages into. The template can be rendered using a templating engine of your choice. For a Scriban-based example, see the template of the Lorahost theme.

Adding Pages

To add your pages to the web application, there are different template languages available to be used: Scriban, Razor and Markdown.

NOTE To build more complex websites, the MVC pattern is recommended.

Create a new HTML file within the tree of your project and mark it either as an embedded resource or as content that will be copied to the output directory of your project. The page can the be added using the appropriate module:

website.Add("shop", ModScriban.Page(Resource.FromFile("Shop.html"))); // or ModRazor, ModMarkdown

This will load the given Scriban template from the specified resource and render it to the requesting client, if http://localhost:8080/shop is called.

You may provide a model used to render your pages based on the current request by providing a factory method:

// within the template, you might use "{{ data.total_items }}" (or "@Model.Data.TotalItems" in Razor) to access your view model
    website.Add("shop", ModScriban.Page<ViewModel<Basket>>(Resource.FromFile("./Shop.html"), LoadBasket));
    public record Basket(int TotalItems);
    private async ValueTask<ViewModel<Basket>> LoadBasket(IRequest request, IHandler handler) 
        var basket = await ...; // load the basket from your data source
        return new ViewModel<Basket>(request, handler, basket);

NOTE View model classes must override GetHashCode() to allow changes to be detected. Using C#'s record will do this for you automatically.

To serve a static page instead of a rendered one, you can use Page.From(Resource.FromFile(...)) to create a page from a given Resource.

Hot Reload

The auto reload module improves the website development experience by automatically reloading the currently shown page when changes are detected. As the change detection regularly polls the website to detect modifications, it should be used in development mode only.



Within your pages, you can access the routing context to generate relative paths to other pages or parts of your web application. Example:

<a href="{{ route 'sitemap.xml' }}">Sitemap</a> <!-- Scriban -->
<a href="@Model.Route("sitemap.xml")">Sitemap</a> <!-- Razor -->

The routing mechanism will automatically find the responsible handler for the requested route within the handler hierarchy and generate an URL that can be used by the browser to navigate to this location.

Some handlers may provide symbolic routes that can be used to access the requested content:

Handler Route Description
Layout {index} The index of the layout (if any)
Layout {fallback} The fallback of the layout (if any)
Website {website} The root of the website
Controller {controller} The root of the controller
Controller {index} The index route of the controller (if any)