A quick reference cheat sheet to getting started with InfrontJS — creating an App, adding States, rendering Views, and basic routing.
<!-- UMD build (global IF) -->
<script src="https://unpkg.com/infrontjs/dist/IF.js"></script>
Use this for the fastest “drop in and run” setup.
<script type="module">
import * as IF from "https://unpkg.com/infrontjs@latest/dist/infrontjs.esm.js";
</script>
Use this if you want modern ES modules in the browser.
npm install infrontjs
// bundler setup
import * as IF from "infrontjs";
<div id="app"></div>
<script type="module">
import * as IF from "https://unpkg.com/infrontjs@latest/dist/infrontjs.esm.js";
// Create app with a container
const app = new IF.App(document.querySelector("#app"));
// Start lifecycle (router/state/view init, initial state, ...)
app.run();
</script>
Creates an App instance and starts it via app.run().
import * as IF from "https://unpkg.com/infrontjs@latest/dist/infrontjs.esm.js";
const app = new IF.App(document.querySelector("#app"), {
router: { mode: "hash" } // "url" (pushState) or "hash"
});
app.run();
Use hash mode if you don’t control server rewrites (GitHub Pages, many CDNs, etc.).
The logical “core unit” of an InfrontJS application. Owns router, stateManager, view, i18n, etc.
const app = new IF.App(containerEl, {
app: {
id: "my-app",
title: "My App",
sayHello: true
},
router: {
isEnabled: true,
mode: "url", // or "hash"
basePath: null
},
l18n: {
defaultLanguage: "en"
}
});
A State represents a route-driven unit of logic / lifecycle.
Typically: fetch data → render a view → bind events → cleanup on exit.
class MyState extends IF.State {
static ROUTE = "my-state";
async enter() {
console.log("Hello from MyState");
}
}
Template rendering uses EJS templates and provides localization helpers.
app.view.render(app.container, `
<h1>Welcome <%= username %></h1>
<p><%= _lcs("greeting") %></p>
`, { username: "John" });
Precompile templates for reuse:
const tpl = app.view.compile(`<h1><%= title %></h1>`);
const html = tpl({ title: "Page 1" });
this.app.view.setWindowTitle("My App - Dashboard");
class GreetingState extends IF.State {
static ROUTE = "";
async enter() {
this.app.view.render(this.app.container, "<h1>Hello InfrontJS World</h1>");
}
}
const app = new IF.App(document.querySelector("#app"), {
router: { mode: "hash" }
});
app.stateManager.add(GreetingState);
app.run();
class CounterState extends IF.State {
static ROUTE = "counter";
async enter() {
this.count = 0;
this.app.view.render(this.app.container, `
<div>
<h1>Counter</h1>
<p>Value: <span id="v"><%= count %></span></p>
<button id="inc">Increment</button>
</div>
`, { count: this.count });
const v = this.app.container.querySelector("#v");
const btn = this.app.container.querySelector("#inc");
this.addEventListener(btn, "click", () => {
this.count++;
v.textContent = String(this.count);
});
}
}
The State base class offers helpers like addEventListener(...) to track cleanup.
| Setting | Description |
|---|---|
router.mode = "url" |
Uses history.pushState URLs (needs server rewrite) |
router.mode = "hash" |
Uses #/path URLs (works on static hosting) |
router.isEnabled = false |
Disable routing entirely |
| Method | When it’s called |
|---|---|
canEnter() |
Before entering a state |
enter() |
Main entry hook |
canExit() |
Before leaving state |
exit() |
Cleanup hook |
class LiveState extends IF.State {
ROUTE = "live";
async onEnter() {
this.addEventListener(window, "resize", () => this.render());
this.setInterval(() => this.tick(), 1000);
this.setTimeout(() => console.log("ready"), 200);
this.render();
}
render() {
this.app.view.render(this.app.container, "<h1>Live</h1>");
}
}