Skip to content

strapi-community/plugin-io

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

@strapi-community/plugin-io

Real-time WebSocket integration for Strapi v5 with Socket.IO

NPM Version NPM Downloads License Strapi Version

Add real-time capabilities to your Strapi application with WebSocket support. Automatically broadcast content changes, manage user connections, and build live features like chat, notifications, and collaborative editing.


Table of Contents


Features

Core Functionality

  • Automatic Real-Time Events - CRUD operations broadcast automatically to connected clients
  • Entity-Specific Subscriptions - Subscribe to individual entities for targeted updates
  • Role-Based Access Control - Built-in permission checks for JWT and API tokens
  • Multi-Client Support - Handle 2500+ concurrent connections efficiently

Developer Experience

  • Visual Admin Panel - Configure everything through the Strapi admin interface
  • TypeScript Support - Full type definitions for IntelliSense
  • Helper Functions - 12 utility methods for common tasks
  • Comprehensive Documentation - Detailed guides and examples

Production Ready

  • Redis Adapter - Scale horizontally across multiple servers
  • Rate Limiting - Prevent abuse with configurable limits
  • Monitoring Dashboard - Live connection stats and event logs
  • Security Features - IP whitelisting, authentication, input validation

Quick Start

1. Install the plugin

npm install @strapi-community/plugin-io

2. Enable in your Strapi project

Create or update config/plugins.js:

module.exports = {
  io: {
    enabled: true,
    config: {
      contentTypes: ['api::article.article'],
      socket: {
        serverOptions: {
          cors: {
            origin: 'http://localhost:3000',
            methods: ['GET', 'POST']
          }
        }
      }
    }
  }
};

3. Start your Strapi server

npm run develop

4. Connect from your frontend

import { io } from 'socket.io-client';

const socket = io('http://localhost:1337');

socket.on('article:create', (article) => {
  console.log('New article published:', article);
});

socket.on('article:update', (article) => {
  console.log('Article updated:', article);
});

That's it! Your application now has real-time updates.


Installation

Requirements

  • Node.js: 18.x - 22.x
  • Strapi: v5.x
  • npm: 6.x or higher

Install the package

# Using npm
npm install @strapi-community/plugin-io

# Using yarn
yarn add @strapi-community/plugin-io

# Using pnpm
pnpm add @strapi-community/plugin-io

Configuration

Basic Configuration

The simplest setup to get started:

// config/plugins.js
module.exports = {
  io: {
    enabled: true,
    config: {
      // Monitor these content types for changes
      contentTypes: [
        'api::article.article',
        'api::comment.comment'
      ]
    }
  }
};

Advanced Configuration

Fine-tune the plugin behavior:

// config/plugins.js
module.exports = {
  io: {
    enabled: true,
    config: {
      // Content types with specific actions and populate
      contentTypes: [
        {
          uid: 'api::article.article',
          actions: ['create', 'update'],  // Only these events
          populate: '*'                    // Include all relations
        },
        {
          uid: 'api::comment.comment',
          actions: ['create', 'delete'],
          populate: ['author', 'article']  // Only specific relations
        },
        {
          uid: 'api::order.order',
          populate: {                      // Strapi populate syntax
            customer: { fields: ['name', 'email'] },
            items: { populate: ['product'] }
          }
        }
      ],
      
      // Socket.IO server configuration
      socket: {
        serverOptions: {
          cors: {
            origin: process.env.CLIENT_URL || 'http://localhost:3000',
            methods: ['GET', 'POST'],
            credentials: true
          },
          pingTimeout: 60000,
          pingInterval: 25000
        }
      },
      
      // Custom event handlers
      events: [
        {
          name: 'connection',
          handler: ({ strapi, io }, socket) => {
            strapi.log.info(`Client connected: ${socket.id}`);
          }
        },
        {
          name: 'disconnect',
          handler: ({ strapi, io }, socket) => {
            strapi.log.info(`Client disconnected: ${socket.id}`);
          }
        }
      ],
      
      // Initialization hook
      hooks: {
        init: ({ strapi, $io }) => {
          strapi.log.info('[Socket.IO] Server initialized');
        }
      }
    }
  }
};

Populate Configuration

Include relations in emitted events by adding the populate option to content types. When configured, the plugin refetches entities with populated relations after create/update operations.

Populate Formats

