Skip to content
On this page

elm-land.json

Overview

The purpose of the elm-land.json file is to provide one place to configure your Elm Land application. Elm Land works out-of-the-box with zero-configuration, but more advanced web applications will customize some of the options described below.

For reference, here is the default elm-land.json file that is created with every new Elm Land project created via the CLI:

json
{
  "app": {
    "elm": {
      "development": { "debugger": true },
      "production": { "debugger": false }
    },
    "env": [],
    "html": {
      "attributes": {
        "html": { "lang": "en" },
        "head": {}
      },
      "title": "Elm Land",
      "meta": [
        { "charset": "UTF-8" },
        { "http-equiv": "X-UA-Compatible", "content": "IE=edge" },
        { "name": "viewport", "content": "width=device-width, initial-scale=1.0" }
      ],
      "link": [],
      "script": []
    },
    "router": {
      "useHashRouting": false
    }
  }
}
{
  "app": {
    "elm": {
      "development": { "debugger": true },
      "production": { "debugger": false }
    },
    "env": [],
    "html": {
      "attributes": {
        "html": { "lang": "en" },
        "head": {}
      },
      "title": "Elm Land",
      "meta": [
        { "charset": "UTF-8" },
        { "http-equiv": "X-UA-Compatible", "content": "IE=edge" },
        { "name": "viewport", "content": "width=device-width, initial-scale=1.0" }
      ],
      "link": [],
      "script": []
    },
    "router": {
      "useHashRouting": false
    }
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

There are no hidden defaults here, everything in this JSON file is explicit defined to prevent unexpected behavior. In the next version of Elm Land, missing fields will prevent Elm Land commands from working at all ( but we'll provide you with a helpful error message about what's missing! )

Each section below will give you a detailed look into the purpose and type of each setting

app.elm

TYPE

elm
{ development : { debugger : Bool }
, production :  { debugger : Bool }
}
{ development : { debugger : Bool }
, production :  { debugger : Bool }
}
1
2
3

This section specifies options that you would normally send the Elm compiler. For convenience, this is split into the two fields below, so you can control each independently.

app.elm.development

TYPE

elm
{ debugger : Bool }
{ debugger : Bool }
1

This defines the Elm compiler options that will be used during elm-land server.

jsonc
{
  "app": {
    "elm": {
      "development": { "debugger": true },
      // ...
    }
    // ...
  }
}
{
  "app": {
    "elm": {
      "development": { "debugger": true },
      // ...
    }
    // ...
  }
}
1
2
3
4
5
6
7
8
9
  • By specifying true, you will enable the Elm debugger in the bottom-right corner of your web browser.
  • By specifying false, the Elm debugger will be disabled, and the icon will no longer be visible.

app.elm.production

TYPE

elm
{ debugger : Bool }
{ debugger : Bool }
1

This defines the Elm compiler options that will be used during elm-land build.

jsonc
{
  "app": {
    "elm": {
      // ...
      "production": { "debugger": false },
    }
    // ...
  }
}
{
  "app": {
    "elm": {
      // ...
      "production": { "debugger": false },
    }
    // ...
  }
}
1
2
3
4
5
6
7
8
9
  • By specifying true, you will enable the Elm debugger in the bottom-right corner of your web browser.
  • By specifying false, the Elm debugger will be disabled, and the icon will no longer be visible.

app.env

TYPE

elm
List String
List String
1

Elm Land allows users to access "environment variables". These variables are commonly used to help determine if an application is running in production or development.

For security reasons, all environment variables are hidden from your Elm Land application by default. For example, even if you run NODE_ENV=production elm-land server, your Elm application still will not have access to the NODE_ENV variable.

This is because these values are fully visible to anyone visiting your website. For that reason, you should never expose any private secrets via environment variables.

When you want to share an environment variable with your app, the app.env field is the one spot check:

jsonc
{
  "app": {
    // ...
    "env": [ "NODE_ENV", "PUBLIC_GITHUB_TOKEN" ],
    // ...
  }
}
{
  "app": {
    // ...
    "env": [ "NODE_ENV", "PUBLIC_GITHUB_TOKEN" ],
    // ...
  }
}
1
2
3
4
5
6
7

In the Working with JavaScript guide, you'll learn how to use src/interop.js to access the environment variables allowed by this file.

Auditing made easy!

If you ever need to audit which variables are exposed to your frontend, this one field in your elm-land.json file is the only place you need to check.

app.html

TYPE

elm
{ attributes : 
    { html : Dict String String 
    , head : Dict String String
    }
, title : String
, meta : List (Dict String String)
, link : List (Dict String String)
, script : List (Dict String String)
}
{ attributes : 
    { html : Dict String String 
    , head : Dict String String
    }
, title : String
, meta : List (Dict String String)
, link : List (Dict String String)
, script : List (Dict String String)
}
1
2
3
4
5
6
7
8
9

Because Elm Land generates "single-page apps", all requests are directed to a single index.html file. This section specifies how that index.html file should be generated, and will apply to every page.

Here is the general shape of that HTML template to give you an overview:

html
<!DOCTYPE html>
  <html {{attributes.html}} >
  <head {{attributes.head}} >
    <title>{{title}}</title>
    {{ meta tags }}
    {{ link tags }}
    {{ script tags }}
  </head>
  <body>
    <!-- Elm Land's entrypoint -->
  </body>
</html>
<!DOCTYPE html>
  <html {{attributes.html}} >
  <head {{attributes.head}} >
    <title>{{title}}</title>
    {{ meta tags }}
    {{ link tags }}
    {{ script tags }}
  </head>
  <body>
    <!-- Elm Land's entrypoint -->
  </body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12

TIP

Elm Land is designed for web applications, usually behind a sign-in screen. For that reason, only a single HTML page is currently supported.

If you'd like to use Elm, but for a website that needs HTML tags to be specified on a per-page basis, other projects like Elm Pages are better suited for your use-case.

app.html.attributes

TYPE

elm
{ html : Dict String String 
, head : Dict String String
}
{ html : Dict String String 
, head : Dict String String
}
1
2
3

This section allows users to specify HTML attributes on the generated <html>, <head>, and <body> tags. Each set of attributes can be represented with a JSON object, where the object's key is the HTML attribute's name, and the value is the attribute's value.

app.html.attributes.html

TYPE

elm
Dict String String
Dict String String
1

Specifies which HTML attributes should render on the <html> tag. If the object is empty, no attributes will be added.

EXAMPLE

Input: elm-land.json

jsonc
{
  "app": {
    // ...
    "html": {
      "attributes": {
        "html": { "lang": "en", "elm": "very-cool" },
        // ...
      },
      // ...
    }
  }
}
{
  "app": {
    // ...
    "html": {
      "attributes": {
        "html": { "lang": "en", "elm": "very-cool" },
        // ...
      },
      // ...
    }
  }
}
1
2
3
4
5
6
7
8
9
10
11
12

Output: index.html

html
<!DOCTYPE>
<html lang="en" elm="very-cool">
  <!-- ... -->
</html>
<!DOCTYPE>
<html lang="en" elm="very-cool">
  <!-- ... -->
</html>
1
2
3
4

app.html.attributes.head

TYPE

elm
Dict String String
Dict String String
1

Specifies which HTML attributes should render on the <head> tag. If the object is empty, no attributes will be added.

EXAMPLE

Input: elm-land.json

jsonc
{
  "app": {
    // ...
    "html": {
      "attributes": {
        // ...
        "head": { "color": "red", "fruit": "apple" },
        // ...
      },
      // ...
    }
  }
}
{
  "app": {
    // ...
    "html": {
      "attributes": {
        // ...
        "head": { "color": "red", "fruit": "apple" },
        // ...
      },
      // ...
    }
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13

Output: index.html

html
<!DOCTYPE>
<html lang="en">
  <head color="red" fruit="apple">
    <!-- ... -->
  </head>
  <!-- ... -->
</html>
<!DOCTYPE>
<html lang="en">
  <head color="red" fruit="apple">
    <!-- ... -->
  </head>
  <!-- ... -->
</html>
1
2
3
4
5
6
7

app.html.title

TYPE

elm
String
String
1

Before your Elm application loads, the HTML file will have a default title. This title will appear in the top tab of the web browser, but only when JavaScript is disabled or if the Elm Land application hasn't run yet.

Once the app is ready, Elm Land will use the tab title defined by the page you are currently on, which can be modified by that page's layout. Check out Pages and routes to better understand the title property.

EXAMPLE

Input: elm-land.json

jsonc
{
  "app": {
    // ...
    "html": {
      // ...
      "title": "My Cool App!",
      // ...
    }
  }
}
{
  "app": {
    // ...
    "html": {
      // ...
      "title": "My Cool App!",
      // ...
    }
  }
}
1
2
3
4
5
6
7
8
9
10

Output: index.html

html
<!DOCTYPE>
<html lang="en">
  <body>
    <title>My Cool App!</title>
    <!-- ... -->
  </body>
    <!-- ... -->
</html>
<!DOCTYPE>
<html lang="en">
  <body>
    <title>My Cool App!</title>
    <!-- ... -->
  </body>
    <!-- ... -->
</html>
1
2
3
4
5
6
7
8

app.html.meta

TYPE

elm
List (Dict String String)
List (Dict String String)
1

For each item in the list, a <meta> tag will be rendered within the <head> tag. Each item in the list represents the attributes that should be rendered with the new HTML element.

EXAMPLE

Input: elm-land.json

jsonc
{
  "app": {
    // ...
    "html": {
      // ...
      "meta": [
        { "charset": "UTF-8" },
        { "name": "description", "content": "This app is 2 cool 4 me." },
      ],
      // ...
    }
  }
}
{
  "app": {
    // ...
    "html": {
      // ...
      "meta": [
        { "charset": "UTF-8" },
        { "name": "description", "content": "This app is 2 cool 4 me." },
      ],
      // ...
    }
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13

Output: index.html

html
<!DOCTYPE html>
<html>
  <head>
    <!-- ... -->
    <meta charset="UTF-8">
    <meta name="description" content="This app is 2 cool 4 me.">
    <!-- ... -->
  </head>
  <!-- ... -->
</html>
<!DOCTYPE html>
<html>
  <head>
    <!-- ... -->
    <meta charset="UTF-8">
    <meta name="description" content="This app is 2 cool 4 me.">
    <!-- ... -->
  </head>
  <!-- ... -->
</html>
1
2
3
4
5
6
7
8
9
10

TYPE

elm
List (Dict String String)
List (Dict String String)
1

For each item in the list, a <link> tag will be rendered within the <head> tag. Each item in the list represents the attributes that should be rendered with the new HTML element.

Feel free to visit the guide on Assets and static files to understand how to reference local icons, images, and CSS from the ./static folder.

EXAMPLE

Input: elm-land.json

jsonc
{
  "app": {
    // ...
    "html": {
      // ...
      "link": [
        { "rel": "icon", "type": "image/png", "href": "/favicon.png" },
        { "rel": "stylesheet", "href": "/main.css" }
      ],
      // ...
    }
  }
}
{
  "app": {
    // ...
    "html": {
      // ...
      "link": [
        { "rel": "icon", "type": "image/png", "href": "/favicon.png" },
        { "rel": "stylesheet", "href": "/main.css" }
      ],
      // ...
    }
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13

Output: index.html

html
<!DOCTYPE html>
<html>
  <head>
    <!-- ... -->
    <link rel="icon" type="image/png" href="/favicon.png">
    <link rel="stylesheet" href="/main.css">
    <!-- ... -->
  </head>
  <!-- ... -->
</html>
<!DOCTYPE html>
<html>
  <head>
    <!-- ... -->
    <link rel="icon" type="image/png" href="/favicon.png">
    <link rel="stylesheet" href="/main.css">
    <!-- ... -->
  </head>
  <!-- ... -->
</html>
1
2
3
4
5
6
7
8
9
10

app.html.script

TYPE

elm
List (Dict String String)
List (Dict String String)
1

For each item in the list, a <script> tag will be rendered within the <head> tag. Each item in the list represents the attributes that should be rendered with the new HTML element.

EXAMPLE

Input: elm-land.json

jsonc
{
  "app": {
    // ...
    "html": {
      // ...
      "script": [
        { "src": "https://code.jquery.com/jquery-3.6.1.min.js" }
      ]
    }
  }
}
{
  "app": {
    // ...
    "html": {
      // ...
      "script": [
        { "src": "https://code.jquery.com/jquery-3.6.1.min.js" }
      ]
    }
  }
}
1
2
3
4
5
6
7
8
9
10
11

Output: index.html

html
<!DOCTYPE html>
<html>
  <head>
    <!-- ... -->
    <script src="https://code.jquery.com/jquery-3.6.1.min.js"></script>
  </head>
  <!-- ... -->
</html>
<!DOCTYPE html>
<html>
  <head>
    <!-- ... -->
    <script src="https://code.jquery.com/jquery-3.6.1.min.js"></script>
  </head>
  <!-- ... -->
</html>
1
2
3
4
5
6
7
8

app.router

TYPE

elm
{ useHashRouting : Bool }
{ useHashRouting : Bool }
1

These are settings specific to how Elm Land deals with URLs and routes. For now, that's just enabling support for Hash-based URLs for folks with hosting constraints.

app.router.useHashRouting

TYPE

elm
Bool
Bool
1

Some hosting environments don't easily support standard URL path routing. For that reason, we've added an option for users to have Routes use URLs with /#/ prefix.

Hash-based routing still supports query parameters, fragments, and everything else the standard Elm Land routing uses.

Using Route.Path.toString will automatically render the correct URL, depending on the setting.

When useHashRouting is false

Standard web application behavior:

Route.Path.Home_ ....................... /
Route.Path.SignIn ...................... /sign-in
Route.Path.Users ....................... /users
Route.Path.Users_Id_ { id = "123" } .... /users/123
Route.Path.Home_ ....................... /
Route.Path.SignIn ...................... /sign-in
Route.Path.Users ....................... /users
Route.Path.Users_Id_ { id = "123" } .... /users/123
1
2
3
4

When useHashRouting is true

Legacy hash-based URL prefixes will be applied.

Route.Path.Home_ ....................... /#/
Route.Path.SignIn ...................... /#/sign-in
Route.Path.Users ....................... /#/users
Route.Path.Users_Id_ { id = "123" } .... /#/users/123
Route.Path.Home_ ....................... /#/
Route.Path.SignIn ...................... /#/sign-in
Route.Path.Users ....................... /#/users
Route.Path.Users_Id_ { id = "123" } .... /#/users/123
1
2
3
4

Made for you with ❤️