THT is in early Beta. We welcome contributors & feedback.

How to Create A Basic Web App  (20 minutes)


We assume you already finished the Get Started page.

Where to Put Stuff 

When you run tht new, it will create:

Here are the key directories:

├── Document Root     Static files (images, etc.)
│                         thtApp.php (new)
└── tht               Your THT app files (new)
    ├── pages             Dynamic web pages
    ├── modules           Shared code
    ├── settings          Site configuration
    └── data              Logs, database files, etc.

SecurityYour THT files are hosted outside of the Document Root directory to prevent anyone from viewing their entire contents as plain text in a browser.


The easiest way to add a web page is to create a .tht file in the pages directory.

The file name is always lowerCamelCase.

The URL for each page is automatically located at the dash-case version of the file name.

File Path                     URL

pages/hello.tht               /hello
pages/helloWorld.tht          /hello-world
pages/misc/myOtherPage.tht    /misc/my-other-page


You can create dynamic URLs in your settings/app.jcon file.

Just add an entry to routes, mapping the URL to a file in the pages directory.

Optional parameters can be added in curly braces, but must be an entire sub-path. (e.g. /page/user{id} is not allowed, but /page/{userId} is okay.)

routes: {
    /my-url:            thisPage.tht
    /another/url:       thatOtherPage.tht
    /blog/{articleId}:  blog.tht

ImportantOnly the characters a-z_-./ are allowed in a route. THT will automatically respond with a 404 error page if any other character is present in the URL. Trailing slashes (directory paths) are not allowed.

Route Params

As you will see shortly, you can access the value of a route param with Web.routeParam(paramName).

Creating a Basic Page (Example) 

This example will cover:

Step 1: Add the Route

Most pages don’t need a route, but for this example, we want to include a dynamic color name in the URL.

Add the following route to settings/app.jcon. It contains a param named color.

routes: {

    /colors/{color}:  /colors.tht

    // other routes...

Step 2: Create the Page

Create a new file pages/colors.tht.

Copy and paste the following code:

TipRead through it line by line to see what’s happening. It’s okay if you don’t understand everything at first. Take note of what is unfamiliar and look it up later in the Language Tour.

// THT will automatically call main() when the page loads.
function main() {

    // Get the current color from the URL
    let pageColor = Web.routeParam('color');

    // Output the full HTML document
        title: 'Color Picker',
        body: html(pageColor),
        css: css(),

// List colors in a function so you can easily
// modify it in one place.
function colors() {
    return ['red', 'green', 'blue'];

// Main page content.
// Wrap content in <main> to get correct sizing & margins.
// We are using HTML shortcut tags here.
template html(pageColor) {

    <.colorBar style="background-color: {{ pageColor }}" />

        <h1>> The {{ pageColor.toUpperCaseFirst() }} Page
        :: for (color in colors()) {
            :: let colorName = color.toUpperCaseFirst();
            <li>> <a href='/colors/{{ color }}'>{{ colorName }}</>
        :: }

// Include the THT base stylesheet and add our own styles.
template css() {

    {{ Css.include('base') }}

    li {
        font-size: 2rem;
    .colorBar {
        height: 4rem;
        background-color: #999;

Step 3: Load the Page

Load the page at

Or at http://localhost:8888/colors/red if you are using the test server.

You will see something like this:

The Red Page
  • Red
  • Green
  • Blue

Step 4: Experiment

Try playing around with the code.

For Future Reference