Format Example Description
'*' or true populate: '*' Include all relations (1 level deep)
String array populate: ['author', 'category'] Only specific relations
Object populate: { author: { fields: ['name'] } } Full Strapi populate syntax

Examples

contentTypes: [
  // All relations with wildcard
  { uid: 'api::article.article', populate: '*' },
  
  // Specific relations only
  { 
    uid: 'api::comment.comment', 
    populate: ['author', 'post'] 
  },
  
  // Strapi populate syntax with field selection
  { 
    uid: 'api::order.order', 
    populate: { 
      customer: { fields: ['username', 'email'] },
      items: { 
        populate: { product: { fields: ['name', 'price'] } }
      }
    } 
  },
  
  // No populate (only base fields)
  { uid: 'api::log.log' }  // populate not set = no relations
]

Note: The populate option only affects create and update events. Delete events always contain minimal data (id, documentId) since the entity no longer exists.

Sensitive Fields Protection

The plugin automatically removes sensitive fields from all emitted data for security. This works in addition to Strapi's built-in private: true field filtering.

Default Blocked Fields

The following fields are always removed from emitted data:

  • password, salt, hash
  • resetPasswordToken, confirmationToken
  • refreshToken, accessToken, token
  • secret, apiKey, api_key
  • privateKey, private_key

Custom Sensitive Fields

Add your own sensitive fields to the block list:

// config/plugins.js
module.exports = {
  io: {
    enabled: true,
    config: {
      contentTypes: ['api::user.user'],
      
      // Additional fields to never emit
      sensitiveFields: [
        'creditCard',
        'ssn',
        'socialSecurityNumber',
        'bankAccount',
        'internalNotes'
      ]
    }
  }
};

How It Works

  1. Schema-level filtering: Strapi's sanitize.contentAPI removes private: true fields
  2. Blocklist filtering: Plugin removes all sensitive field names recursively
  3. Applies to all emits: Both emit() and raw() methods are protected
// Even with populate, sensitive fields are stripped
contentTypes: [
  {
    uid: 'api::user.user',
    populate: '*'  // Relations included, but passwords etc. still removed
  }
]

Security Note: Fields are matched case-insensitively and also partial matches work (e.g., apiKey blocks myApiKey, user_api_key, etc.)

Environment Variables

Recommended environment-based configuration:

// config/plugins.js
module.exports = ({ env }) => ({
  io: {
    enabled: env.bool('SOCKET_IO_ENABLED', true),
    config: {
      contentTypes: env.json('SOCKET_IO_CONTENT_TYPES', []),
      socket: {
        serverOptions: {
          cors: {
            origin: env('CLIENT_URL', 'http://localhost:3000')
          }
        }
      }
    }
  }
});
# .env
SOCKET_IO_ENABLED=true
CLIENT_URL=https://your-app.com
SOCKET_IO_CONTENT_TYPES=["api::article.article","api::comment.comment"]

Usage Examples

Server-Side Usage

Access the Socket.IO instance anywhere in your Strapi application:

// In a controller, service, or lifecycle
const io = strapi.$io;

// Emit to all connected clients
strapi.$io.raw({
  event: 'notification',
  data: {
    message: 'Server maintenance in 5 minutes',
    type: 'warning'
  }
});

// Send private message to a specific socket
strapi.$io.sendPrivateMessage(socketId, 'order:updated', {
  orderId: 123,
  status: 'shipped'
});

// Emit to all clients in a room
strapi.$io.server.to('admin-room').emit('dashboard:update', {
  activeUsers: 42,
  revenue: 15000
});

// Emit to a specific namespace
strapi.$io.emitToNamespace('admin', 'alert', {
  message: 'New user registered'
});

Client-Side Usage

Basic Connection

import { io } from 'socket.io-client';

const socket = io('http://localhost:1337');

socket.on('connect', () => {
  console.log('Connected to server');
});

socket.on('disconnect', () => {
  console.log('Disconnected from server');
});

// Listen for content type events
socket.on('article:create', (data) => {
  console.log('New article:', data);
});

socket.on('article:update', (data) => {
  console.log('Article updated:', data);
});

socket.on('article:delete', (data) => {
  console.log('Article deleted:', data.documentId);
});

With React

import { useEffect, useState } from 'react';
import { io } from 'socket.io-client';

