Learn how to solve common developer challenges with Vaultrice through these step-by-step guides.
A company with multiple brand websites (e.g., brand-a.com
and brand-b.com
) wants to share user preferences like theme (dark/light mode) across all of them. A user's choice on one site should instantly apply to the other.
Standard localStorage
is confined to a single domain. Building a custom solution requires a database, an API, and complex cross-origin logic. Vaultrice offers a "drop-in" solution that handles this out of the box, abstracting away the backend complexity.
To link a user's preferences across domains, both websites must use the same object ID. A stable user ID from your authentication system is perfect for this.
// A unique ID for the logged-in user
const userId = 'user-ada-lovelace-1729';
On both brand-a.com
and brand-b.com
, initialize the NonLocalStorage
client using the same project credentials and the shared userId
.
import { NonLocalStorage } from '@vaultrice/sdk';
const credentials = {
projectId: 'your-project-id',
apiKey: 'your-api-key',
apiSecret: 'your-api-secret'
// instead of apiKey + apiSecret you can also use
// the accessToken approach: https://www.vaultrice.com/docs/security#authentication-methods
};
const userSettings = new NonLocalStorage(credentials, userId);
On brand-a.com
, when the user toggles their theme preference, save it to Vaultrice using setItem
.
// On brand-a.com
const themeToggle = document.getElementById('theme-toggle');
themeToggle.addEventListener('change', async (event) => {
const newTheme = event.target.checked ? 'dark' : 'light';
await userSettings.setItem('theme', newTheme);
console.log(`Theme set to ${newTheme}`);
// (Your UI logic to apply the theme locally)
});
On brand-b.com
, get the initial theme value and then use on('setItem', ...)
to listen for real-time changes. This allows the UI to update instantly without needing a page refresh.
// On brand-b.com
const body = document.body;
async function initializeTheme() {
const themeItem = await userSettings.getItem('theme');
const theme = themeItem?.value || 'light'; // Default to light
applyTheme(theme);
}
// Listen for real-time updates from other domains
userSettings.on('setItem', 'theme', (item) => {
console.log(`Theme was updated to: ${item.value}`);
applyTheme(item.value);
});
function applyTheme(theme) {
body.className = theme; // Applies 'dark' or 'light' class to the body
}
initializeTheme();
A team needs a simple to-do list where changes made by one user are instantly visible to all other team members. They also need to see who is currently viewing the list.
Building this manually requires wiring a database to a separate WebSocket provider. With Vaultrice, real-time data sync and presence are integrated. The Presence API
is a huge time-saver for features like "online user lists," which is a non-trivial feature to build reliably. This tutorial showcases the all-in-one power of the SyncObject
.
Define a TypeScript interface for our data and create a SyncObject
instance. Everyone collaborating on the list will connect to the same object ID.
import { createSyncObject } from '@vaultrice/sdk';
interface Todo {
text: string;
completed: boolean;
}
interface TodoListState {
tasks?: { [id: string]: Todo };
title?: string;
}
const todoList = await createSyncObject<TodoListState>(
credentials,
'project-alpha-todos'
);
Have each user join
the presence channel with their name when they open the to-do list.
await todoList.join({ name: 'Bob' });
Read the joinedConnections
property to show who is online. Then, use the presence:join
and presence:leave
events to keep the list updated in real-time.
const collaboratorList = document.getElementById('collaborators');
function renderCollaborators() {
collaboratorList.innerHTML = '';
todoList.joinedConnections.forEach(user => {
const li = document.createElement('li');
li.textContent = user.data.name;
collaboratorList.appendChild(li);
});
}
// Listen for presence changes and re-render
todoList.on('presence:join', renderCollaborators);
todoList.on('presence:leave', renderCollaborators);
// Initial render
renderCollaborators();
To add a task, simply set a property on the tasks
object. To display the list, listen for changes to the tasks
property.
// Adding a new task is a simple property assignment
function addTask(text) {
const taskId = `task-${Date.now()}`;
const newTask = { text, completed: false };
// Use the spread operator to non-destructively add the new task
todoList.tasks = { ...(todoList.tasks || {}), [taskId]: newTask };
}
// Listen for changes to the 'tasks' property and re-render the list
todoList.on('setItem', 'tasks', (item) => {
renderTasks(item.value);
});
// Initial render
renderTasks(todoList.tasks || {});
A development team wants to enable or disable application features in real-time for all users without deploying new code.
While there are dedicated feature flag services, Vaultrice offers a flexible and cost-effective solution. Using createSyncObject
, you can create a reactive configuration object that instantly propagates changes to all clients.
Using TypeScript, you can define an interface for your configuration object.
interface FeatureFlags {
enableNewDashboard?: boolean;
showPromoBanner?: boolean;
}
On your client application, use the createSyncObject
factory. This returns a Proxy object that behaves like a normal JavaScript object but automatically syncs any property changes.
import { NonLocalStorage } from '@vaultrice/sdk';
const featureFlags = new NonLocalStorage<FeatureFlags>(
credentials,
'app-feature-flags' // A single, well-known ID for all clients
);
In a separate admin application, create another SyncObject
instance connected to the same ID. When an admin changes a property on this object, the change is instantly broadcast to all clients.
// In your admin panel application
const adminControls = new NonLocalStorage<FeatureFlags>(
adminCredentials, // Use admin credentials
'app-feature-flags' // Same ID
);
// Bind this to a toggle switch in the admin UI
const dashboardToggle = document.getElementById('dashboard-toggle');
dashboardToggle.addEventListener('change', async (e) => {
// This change is instantly sent to all connected clients
await adminControls.setItem('enableNewDashboard', e.target.checked);
});
Your client application can now read the properties of the featureFlags
object. Because it's a reactive proxy, you can build your UI to respond to its values. No event listeners are needed.
// In your main client application
async function renderDashboard() {
// Read the current value from the server
const dashboardFlag = await featureFlags.getItem('enableNewDashboard');
if (dashboardFlag?.value) {
showNewDashboard();
} else {
showOldDashboard();
}
}
// Listen for real-time changes
featureFlags.on('setItem', 'enableNewDashboard', (item) => {
if (item.value) {
showNewDashboard();
} else {
showOldDashboard();
}
});
// You can call this function anytime
renderDashboard();
These tutorials show just a few ways to leverage Vaultrice's real-time capabilities. What will you build next?