📚DocumentationTutorials

Tutorials

Learn how to solve common developer challenges with Vaultrice through these step-by-step guides.

Tutorial 1: Cross-Domain User State Management

🎯

The Need

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.

💡

Why Vaultrice?

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.

Step-by-Step Guide

1

Define a Shared User ID

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';
2

Initialize Vaultrice on Both Sites

On both brand-a.com and brand-b.com, initialize the NonLocalStorage client using the same project credentials and the shared userId.

NonLocalStorage API
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);
3

Set the Preference on One Domain

On brand-a.com, when the user toggles their theme preference, save it to Vaultrice using setItem.

NonLocalStorage API
// 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)
});
4

React to Changes on the Other Domain

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.

NonLocalStorage API
// 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();

Tutorial 2: Building a Collaborative To-Do List

🎯

The Need

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.

💡

Why Vaultrice?

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.

Step-by-Step Guide

1

Create 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'
);
2

Join Presence

Have each user join the presence channel with their name when they open the to-do list.

await todoList.join({ name: 'Bob' });
3

Display the Live Collaborator List

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();
4

Add and Display To-Do Items

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 || {});

Tutorial 3: Real-Time Configuration and Feature Flags

🎯

The Need

A development team wants to enable or disable application features in real-time for all users without deploying new code.

💡

Why Vaultrice?

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.

Step-by-Step Guide

1

Define the Shape of Your Flags

Using TypeScript, you can define an interface for your configuration object.

interface FeatureFlags {
  enableNewDashboard?: boolean;
  showPromoBanner?: boolean;
}
2

Create a Synchronized Config Object

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.

NonLocalStorage API
import { NonLocalStorage } from '@vaultrice/sdk';

const featureFlags = new NonLocalStorage<FeatureFlags>(
  credentials,
  'app-feature-flags' // A single, well-known ID for all clients
);
3

Control the Flags from an Admin Panel

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.

NonLocalStorage API
// 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);
});
4

React to Flag Changes in the Client App

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.

NonLocalStorage API
// 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();

Ready to Build Your Own?

These tutorials show just a few ways to leverage Vaultrice's real-time capabilities. What will you build next?