palinxdocs

State and clicks

Palinx state lives in signals. When a signal changes, the parts of the page that read it update.

Add a counter

src/routes/index.route.ts (changes since step 4)
 // There is no index.ts any more. `px dev` starts the server, and it finds
 // this page because the file lives in src/routes/.
-import { Route, html } from "@palinx/core";
+import { Route, html, signal } from "@palinx/core";
 
 export default class Home extends Route {
+  private count = signal(0);
+
   render() {
     return html`
       <h1>hello</h1>
+      <p>Clicked ${this.count()} times</p>
+      <button @click=${() => this.count.set(this.count() + 1)}>Click me</button>
     `;
   }
 }
  • signal(0) creates a signal holding 0. Read it by calling it, this.count(), and write it with .set().
  • @click=${...} binds a click handler.

Run it

On http://localhost:2500, the page shows Clicked 0 times and a Click me button. Three clicks later:

Clicked 3 times

How it works

The page is rendered on the server, then its code runs in the browser, where it handles clicks. Reading this.count() inside the template subscribes that text to the signal, so .set() updates just that text: no virtual DOM and no re-render of the page.

Note: a shorter handler form. Elsewhere in the docs you'll see @click=${this.count.set(this.count() + 1)} without the () =>. Palinx compiles that into a listener, so both forms behave the same. This track uses the arrow function because it reads as plain JavaScript. Templates & reactivity explains both.

Next: Talk to the server.