Skip to content

Preferences

Contacts turn channels off and mute notification types. Chaski checks their choices before every send.

What a contact can choose

A contact’s preferences have two parts:

  • Channels: email, in_app and push, each on or off. A channel the contact never set stays on.
  • Muted types: notification types the contact doesn’t want. An entry ending in * mutes every type that starts with it, and a channel: prefix limits it to one channel: push:reminder.* mutes reminders on push only.
TypeScript
type ChaskiPreferences = {
  channels: { email?: boolean; in_app?: boolean; push?: boolean };
  mutedTypes: string[];
};

Every send checks them, channel by channel. A send with transactional: true skips the check, for receipts, password resets and other notifications the contact must get.

Build a settings screen

Your frontend reads and changes the signed-in user’s preferences through the routes your app mounts with userRoutes(). With React:

src/settings/notifications.tsx
import { usePreferences } from 'chaskijs/react';

export const NotificationSettings = () => {
  const { preferences, topics, update } = usePreferences();
  if (!preferences) return null;
  return (
    <>
      <label>
        <input
          type="checkbox"
          checked={preferences.channels.email !== false}
          onChange={(event) => update({ channels: { email: event.target.checked } })}
        />
        Email
      </label>
      {/* One section per topic, with a switch for each of its types. */}
    </>
  );
};

topics lists your notification types grouped by the topic their template sets, so the screen can offer what your app actually sends. Without React, client.preferences from chaskijs/client has the same get(), update() and topics().

Mute types for everyone

Muted by default, on the Channels page of the dashboard, lists types every contact has muted until they save preferences of their own, such as a weekly digest people opt into. It takes the same entries as a contact’s muted types, * and channel: prefixes included.

On the server

env.CHASKI.preferences() reads and writes any contact’s preferences from your app, by recipient id:

TypeScript
await env.CHASKI.preferences().set(user.id, { mutedTypes: ['marketing.*'] });
const { channels, mutedTypes } = await env.CHASKI.preferences().get(user.id);

Updated Oct 30, 2026

MIT License · chaski.sh