Vue 3
Composition API, single-file component. Works in Vite, Nuxt, or any Vue 3 setup.
Install
The SDK isn't on npm yet. Save the module and its type declarations into your project — it's one dependency-free ES module, so there's nothing else to install.
curl -o src/lib/sensrik.js https://docs.sensrik.com/sensrik.js
curl -o src/lib/sensrik.d.ts https://docs.sensrik.com/sensrik.d.ts
A reusable Sensrik singleton
// src/lib/sensrik.ts
import { Sensrik } from './sensrik.js';
const STORAGE_KEY = 'sensrik.session';
function loadStored() {
try { return JSON.parse(localStorage.getItem(STORAGE_KEY) || 'null'); }
catch { return null; }
}
const stored = loadStored();
export const sensrik = new Sensrik({
accessToken: stored?.accessToken,
refreshToken: stored?.refreshToken,
onTokenRefreshed: (tokens) => localStorage.setItem(STORAGE_KEY, JSON.stringify(tokens)),
});
A login form (composition API)
<!-- src/components/LoginForm.vue -->
<script setup lang="ts">
import { ref } from 'vue';
import { sensrik } from '../lib/sensrik';
const emit = defineEmits<{ success: [] }>();
const email = ref('');
const password = ref('');
const error = ref<string | null>(null);
const busy = ref(false);
async function handleSubmit() {
error.value = null;
busy.value = true;
try {
await sensrik.auth.login(email.value, password.value);
emit('success');
} catch (err: any) {
error.value = err?.status === 401 ? 'Invalid email or password.' : err?.message;
} finally {
busy.value = false;
}
}
</script>
<template>
<form @submit.prevent="handleSubmit">
<div v-if="error" class="error">{{ error }}</div>
<input v-model="email" type="email" required />
<input v-model="password" type="password" required />
<button type="submit" :disabled="busy">
{{ busy ? 'Signing in…' : 'Sign in' }}
</button>
</form>
</template>
A devices list (auto-refreshes every 30s)
<!-- src/components/DevicesList.vue -->
<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue';
import { sensrik } from '../lib/sensrik';
import type { Device } from '../lib/sensrik.js';
const devices = ref<Device[]>([]);
const error = ref<string | null>(null);
const loading = ref(true);
let interval: ReturnType<typeof setInterval> | null = null;
async function load() {
try {
devices.value = await sensrik.devices.list();
error.value = null;
} catch (err: any) {
error.value = err?.message ?? 'Failed to load';
} finally {
loading.value = false;
}
}
onMounted(async () => {
await load();
interval = setInterval(load, 30_000);
});
onUnmounted(() => { if (interval) clearInterval(interval); });
</script>
<template>
<p v-if="loading">Loading…</p>
<p v-else-if="error" style="color:red">{{ error }}</p>
<p v-else-if="devices.length === 0">No devices yet.</p>
<ul v-else>
<li v-for="d in devices" :key="d.id">
<strong>{{ d.name }}</strong> — {{ d.isOnline ? '🟢 online' : '⚪ offline' }} — {{ d.batterySoc ?? '—' }}%
</li>
</ul>
</template>
For a full storefront — login + devices + device detail with live charts — ask your Sensrik admin for the vanilla template and reimplement the pages in Vue. The SDK calls are the same.