NarraLeaf

Custom Notification

What It Replaces

Notifications display brief messages in-game (e.g. "Saved", "Unlocked"). You can replace the default Notification component via the notification option in game.configure to customize appearance and layout.

Use liveGame.notify to trigger notifications. The custom component receives a notifications array (INotificationsProps) and renders each item.

1. Create the Custom Notification Component

The custom component receives { notifications } typed as INotificationsProps. Each notification has id and message:

import type { INotificationsProps } from "narraleaf-react";

function CustomNotification({ notifications }: INotificationsProps) {
  return (
    <div className="absolute top-4 left-0 right-0 flex flex-col items-center gap-2 pointer-events-none">
      {notifications.map(({ id, message }) => (
        <div
          key={id}
          className="bg-black/70 text-white px-4 py-2 rounded-lg shadow-lg text-sm"
        >
          {message}
        </div>
      ))}
    </div>
  );
}

2. Register with Game

import { Game, GameProviders, Player } from "narraleaf-react";

const game = new Game({ notification: CustomNotification });

function App() {
  return (
    <GameProviders game={game}>
      <Player story={story} onReady={({ liveGame }) => liveGame.newGame()} />
    </GameProviders>
  );
}

3. Trigger Notifications

Call notify anywhere you have access to LiveGame:

const liveGame = game.getLiveGame();

// Show notification, auto-dismiss after 3000ms (default)
liveGame.notify("Saved");

// Custom duration in ms
liveGame.notify("Achievement unlocked", 5000);

// duration: null - do not auto-dismiss (stays until manually removed)
const notice = liveGame.notify("Important notice", null);

// Remove a persistent notification later.
notice.cancel();

notify() returns a NotificationToken with cancel() and promise. The promise settles when the notification disappears.

4. Example with Animation

Use Motion for fade in/out:

import { motion, AnimatePresence } from "motion/react";
import type { INotificationsProps } from "narraleaf-react";

function AnimatedNotification({ notifications }: INotificationsProps) {
  return (
    <div className="absolute top-4 left-0 right-0 flex flex-col items-center gap-2 pointer-events-none">
      <AnimatePresence>
        {notifications.map(({ id, message }) => (
          <motion.div
            key={id}
            initial={{ opacity: 0, y: -10 }}
            animate={{ opacity: 1, y: 0 }}
            exit={{ opacity: 0, y: -10 }}
            transition={{ duration: 0.2 }}
            className="bg-amber-500/90 text-black px-4 py-2 rounded-lg"
          >
            {message}
          </motion.div>
        ))}
      </AnimatePresence>
    </div>
  );
}

5. Notification Data Structure

type Notification = {
  id: string;    // Unique id for React key
  message: string;
  // duration is used internally for auto-dismiss
};

See Also

On this page