Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/directus/directus/llms.txt

Use this file to discover all available pages before exploring further.

Overview

The Directus SDK provides real-time functionality through WebSocket connections, allowing you to subscribe to live updates for collections, send custom messages, and handle WebSocket events.

Setup

Basic Real-time Client

Create a client with real-time capabilities:
import { createDirectus, realtime } from '@directus/sdk';

const client = createDirectus<Schema>('https://your-directus-url.com')
  .with(realtime());

// Connect to WebSocket
await client.connect();

Authentication Modes

The realtime() composable supports three authentication modes:
  • handshake - Authenticate during connection (default, recommended)
  • strict - Pass token in URL query parameter
  • public - No authentication (for public data)
import { createDirectus, realtime, authentication } from '@directus/sdk';

const client = createDirectus<Schema>('https://your-directus-url.com')
  .with(authentication('json'))
  .with(realtime({
    authMode: 'handshake',
  }));

// Login first
await client.login({
  email: 'user@example.com',
  password: 'password',
});

// Then connect WebSocket
await client.connect();

Public Mode

const client = createDirectus<Schema>('https://your-directus-url.com')
  .with(realtime({
    authMode: 'public',
  }));

await client.connect();

Subscriptions

Subscribe to Collection Updates

Subscribe to real-time updates for a collection:
const { subscription, unsubscribe } = await client.subscribe('articles', {
  query: {
    fields: ['id', 'title', 'status'],
    filter: {
      status: { _eq: 'published' },
    },
  },
});

// Listen for updates
for await (const message of subscription) {
  console.log('Event:', message.event); // 'init', 'create', 'update', 'delete'
  console.log('Data:', message.data);
}

Subscription Events

Subscriptions emit different event types:
  • init - Initial data when subscription starts
  • create - New item created
  • update - Existing item updated
  • delete - Item deleted
const { subscription, unsubscribe } = await client.subscribe('articles');

for await (const message of subscription) {
  switch (message.event) {
    case 'init':
      console.log('Initial data:', message.data);
      break;
    case 'create':
      console.log('New item created:', message.data);
      break;
    case 'update':
      console.log('Item updated:', message.data);
      break;
    case 'delete':
      console.log('Item deleted:', message.data);
      break;
  }
}

Unsubscribe

Stop listening to updates:
const { subscription, unsubscribe } = await client.subscribe('articles');

// Listen for a while...
let count = 0;
for await (const message of subscription) {
  console.log(message);
  count++;
  
  if (count >= 10) {
    unsubscribe();
    break;
  }
}

WebSocket Events

Listen to WebSocket Events

Handle low-level WebSocket events:
// Connection opened
const stopOpen = client.onWebSocket('open', (event) => {
  console.log('WebSocket connected');
});

// Connection closed
const stopClose = client.onWebSocket('close', (event) => {
  console.log('WebSocket closed');
});

// Connection error
const stopError = client.onWebSocket('error', (event) => {
  console.error('WebSocket error:', event);
});

// Message received
const stopMessage = client.onWebSocket('message', (message) => {
  console.log('Raw message:', message);
});

// Stop listening
stopOpen();
stopClose();
stopError();
stopMessage();

Send Custom Messages

Send Messages

Send custom messages through the WebSocket:
// Send ping message
client.sendMessage({ type: 'ping' });

// Send custom message
client.sendMessage({
  type: 'custom',
  data: { foo: 'bar' },
});

Ping/Pong Example

const stop = client.onWebSocket('message', (message) => {
  if ('type' in message && message.type === 'pong') {
    console.log('PONG received');
    stop();
  }
});

client.sendMessage({ type: 'ping' });

Connection Management

Connect

await client.connect();
console.log('WebSocket connected');

Disconnect

client.disconnect();
console.log('WebSocket disconnected');

Check Connection Status

const isConnected = await client.isConnected();
console.log('Connected:', isConnected);

Configuration

Advanced Configuration

const client = createDirectus<Schema>('https://your-directus-url.com')
  .with(realtime({
    authMode: 'handshake',
    
    // Heartbeat ping/pong
    heartbeat: true, // Default: true
    
    // Debug logging
    debug: true, // Default: false
    
    // Connection timeout
    connect: {
      timeout: 10000, // 10 seconds (default)
    },
    
    // Reconnection settings
    reconnect: {
      delay: 1000, // 1 second delay (default)
      retries: 10, // Max retry attempts (default)
    },
  }));

Custom WebSocket URL

const client = createDirectus<Schema>('https://your-directus-url.com')
  .with(realtime({
    url: 'wss://custom-websocket-url.com',
  }));

Full Example

Complete example with authentication and subscriptions:
import { createDirectus, authentication, realtime } from '@directus/sdk';

interface Article {
  id: number;
  title: string;
  status: string;
}

interface Schema {
  articles: Article[];
}

const client = createDirectus<Schema>('https://your-directus-url.com')
  .with(authentication('json'))
  .with(realtime({
    authMode: 'handshake',
    debug: true,
  }));

async function main() {
  // Login
  await client.login({
    email: 'user@example.com',
    password: 'password',
  });

  // Connect WebSocket
  await client.connect();

  // Subscribe to articles
  const { subscription, unsubscribe } = await client.subscribe('articles', {
    query: {
      fields: ['*'],
      filter: {
        status: { _eq: 'published' },
      },
    },
  });

  // Listen for updates
  console.log('Listening for updates...');
  
  for await (const message of subscription) {
    console.log(`[${message.event}]`, message.data);
  }
}

main().catch(console.error);

Type Signatures

// Real-time configuration
interface WebSocketConfig {
  authMode?: 'handshake' | 'strict' | 'public';
  url?: string;
  heartbeat?: boolean;
  debug?: boolean;
  connect?: {
    timeout?: number;
  };
  reconnect?: {
    delay?: number;
    retries?: number;
  };
}

// Subscription options
interface SubscribeOptions<Schema, Collection> {
  query?: Query<Schema, Schema[Collection]>;
  uid?: string;
}

// Subscription output
type SubscriptionOutput = {
  type: 'subscription';
  event: 'init' | 'create' | 'update' | 'delete';
  data: Item | Item[];
  uid: string;
};

// WebSocket client methods
interface WebSocketClient<Schema> {
  connect(): Promise<WebSocket>;
  disconnect(): void;
  isConnected(): Promise<boolean>;
  
  subscribe<Collection>(
    collection: Collection,
    options?: SubscribeOptions<Schema, Collection>
  ): Promise<{
    subscription: AsyncGenerator<SubscriptionOutput>;
    unsubscribe: () => void;
  }>;
  
  sendMessage(message: string | Record<string, any>): void;
  
  onWebSocket(
    event: 'open' | 'close' | 'error' | 'message',
    callback: (event: any) => void
  ): () => void;
}

Next Steps

Items Operations

Perform CRUD operations on items

Authentication

Authenticate for protected subscriptions

WebSocket API

Learn about WebSocket protocol details

Flows

Trigger flows from real-time events