Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 36 additions & 2 deletions content/changelog/livetemplate.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
title: "Changelog"
source_repo: "https://github.com/livetemplate/livetemplate"
source_path: "CHANGELOG.md"
source_ref: "v0.23.0"
source_commit: "8294ce439a46a6a1f92e2a77b8a4978c9e526cc6"
source_ref: "v0.25.0"
source_commit: "de4c80d83cf8a18cd629e515904517b2889f3e74"
---

# Changelog
Expand All @@ -13,6 +13,40 @@ All notable changes to LiveTemplate will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [v0.25.0] - 2026-08-15

### Changes

- docs: rewrite the guide and reference openers (#533) (c922f83a)
- test(census): pin associated-template coverage for separately-parsed sources (#473) (be26cab3)
- feat(census): advertise template lvt-* attributes so unhandled ones can warn (#473) (6f1bb1c1)



## [v0.24.0] - 2026-08-03

### Fixed

- **`ctx.GetBool()` now reads a checkbox on both transports.** It accepted
`bool` and the strings `"true"`/`"false"` — and neither is what a checkbox
actually sends. Over the WebSocket the client serializes a lone checkbox as
`input.checked` (a bool; the `value` attribute is discarded), which worked.
With the client not running, the browser posts the box's `value` attribute —
`"1"`, or `"on"` when it has none — and `GetBool` read `false` for a ticked
box. Since `GetString` does not accept a bool either, no accessor read a
checkbox correctly on both paths, so a handler could not be written once and
stay correct across them — the opposite of what the `progressive_enhancement`
capability promises. `GetBoolOk` now accepts `"1"`/`"on"`/`"true"` as true and
`"0"`/`"off"`/`"false"` as false (case-insensitive), plus numbers in every
width `GetFloatOk` accepts — a numeric-looking hidden input is what the
client's `parseValue()` turns into a number before sending it. `NaN` and
`±Inf` are rejected rather than read as true, and a string that is neither
boolean-shaped nor `1`/`0` (say `"2"`) stays unrecognized rather than being
guessed at. An absent key still reads `(false, false)` — that is how an
unchecked box arrives on the POST path, where it is not submitted at all.
`docs/proposals/patterns.md` has documented `ctx.GetBool()` as the way to read
checkbox state all along.

## [v0.23.0] - 2026-08-02

### Added
Expand Down
8 changes: 4 additions & 4 deletions content/contributing/livetemplate.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
title: "Contributing to LiveTemplate Core Library"
source_repo: "https://github.com/livetemplate/livetemplate"
source_path: "CONTRIBUTING.md"
source_ref: "v0.23.0"
source_commit: "8294ce439a46a6a1f92e2a77b8a4978c9e526cc6"
source_ref: "v0.25.0"
source_commit: "de4c80d83cf8a18cd629e515904517b2889f3e74"
---

# Contributing to LiveTemplate Core Library
Expand Down Expand Up @@ -226,7 +226,7 @@ livetemplate/
└── scripts/ # Development scripts
```

For the complete file-by-file map with line counts and dependencies, see [docs/design/CODE_STRUCTURE.md](https://github.com/livetemplate/livetemplate/blob/v0.23.0/docs/design/CODE_STRUCTURE.md).
For the complete file-by-file map with line counts and dependencies, see [docs/design/CODE_STRUCTURE.md](https://github.com/livetemplate/livetemplate/blob/v0.25.0/docs/design/CODE_STRUCTURE.md).

**Note:** The client library, CLI tool, and examples are now in separate repositories:
- Client: https://github.com/livetemplate/client
Expand Down Expand Up @@ -528,7 +528,7 @@ Look for issues labeled `good first issue` - these are:
### Learning the Codebase

1. **Start with the Contributor Walkthrough**
- [`docs/guides/new-contributor-walkthrough.md`](https://github.com/livetemplate/livetemplate/blob/v0.23.0/docs/guides/new-contributor-walkthrough.md) - **START HERE!** Comprehensive guide to the 5-phase architecture with links to all code and tests
- [`docs/guides/new-contributor-walkthrough.md`](https://github.com/livetemplate/livetemplate/blob/v0.25.0/docs/guides/new-contributor-walkthrough.md) - **START HERE!** Comprehensive guide to the 5-phase architecture with links to all code and tests

2. **Read the architecture docs**
- `CLAUDE.md` - Development guidelines
Expand Down
6 changes: 3 additions & 3 deletions content/guides/ephemeral-components.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@
title: "Ephemeral Components Guide"
source_repo: "https://github.com/livetemplate/livetemplate"
source_path: "docs/guides/ephemeral-components.md"
source_ref: "v0.23.0"
source_commit: "8294ce439a46a6a1f92e2a77b8a4978c9e526cc6"
source_ref: "v0.25.0"
source_commit: "de4c80d83cf8a18cd629e515904517b2889f3e74"
---

# Ephemeral Components Guide

Ephemeral components are UI elements that appear briefly, deliver information, and then disappear — toasts, banners, alerts, and confirmation flashes. They have no meaningful persistent state from the server's perspective.

This guide explains why these components should live **entirely on the client** and how to implement that pattern correctly.
They belong **entirely on the client**. Below is why, and how to build them that way.

---

Expand Down
10 changes: 5 additions & 5 deletions content/guides/observability.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@
title: "LiveTemplate Observability Guide"
source_repo: "https://github.com/livetemplate/livetemplate"
source_path: "docs/guides/OBSERVABILITY.md"
source_ref: "v0.23.0"
source_commit: "8294ce439a46a6a1f92e2a77b8a4978c9e526cc6"
source_ref: "v0.25.0"
source_commit: "de4c80d83cf8a18cd629e515904517b2889f3e74"
---

# LiveTemplate Observability Guide

## Overview

LiveTemplate provides production-ready observability through two complementary systems:
Observability comes from two systems that work together:

- **Structured logging** via Go's standard `log/slog` package (used directly throughout the codebase)
- **Operational metrics** via `internal/observe` package (counters, gauges, histograms with Prometheus export)
Expand Down Expand Up @@ -409,6 +409,6 @@ func RequestIDMiddleware(next http.Handler) http.Handler {

## Related Documentation

- [ARCHITECTURE.md](https://github.com/livetemplate/livetemplate/blob/v0.23.0/docs/design/ARCHITECTURE.md) - System architecture overview
- [internal/observe/](https://github.com/livetemplate/livetemplate/tree/v0.23.0/internal/observe) - Package implementation
- [ARCHITECTURE.md](https://github.com/livetemplate/livetemplate/blob/v0.25.0/docs/design/ARCHITECTURE.md) - System architecture overview
- [internal/observe/](https://github.com/livetemplate/livetemplate/tree/v0.25.0/internal/observe) - Package implementation
- [Go slog documentation](https://pkg.go.dev/log/slog) - Standard library reference
6 changes: 3 additions & 3 deletions content/guides/progressive-complexity.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
title: "Progressive Complexity Guide"
source_repo: "https://github.com/livetemplate/livetemplate"
source_path: "docs/guides/progressive-complexity.md"
source_ref: "v0.23.0"
source_commit: "8294ce439a46a6a1f92e2a77b8a4978c9e526cc6"
source_ref: "v0.25.0"
source_commit: "de4c80d83cf8a18cd629e515904517b2889f3e74"
---

# Progressive Complexity Guide
Expand All @@ -13,7 +13,7 @@ LiveTemplate follows a two-tier progressive complexity model:
- **Tier 1: Standard HTML** — forms, buttons, links, dialogs, validation. No custom attributes.
- **Tier 2: `lvt-*` Attributes** — debounce, reactive DOM, lifecycle hooks. Only when HTML can't express it.

This guide walks through Tier 1 from the simplest case to full-featured applications.
What follows is Tier 1, from the simplest case up to a full application.

---

Expand Down
18 changes: 9 additions & 9 deletions content/guides/scaling.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
title: "LiveTemplate Scaling Guide"
source_repo: "https://github.com/livetemplate/livetemplate"
source_path: "docs/guides/SCALING.md"
source_ref: "v0.23.0"
source_commit: "8294ce439a46a6a1f92e2a77b8a4978c9e526cc6"
source_ref: "v0.25.0"
source_commit: "de4c80d83cf8a18cd629e515904517b2889f3e74"
---

# LiveTemplate Scaling Guide
Expand All @@ -16,7 +16,7 @@ source_commit: "8294ce439a46a6a1f92e2a77b8a4978c9e526cc6"

## Overview

This guide covers scaling LiveTemplate applications from **single-host prototypes** to **production systems handling millions of concurrent WebSocket connections**.
Scaling a LiveTemplate application, from a **single-host prototype** up to **millions of concurrent WebSocket connections**.

---

Expand Down Expand Up @@ -199,7 +199,7 @@ handler := livetemplate.Mount(rootStore,

## Migration Guide: Memory to Redis Session Store

This guide walks through migrating from in-memory session storage to Redis-backed storage for horizontal scaling.
Moving session storage from memory to Redis, so you can run more than one host.

### When to Migrate

Expand Down Expand Up @@ -537,7 +537,7 @@ spec:
2. **Readiness Probe** (`/health/ready`):
- **Always use** for all deployments
- Should check external dependencies (Redis, DB)
- Allows application to temporarily become "not ready" without restart
- Lets the application go "not ready" for a while without a restart
- Example: Redis connection lost → readiness fails → no new connections → Redis recovers → readiness passes → traffic resumes

3. **Startup Probe** (`/health/live`):
Expand Down Expand Up @@ -625,7 +625,7 @@ func setupHealthChecks(sessionStore *livetemplate.RedisSessionStore, db *sql.DB)

**Advanced Database Health Checks:**

For production deployments with databases, implement comprehensive health checks that verify not just connectivity, but also connection pool health and query performance.
In production with a database, check more than connectivity: the connection pool and query latency fail separately, and each one takes the app down on its own.

```go
package main
Expand Down Expand Up @@ -1407,7 +1407,7 @@ See [session.md](/reference/session) for the Session API guide on server-initiat

## Capacity Planning

This section provides formulas and guidelines for estimating resource requirements based on your expected load.
Formulas for estimating what a given load will cost you in resources.

### Memory Estimation

Expand Down Expand Up @@ -1869,8 +1869,8 @@ redis_connected_clients{instance="redis1"} > 9000 # 90% of Redis max clients

## Next Steps

- **Roadmap:** See [ROADMAP.md](https://github.com/livetemplate/livetemplate/blob/v0.23.0/ROADMAP.md) for upcoming scaling features
- **Architecture:** See [ARCHITECTURE.md](https://github.com/livetemplate/livetemplate/blob/v0.23.0/docs/design/ARCHITECTURE.md) for system design
- **Roadmap:** See [ROADMAP.md](https://github.com/livetemplate/livetemplate/blob/v0.25.0/ROADMAP.md) for upcoming scaling features
- **Architecture:** See [ARCHITECTURE.md](https://github.com/livetemplate/livetemplate/blob/v0.25.0/docs/design/ARCHITECTURE.md) for system design

---

Expand Down
12 changes: 6 additions & 6 deletions content/guides/standard-html-reactivity.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@
title: "Standard HTML Reactivity"
source_repo: "https://github.com/livetemplate/livetemplate"
source_path: "docs/guides/standard-html-reactivity.md"
source_ref: "v0.23.0"
source_commit: "8294ce439a46a6a1f92e2a77b8a4978c9e526cc6"
source_ref: "v0.25.0"
source_commit: "de4c80d83cf8a18cd629e515904517b2889f3e74"
---

# Standard HTML Reactivity

LiveTemplate makes standard HTML reactive by default. A plain `<form method="POST">` with `<button name="add">` is interactive at every transport level — no framework-specific attributes required. This guide explains how it works, how it compares to other frameworks, and the tradeoffs involved.
LiveTemplate makes standard HTML reactive by default. A plain `<form method="POST">` with `<button name="add">` is interactive at every transport level — no framework-specific attributes required. How it works, how it compares to the alternatives, and what it costs you.

> **Recent reinforcement:** As of client v0.8.38, the TypeScript client and the generated templates went through a deliberate "attribute reduction" pass that removed `lvt-*` attributes from anything HTML can already express. Tier 1 standard HTML is now the default everywhere; Tier 2 attributes are reserved for behaviors HTML genuinely cannot express (timing, keyboard shortcuts, reactive DOM).
> **Recent reinforcement:** As of client v0.8.38, the TypeScript client and the generated templates went through a deliberate "attribute reduction" pass that removed `lvt-*` attributes from anything HTML can already express. Tier 1 standard HTML is now the default everywhere; Tier 2 attributes are reserved for behaviors HTML cannot express (timing, keyboard shortcuts, reactive DOM).

---

Expand Down Expand Up @@ -151,7 +151,7 @@ LiveTemplate is inspired by Phoenix LiveView but does not yet cover its full fea
| **Stateful Components** | `LiveComponent` with own lifecycle | Stateless templates only | `{{template}}` invocations work but have no component-level state or event handling. |
| **Streams** | `stream/3` for large lists | Not yet | LiveView streams handle large/infinite lists without keeping all items in server memory. Streaming-range rendering (PRs #366/#368/#369/#370) is the latest step toward this. |
| **JS Commands** | `JS.push`, `JS.toggle`, `JS.show` | Partial | [`lvt-*` reactive attributes](/reference/client-attributes) cover common cases (disable, add/remove class, set attribute) but aren't as composable as LiveView's server-defined JS chains. |
| **Client Hooks** | `phx-hook` lifecycle callbacks | Proposed | [`lvt-hook` proposal](https://github.com/livetemplate/livetemplate/blob/v0.23.0/docs/proposals/lifecycle-hooks-proposal.md) covers third-party JS library integration; not yet shipped. |
| **Client Hooks** | `phx-hook` lifecycle callbacks | Proposed | [`lvt-hook` proposal](https://github.com/livetemplate/livetemplate/blob/v0.25.0/docs/proposals/lifecycle-hooks-proposal.md) covers third-party JS library integration; not yet shipped. |
| **Presence** | `Phoenix.Presence` | Not built-in | Can be built on LiveTemplate's session stores; requires manual implementation. |
| **Testing Helpers** | `live/2`, `render_click/3` | Minimal | `AssertPureState` exists; no view-level test DSL. Browser tests use chromedp. |
| **Form Recovery** | Automatic on reconnect | Partial — `lvt-form:preserve` retains specific fields across re-renders | Full automatic recovery on WS reconnection is not yet built in. |
Expand Down Expand Up @@ -191,7 +191,7 @@ See the [Progressive Complexity Guide](/guides/progressive-complexity) for the c
**Advantages of LiveTemplate's approach:**
- Standard HTML works at all transport levels (no-JS, fetch, WebSocket)
- No framework vocabulary to learn for common interactions
- Progressive enhancement works out of the box
- Progressive enhancement needs no extra wiring
- Less markup to write

**Disadvantages:**
Expand Down
19 changes: 16 additions & 3 deletions content/reference/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
title: "Go Library API Reference"
source_repo: "https://github.com/livetemplate/livetemplate"
source_path: "docs/references/api-reference.md"
source_ref: "v0.23.0"
source_commit: "8294ce439a46a6a1f92e2a77b8a4978c9e526cc6"
source_ref: "v0.25.0"
source_commit: "de4c80d83cf8a18cd629e515904517b2889f3e74"
---

# Go Library API Reference
Expand Down Expand Up @@ -278,8 +278,21 @@ Primarily useful in tests. In production, Context is created internally and pass
| `GetString` | `(key string) string` | Get a string value from action data |
| `GetInt` | `(key string) int` | Get an integer value |
| `GetFloat` | `(key string) float64` | Get a float value |
| `GetBool` | `(key string) bool` | Get a boolean value |
| `GetBool` | `(key string) bool` | Get a boolean value — this is the accessor for checkbox state (see below) |
| `Has` | `(key string) bool` | Check if a key exists in action data |

**Reading a checkbox.** Use `GetBool`, not `GetString`. The same box reaches the
handler as a different type depending on how the form was submitted: over the
WebSocket the client sends `input.checked` (a bool — the `value` attribute is
discarded), while a plain POST carries the `value` attribute as a string
(`"1"`, or `"on"` when the input has no `value`). An unchecked box is not
posted at all, so the key is simply absent. `GetBool` accepts all of these and
reads an absent key as `false`, which is what lets one handler serve both
transports:

```go
enabled := ctx.GetBool("notifications") // correct with and without JS
```
| `Get` | `(key string) interface{}` | Get a raw value |
| `Bind` | `(v interface{}) error` | Unmarshal action data into a struct |
| `BindAndValidate` | `(v interface{}, validate *validator.Validate) error` | Bind and validate in one step |
Expand Down
6 changes: 3 additions & 3 deletions content/reference/authentication.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@
title: "Authentication Reference"
source_repo: "https://github.com/livetemplate/livetemplate"
source_path: "docs/references/authentication.md"
source_ref: "v0.23.0"
source_commit: "8294ce439a46a6a1f92e2a77b8a4978c9e526cc6"
source_ref: "v0.25.0"
source_commit: "de4c80d83cf8a18cd629e515904517b2889f3e74"
---

# Authentication Reference

Authentication in LiveTemplate handles two key responsibilities: **user identification** and **session grouping**. This guide covers the Authenticator interface, built-in implementations, HTTP methods for auth flows, and patterns for custom authentication.
Authentication in LiveTemplate handles two key responsibilities: **user identification** and **session grouping**. Below: the Authenticator interface, the built-in implementations, the HTTP methods for auth flows, and how to write your own.

## Overview

Expand Down
Loading
Loading