function ArticlesList() {
  const [articles, setArticles] = useState([]);
  
  useEffect(() => {
    const socket = io('http://localhost:1337');
    
    // Listen for new articles
    socket.on('article:create', (article) => {
      setArticles(prev => [article, ...prev]);
    });
    
    // Listen for updates
    socket.on('article:update', (article) => {
      setArticles(prev => 
        prev.map(a => a.documentId === article.documentId ? article : a)
      );
    });
    
    // Listen for deletions
    socket.on('article:delete', (data) => {
      setArticles(prev => 
        prev.filter(a => a.documentId !== data.documentId)
      );
    });
    
    return () => socket.disconnect();
  }, []);
  
  return (
    <div>
      {articles.map(article => (
        <div key={article.documentId}>{article.title}</div>
      ))}
    </div>
  );
}

With Vue 3

<script setup>
import { ref, onMounted, onUnmounted } from 'vue';
import { io } from 'socket.io-client';

const articles = ref([]);
let socket;

onMounted(() => {
  socket = io('http://localhost:1337');
  
  socket.on('article:create', (article) => {
    articles.value = [article, ...articles.value];
  });
  
  socket.on('article:update', (article) => {
    const index = articles.value.findIndex(a => a.documentId === article.documentId);
    if (index !== -1) {
      articles.value[index] = article;
    }
  });
  
  socket.on('article:delete', (data) => {
    articles.value = articles.value.filter(a => a.documentId !== data.documentId);
  });
});

onUnmounted(() => {
  socket?.disconnect();
});
</script>

<template>
  <div v-for="article in articles" :key="article.documentId">
    {{ article.title }}
  </div>
</template>

Entity-Specific Subscriptions

Subscribe to updates for specific entities only:

// Client-side: Subscribe to a specific article
socket.emit('subscribe-entity', {
  uid: 'api::article.article',
  id: 123
}, (response) => {
  if (response.success) {
    console.log('Subscribed to article 123');
  }
});

// Now you only receive updates for article 123
socket.on('article:update', (data) => {
  console.log('Article 123 was updated:', data);
});

// Unsubscribe when done
socket.emit('unsubscribe-entity', {
  uid: 'api::article.article',
  id: 123
});

Benefits:

  • Reduced bandwidth - only receive relevant updates
  • Better performance - less client-side processing
  • Built-in permission checks - respects user roles

Room Management

Organize connections into rooms:

// Server-side: Add socket to a room
strapi.$io.joinRoom(socketId, 'premium-users');

// Get all sockets in a room
const sockets = await strapi.$io.getSocketsInRoom('premium-users');
console.log(`${sockets.length} premium users online`);

// Broadcast to a specific room
strapi.$io.server.to('premium-users').emit('exclusive-offer', {
  discount: 20,
  expiresIn: '24h'
});

// Remove socket from a room
strapi.$io.leaveRoom(socketId, 'premium-users');

// Disconnect a specific socket
strapi.$io.disconnectSocket(socketId, 'Kicked by admin');

Helper Functions

The plugin provides 12 utility functions available on strapi.$io:

Room Management

joinRoom(socketId, roomName)

Add a socket to a room.

const success = strapi.$io.joinRoom(socketId, 'premium-users');
// Returns: true if socket found and joined, false otherwise

leaveRoom(socketId, roomName)

Remove a socket from a room.

const success = strapi.$io.leaveRoom(socketId, 'premium-users');
// Returns: true if socket found and left, false otherwise

getSocketsInRoom(roomName)

Get all sockets in a specific room.

const sockets = await strapi.$io.getSocketsInRoom('premium-users');
// Returns: [{ id: 'socket-id', user: { username: 'john' } }, ...]

Messaging

sendPrivateMessage(socketId, event, data)

Send a message to a specific socket.

strapi.$io.sendPrivateMessage(socketId, 'order:shipped', {
  orderId: 123,
  trackingNumber: 'ABC123'
});

broadcast(socketId, event, data)

Broadcast from a socket to all other connected clients.

strapi.$io.broadcast(socketId, 'user:typing', {
  username: 'john',
  channel: 'general'
});

emitToNamespace(namespace, event, data)

Emit an event to all clients in a namespace.

strapi.$io.emitToNamespace('admin', 'alert', {
  message: 'New user registered',
  level: 'info'
});

Connection Management

disconnectSocket(socketId, reason)

Force disconnect a specific socket.

