Live demo
Hello, world!
This site is written in PHX, a language for the web that keeps the feel of PHP while the compiler guarantees type safety and safe output. Every page runs on the server as you load it, and shows its own source at the bottom.
Escaping
Type <script> anywhere: output is escaped for where it lands — text, attribute, URL or
script — and the unsafe spots do not compile.
Message board
SQLite with sql"..." literals, automatic CSRF checks, sessions, flash messages and rate
limiting.
Two-factor codes
TOTP secrets, a QR code for your authenticator app and replay-safe verification, all built in.
JSON API
Endpoints that return JSON, called from a script that gets its CSP nonce automatically.
Source of this page
Read from disk by lib/source.phx as the page is served.
public/index.phx
<?phx
import std.http.request;
import lib.source.sources;
$name = (request()->query("name") ?? "")->trim();
if ($name->isEmpty() || $name->len() > 40) {
$name = "world";
}
$body = render("views/home.phx.html", name: $name);
echo render(
"views/layout.phx.html",
title: "Live demo",
path: "/",
body: $body,
files: sources(["public/index.phx", "views/home.phx.html"]),
);
views/home.phx.html
<?phx params(string $name) ?>
<section class="hero">
<p class="eyebrow">Live demo</p>
<h1>Hello, <?= $name ?>!</h1>
<p class="lead">This site is written in <a href="https://phx-lang.org">PHX</a>, a language for the web that keeps
the feel of PHP while the compiler guarantees type safety and safe output. Every page runs on the server as you
load it, and shows its own source at the bottom.</p>
<form method="get" action="/" class="inline">
<label for="name">Your name</label>
<input id="name" name="name" value="<?= $name == "world" ? "" : $name ?>" maxlength="40" autocomplete="off"
placeholder="Try <b>you</b>">
<button>Greet me</button>
</form>
</section>
<div class="grid">
<a class="card" href="/escape">
<h2>Escaping</h2>
<p>Type <code><script></code> anywhere: output is escaped for where it lands — text, attribute, URL or
script — and the unsafe spots do not compile.</p>
</a>
<a class="card" href="/board">
<h2>Message board</h2>
<p>SQLite with <code>sql"..."</code> literals, automatic CSRF checks, sessions, flash messages and rate
limiting.</p>
</a>
<a class="card" href="/totp">
<h2>Two-factor codes</h2>
<p>TOTP secrets, a QR code for your authenticator app and replay-safe verification, all built in.</p>
</a>
<a class="card" href="/api">
<h2>JSON API</h2>
<p>Endpoints that return JSON, called from a script that gets its CSP nonce automatically.</p>
</a>
</div>