Rendering template files
See CSS, JavaScript, Chart.js, Lucide, Bootstrap and static assets.
In this lesson, a page uses a separate HTML template rather than embedding its markup inside a route. The application then serves CSS and JavaScript from a public static directory.
View the frontend example to see the template output and the actual CSS/JavaScript assets.
1. Create a small project
mojara new dashboard web
cd dashboard
Create this application structure:
dashboard/
app.mojo
templates/
dashboard.html
static/
css/
site.css
js/
app.js
2. Write the template file
Create templates/dashboard.html:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{ page_title }}</title>
<link rel="stylesheet" href="/static/css/site.css">
<script defer src="/static/js/app.js"></script>
</head>
<body>
<header><strong>Mojara Dashboard</strong></header>
<main>
<h1>Welcome, {{ name }}!</h1>
<p>This page was rendered from a template file.</p>
<button id="greet" type="button">Say hello</button>
<p id="message" role="status"></p>
</main>
</body>
</html>
{{ page_title }} and {{ name }} mark values supplied when the template is rendered. The link and script elements load static files.
3. Render the template from a route
from mojara import App, Request, Response, render_template
def dashboard(req: Request) -> Response:
var html = render_template(
"dashboard.html",
{"page_title": "My Dashboard", "name": "Amina"},
)
return Response.html(html)
def main() raises:
var app = App()
app.get("/", dashboard)
app.static("/static", directory="static")
app.run(port=8000)
The handler renders dashboard.html using the supplied values. The static mapping makes static/css/site.css available at /static/css/site.css, and likewise for the JavaScript.
Render user data with HTML escaping enabled. Keep private source, configuration, and template files outside the static directory.
4. Add your CSS
Create static/css/site.css:
:root { font-family: system-ui, sans-serif; color: #321a0d; }
body { margin: 0; background: #fff9ee; }
header { padding: 16px 24px; background: #f27818; color: white; }
main { max-width: 720px; margin: 48px auto; padding: 24px; }
h1 { color: #b94a0d; }
button { background: #e8691e; color: white; border: 0; padding: 12px 18px; cursor: pointer; }
button:hover { background: #c34f13; }
This stylesheet controls the background, header, typography, layout and button style without changing the Mojo route.
5. Add JavaScript
Create static/js/app.js:
document.querySelector("#greet").addEventListener("click", () => {
document.querySelector("#message").textContent = "Hello from JavaScript!";
});
The defer attribute causes the script to execute after the HTML is parsed. Clicking Say hello updates the page without reloading.
6. Run and inspect
mojara dev
Open the address printed by Mojara, then check the static resources:
curl -i http://127.0.0.1:8000/
curl -i http://127.0.0.1:8000/static/css/site.css
curl -i http://127.0.0.1:8000/static/js/app.js
The first request returns HTML; the second and third return CSS and JavaScript. If your server uses another port, substitute that port.