const success = strapi.$io.disconnectSocket(socketId, 'Session expired');
// Returns: true if socket found and disconnected, false otherwise

Entity Subscriptions

subscribeToEntity(socketId, uid, id)

Subscribe a socket to a specific entity (server-side).

const result = await strapi.$io.subscribeToEntity(socketId, 'api::article.article', 123);
// Returns: { success: true, room: 'api::article.article:123', uid, id }
// or: { success: false, error: 'Socket not found' }

unsubscribeFromEntity(socketId, uid, id)

Unsubscribe a socket from a specific entity.

const result = strapi.$io.unsubscribeFromEntity(socketId, 'api::article.article', 123);
// Returns: { success: true, room: 'api::article.article:123', uid, id }

getEntitySubscriptions(socketId)

Get all entity subscriptions for a socket.

const result = strapi.$io.getEntitySubscriptions(socketId);
// Returns: { 
//   success: true, 
//   subscriptions: [
//     { uid: 'api::article.article', id: '123', room: 'api::article.article:123' }
//   ]
// }

emitToEntity(uid, id, event, data)

Emit an event to all clients subscribed to a specific entity.

strapi.$io.emitToEntity('api::article.article', 123, 'article:commented', {
  commentId: 456,
  author: 'jane'
});

getEntityRoomSockets(uid, id)

Get all sockets subscribed to a specific entity.

const sockets = await strapi.$io.getEntityRoomSockets('api::article.article', 123);
// Returns: [{ id: 'socket-id', user: { username: 'john' } }, ...]

Authentication

The plugin supports multiple authentication strategies.

Public Access (No Authentication)

const socket = io('http://localhost:1337');
// No auth - placed in 'Public' role room

JWT Authentication (Users & Permissions)

// 1. Get JWT token from login
const response = await fetch('http://localhost:1337/api/auth/local', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    identifier: 'user@example.com',
    password: 'password123'
  })
});

const { jwt } = await response.json();

// 2. Connect with JWT
const socket = io('http://localhost:1337', {
  auth: {
    strategy: 'jwt',
    token: jwt
  }
});

// User is placed in their role room (e.g., 'Authenticated')

API Token Authentication

// 1. Create API token in Strapi Admin:
//    Settings > Global Settings > API Tokens > Create new token

// 2. Connect with API token
const socket = io('http://localhost:1337', {
  auth: {
    strategy: 'api-token',
    token: 'your-api-token-here'
  }
});

Permission Enforcement

Events are automatically filtered based on the user's role:

// Authenticated user with 'Editor' role
socket.on('article:create', (data) => {
  // Only receives events for content types they have permission to access
});

Configure permissions in the Strapi admin panel:

  1. Go to Settings > Users & Permissions > Roles
  2. Select a role (e.g., "Authenticated")
  3. Configure Socket.IO permissions per content type

Admin Panel

The plugin provides a full admin interface for configuration and monitoring.

Dashboard Widget

Requires Strapi v5.13+

After installation, a live statistics widget appears on your Strapi admin homepage:

Widget Shows:

  • Live connection status (pulsing indicator when active)
  • Active connections count
  • Active rooms count
  • Events per second
  • Total events processed since startup

Updates automatically every 5 seconds.

Settings Page

Navigate to Settings > Socket.IO > Settings for visual configuration:

Path: /admin/settings/io/settings

General Settings

  • Enable/disable the plugin
  • Configure CORS origins
  • Set server options (ping timeout, etc.)

Content Types

  • Enable automatic events for content types per role
  • Select specific actions (create, update, delete)
  • Configure role-based permissions

Events

  • Include relations in events (includeRelations)
  • Custom event names
  • Exclude specific fields
  • Only published content mode

Security

  • Require authentication
  • Rate limiting configuration
  • IP whitelisting/blacklisting
  • Input validation rules

Rooms

  • Auto-join by role configuration
  • Enable/disable private rooms

Advanced

  • Configure namespaces
  • Redis adapter settings for scaling
  • Entity subscription limits

Monitoring Page

Navigate to Settings > Socket.IO > Monitoring for live statistics:

Path: /admin/settings/io/monitoring

  • View active connections with user details
  • See event logs in real-time
  • Monitor performance metrics (events/second)
  • View entity subscription statistics
  • Send test events
  • Reset statistics

Monitoring Service

Access monitoring data programmatically via the monitoring service:

const monitoringService = strapi.plugin('io').service('monitoring');

