Vanilla HTML + JS
A single self-contained HTML file that signs a user in and lists their devices using the SDK. Save as index.html, host anywhere, open in a browser. No build, no install.
Full example
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>My devices</title>
</head>
<body>
<h1>My devices</h1>
<form id="login">
<input name="email" type="email" placeholder="Email" required />
<input name="password" type="password" placeholder="Password" required />
<button>Sign in</button>
</form>
<ul id="devices"></ul>
<script type="module">
import { Sensrik } from 'https://docs.sensrik.com/sensrik.js';
// Browser code signs in as the END USER. Never put an sk_... API key in a
// page: anyone can read it with view-source. API keys are server-side only.
const sensrik = new Sensrik();
const list = document.getElementById('devices');
// textContent, never innerHTML: a device name or error message is data,
// and "<img src=x onerror=...>" must show up as text, not run.
const item = (text, color) => {
const li = document.createElement('li');
li.textContent = text;
if (color) li.style.color = color;
return li;
};
document.getElementById('login').addEventListener('submit', async (e) => {
e.preventDefault();
const form = e.currentTarget;
try {
await sensrik.auth.login(form.email.value, form.password.value);
// listAll: list() is ONE page (50 by default) with no hint that more exist.
const devices = await sensrik.devices.listAll();
list.replaceChildren(...(devices.length === 0
? [item('No devices yet.')]
: devices.map((d) => item(`${d.name} — ${d.isOnline ? 'online' : 'offline'}`))));
} catch (err) {
list.replaceChildren(item(`Failed: ${err.message}`, 'red'));
}
});
</script>
</body>
</html>
API keys are server-side only
An sk_… API key carries the tenant's Owner rights. Anything in a web page — inline, in a bundle, in config.js — can be read by every visitor, so browser code always uses the sign-in flow above. Use an API key only from code that runs on a server or in a script you control, and load it from the environment:
import { Sensrik } from './sensrik.js';
// Server-side only: read the key from the environment, never from source.
const sensrik = new Sensrik({ apiKey: process.env.SENSRIK_API_KEY });
const devices = await sensrik.devices.listAll();
Why render with textContent
Device names, locations and error messages come from the API and can contain anything, including markup. Building HTML strings around them lets a name like <img src=x onerror=…> run script in your page. Create elements and set textContent instead.
Why this works without a build step
- The SDK is served as an ES module from
https://docs.sensrik.com/sensrik.js. - Modern browsers (last 3 years) support
<script type="module">+ top-levelawaitnatively. - No bundler, no transpiler, no
node_modules. Saves bytes, ships faster.
Want the full storefront?
For login + device list + device detail with live readings, ask your Sensrik admin for the storefront template. Same shape as this snippet, more pages.