Available Methods

getConnectionStats()

Get current connection statistics.

const stats = monitoringService.getConnectionStats();
// Returns:
// {
//   connected: 42,
//   rooms: [
//     { name: 'Authenticated', members: 35, isEntityRoom: false },
//     { name: 'api::article.article:123', members: 5, isEntityRoom: true }
//   ],
//   sockets: [
//     {
//       id: 'abc123',
//       connected: true,
//       rooms: ['Authenticated'],
//       entitySubscriptions: [{ uid: 'api::article.article', id: '123', room: '...' }],
//       handshake: { address: '::1', time: '...', query: {} },
//       user: { id: 1, username: 'john' }
//     }
//   ],
//   entitySubscriptions: {
//     total: 15,
//     byContentType: { 'api::article.article': 10, 'api::comment.comment': 5 },
//     rooms: ['api::article.article:123', ...]
//   }
// }

getEventStats()

Get event statistics.

const stats = monitoringService.getEventStats();
// Returns:
// {
//   totalEvents: 1234,
//   eventsByType: { 'create': 500, 'update': 600, 'delete': 134 },
//   lastReset: 1703123456789,
//   eventsPerSecond: '2.50'
// }

getEventLog(limit)

Get recent event log entries.

const logs = monitoringService.getEventLog(50);
// Returns:
// [
//   { timestamp: 1703123456789, type: 'create', data: {...} },
//   { timestamp: 1703123456790, type: 'connect', data: {...} }
// ]

logEvent(type, data)

Manually log an event.

monitoringService.logEvent('custom-event', {
  action: 'user-action',
  userId: 123
});

resetStats()

Reset all statistics and clear event log.

monitoringService.resetStats();

sendTestEvent(eventName, data)

Send a test event to all connected clients.

const result = monitoringService.sendTestEvent('test', { message: 'Hello!' });
// Returns:
// {
//   success: true,
//   eventName: 'test',
//   data: { message: 'Hello!', timestamp: 1703123456789, test: true },
//   recipients: 42
// }

Use Cases

Custom Analytics Dashboard:

// In a custom controller
async getAnalytics(ctx) {
  const monitoring = strapi.plugin('io').service('monitoring');
  
  ctx.body = {
    connections: monitoring.getConnectionStats(),
    events: monitoring.getEventStats(),
    recentActivity: monitoring.getEventLog(10)
  };
}

Health Check Endpoint:

async healthCheck(ctx) {
  const monitoring = strapi.plugin('io').service('monitoring');
  const stats = monitoring.getConnectionStats();
  
  ctx.body = {
    status: 'healthy',
    websocket: {
      connected: stats.connected,
      rooms: stats.rooms.length
    }
  };
}

TypeScript Support

Full TypeScript definitions are included for excellent IDE support.

Import Types

import type { 
  SocketIO, 
  SocketIOConfig,
  EmitOptions,
  RawEmitOptions,
  PluginSettings,
  MonitoringService,
  SettingsService,
  ConnectionStats,
  EventStats
} from '@strapi-community/plugin-io/types';

Configuration Example

// config/plugins.ts
import type { SocketIOConfig } from '@strapi-community/plugin-io/types';

export default {
  io: {
    enabled: true,
    config: {
      contentTypes: [
        {
          uid: 'api::article.article',
          actions: ['create', 'update', 'delete']
        }
      ],
      socket: {
        serverOptions: {
          cors: {
            origin: process.env.CLIENT_URL || 'http://localhost:3000',
            methods: ['GET', 'POST']
          }
        }
      }
    } satisfies SocketIOConfig
  }
};

Usage Example

// In your Strapi code
import type { SocketIO } from '@strapi-community/plugin-io/types';

// Type-safe access
const io: SocketIO = strapi.$io;

// All methods have full IntelliSense
await io.emit({
  event: 'create',
  schema: strapi.contentTypes['api::article.article'],
  data: { title: 'New Article' }
});

// Helper functions are typed
const sockets = await io.getSocketsInRoom('premium-users');
io.sendPrivateMessage(sockets[0].id, 'welcome', { message: 'Hello!' });

Performance

The plugin is optimized for production environments.

Benchmarks

  • Concurrent Connections: 2500+ simultaneous connections
  • Memory Usage: ~17KB per connection
  • Event Throughput: 10,000+ events/second
  • Latency: <10ms for local broadcasts

Optimizations

Intelligent Caching

Role and permission data is cached for 5 minutes, reducing database queries by up to 90%.

Debouncing

Bulk operations are automatically debounced to prevent event flooding during data imports.

Parallel Processing

All event emissions are processed in parallel for maximum throughput.

Connection Pooling

Efficient connection management with automatic cleanup of stale connections.

Production Configuration

// config/plugins.js (production)
module.exports = ({ env }) => ({
  io: {
    enabled: true,
    config: {
      contentTypes: env.json('SOCKET_IO_CONTENT_TYPES'),
      
      socket: {
        serverOptions: {
          cors: {
            origin: env('CLIENT_URL'),
            credentials: true
          },
          // Optimize for production
          pingTimeout: 60000,
          pingInterval: 25000,
          maxHttpBufferSize: 1e6,
          transports: ['websocket', 'polling']
        }
      },
      
      // Use Redis for horizontal scaling
      hooks: {
        init: async ({ strapi, $io }) => {
          const { createAdapter } = require('@socket.io/redis-adapter');
          const { createClient } = require('redis');
          
          const pubClient = createClient({ url: env('REDIS_URL') });
          const subClient = pubClient.duplicate();
          
          await Promise.all([pubClient.connect(), subClient.connect()]);
          
          $io.server.adapter(createAdapter(pubClient, subClient));
          
          strapi.log.info('[Socket.IO] Redis adapter connected');
        }
      }
    }
  }
});

Migration Guide

From v2 (Strapi v4) to v5 (Strapi v5)

Good news: The API is 100% compatible! Most projects migrate in under 1 hour.

Quick Migration Steps

  1. Update Strapi to v5

    npm install @strapi/strapi@5 @strapi/plugin-users-permissions@5
  2. Update the plugin

    npm uninstall strapi-plugin-io
    npm install @strapi-community/plugin-io@latest
  3. Test your application

    npm run develop

Your configuration stays the same - no code changes needed!

What Changed

  • Package name: strapi-plugin-io -> @strapi-community/plugin-io
  • Package structure: Uses new Strapi v5 Plugin SDK
  • Dependencies: Updated to Strapi v5 peer dependencies
  • Build process: Optimized build with modern tooling

What Stayed the Same

  • All API methods work identically
  • Configuration format unchanged
  • Client-side code works as-is
  • Same helper functions
  • Same event format

For detailed migration instructions, see docs/guide/migration.md.


Documentation

Official Documentation

Guides

Examples


Related Plugins

Build complete real-time applications with these complementary Strapi v5 plugins:

Enterprise email management with OAuth 2.0 support. Perfect for sending transactional emails triggered by Socket.IO events.

Use case: Send email notifications when real-time events occur.

Advanced session tracking and monitoring. Track Socket.IO connections, monitor active users, and analyze session patterns.

Use case: Monitor who's connected to your WebSocket server in real-time.

Bookmark management system with real-time sync. Share bookmarks instantly with your team using Socket.IO integration.

Use case: Collaborative bookmark management with live updates.


Contributing

We welcome contributions! Here's how you can help:

Report Bugs

Found a bug? Open an issue with:

  • Strapi version
  • Plugin version
  • Steps to reproduce
  • Expected vs actual behavior

Suggest Features

Have an idea? Start a discussion to:

  • Describe the feature
  • Explain the use case
  • Discuss implementation

Submit Pull Requests

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Development Setup

# Clone the repository
git clone https://github.com/strapi-community/strapi-plugin-io.git
cd strapi-plugin-io

# Install dependencies
npm install

# Build the plugin
npm run build

# Run in watch mode
npm run watch

# Verify structure
npm run verify

Support


License

MIT License

Copyright (c) 2024 Strapi Community


Credits

Original Authors:

Enhanced and Maintained by:

Maintained until: December 2026


Changelog

v5.0.0 (Latest)

  • Strapi v5 support
  • Package renamed to @strapi-community/plugin-io
  • Enhanced TypeScript support
  • Entity-specific subscriptions
  • 12 helper functions
  • Admin panel with monitoring dashboard
  • Performance optimizations
  • Updated documentation

For full changelog, see CHANGELOG.md.


Documentation | API Reference | Examples | GitHub

Made with love for the Strapi community

About

A plugin for Socket IO integration with Strapi CMS.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 7