Vanilla JavaScript

Use CloudSignal MQTT with plain HTML and JavaScript via CDN

Vanilla JavaScript

Use CloudSignal directly in your HTML pages without any build tools or frameworks.

CDN Links

<!-- From unpkg -->
<script src="https://unpkg.com/@cloudsignal/[email protected]/dist/index.global.js"></script>

<!-- Or from jsDelivr -->
<script src="https://cdn.jsdelivr.net/npm/@cloudsignal/[email protected]/dist/index.global.js"></script>

Quick Start

<!DOCTYPE html>
<html>
<head>
  <title>CloudSignal Demo</title>
</head>
<body>
  <div id="status">Disconnected</div>
  <button id="connect">Connect</button>
  <div id="messages"></div>

  <script src="https://unpkg.com/@cloudsignal/[email protected]/dist/index.global.js"></script>
  <script>
    let client = null;

    document.getElementById('connect').onclick = async () => {
      // Note: use CloudSignal.default for the IIFE bundle
      client = new CloudSignal.default({
        tokenServiceUrl: 'https://auth.cloudsignal.app',
        preset: 'desktop',
        debug: true,
      });

      // Connection status
      client.onConnectionStatusChange = (connected) => {
        document.getElementById('status').textContent = 
          connected ? '🟒 Connected' : 'πŸ”΄ Disconnected';
      };

      // Receive messages
      client.onMessage((topic, message) => {
        const div = document.createElement('div');
        div.textContent = `${topic}: ${message}`;
        document.getElementById('messages').prepend(div);
      });

      // Connect
      try {
        await client.connectWithToken({
          host: 'wss://connect.cloudsignal.app:18885/',
          organizationId: 'your-org-uuid',
          secretKey: 'cs_live_xxxxx',
          userEmail: '[email protected]',
        });

        await client.subscribe('my/topic');
        client.transmit('my/topic', { hello: 'world' });
      } catch (error) {
        console.error('Connection failed:', error);
      }
    };
  </script>
</body>
</html>

Global Namespace

When loaded via script tag, the SDK exposes a CloudSignal global object:

// Main client class (note the .default)
const client = new CloudSignal.default(options);

// Other exports
CloudSignal.VERSION;           // "2.2.1"
CloudSignal.CONNECTION_STATES; // { CONNECTED: "connected", ... }

Complete Example

Full working example with UI:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>CloudSignal MQTT Demo</title>
  <style>
    body { font-family: system-ui, sans-serif; max-width: 800px; margin: 2rem auto; padding: 0 1rem; }
    .card { background: #f5f5f5; border-radius: 8px; padding: 1rem; margin-bottom: 1rem; }
    .status { font-size: 1.2rem; margin-bottom: 1rem; }
    .connected { color: green; }
    .disconnected { color: red; }
    button { padding: 0.5rem 1rem; cursor: pointer; margin-right: 0.5rem; }
    button:disabled { opacity: 0.5; cursor: not-allowed; }
    input { padding: 0.5rem; width: 200px; }
    #messages { max-height: 300px; overflow-y: auto; }
    .message { padding: 0.5rem; border-bottom: 1px solid #ddd; font-family: monospace; font-size: 0.9rem; }
    .log { padding: 0.25rem 0.5rem; font-size: 0.8rem; color: #666; }
  </style>
</head>
<body>
  <h1>CloudSignal MQTT Demo</h1>
  
  <div class="card">
    <div id="status" class="status disconnected">βšͺ Not Connected</div>
    <button id="connectBtn">Connect</button>
    <button id="disconnectBtn" disabled>Disconnect</button>
  </div>

  <div class="card">
    <h3>Subscribe</h3>
    <input type="text" id="subTopic" placeholder="topic/to/subscribe" value="test/#">
    <button id="subscribeBtn" disabled>Subscribe</button>
  </div>

  <div class="card">
    <h3>Publish</h3>
    <input type="text" id="pubTopic" placeholder="topic" value="test/hello">
    <input type="text" id="pubMessage" placeholder="message" value='{"greeting": "hello"}'>
    <button id="publishBtn" disabled>Publish</button>
  </div>

  <div class="card">
    <h3>Messages</h3>
    <div id="messages"></div>
  </div>

  <div class="card">
    <h3>Debug Log</h3>
    <div id="log"></div>
  </div>

  <script src="https://unpkg.com/@cloudsignal/[email protected]/dist/index.global.js"></script>
  <script>
    // DOM elements
    const statusEl = document.getElementById('status');
    const messagesEl = document.getElementById('messages');
    const logEl = document.getElementById('log');
    const connectBtn = document.getElementById('connectBtn');
    const disconnectBtn = document.getElementById('disconnectBtn');
    const subscribeBtn = document.getElementById('subscribeBtn');
    const publishBtn = document.getElementById('publishBtn');

    let client = null;

    // Logging helper
    function log(msg) {
      const div = document.createElement('div');
      div.className = 'log';
      div.textContent = `[${new Date().toLocaleTimeString()}] ${msg}`;
      logEl.prepend(div);
      console.log(msg);
    }

    // Update UI based on connection state
    function updateUI(connected) {
      statusEl.textContent = connected ? '🟒 Connected' : 'πŸ”΄ Disconnected';
      statusEl.className = `status ${connected ? 'connected' : 'disconnected'}`;
      connectBtn.disabled = connected;
      disconnectBtn.disabled = !connected;
      subscribeBtn.disabled = !connected;
      publishBtn.disabled = !connected;
    }

    // Connect
    connectBtn.onclick = async () => {
      log('Connecting...');
      
      client = new CloudSignal.default({
        tokenServiceUrl: 'https://auth.cloudsignal.app',
        preset: 'desktop',
        debug: true,
      });

      client.onConnectionStatusChange = (connected) => {
        log(`Connection status: ${connected}`);
        updateUI(connected);
      };

      client.onAuthError = (error) => {
        log(`Auth error: ${error.message}`);
        updateUI(false);
      };

      client.onReconnecting = (attempt) => {
        log(`Reconnecting... attempt ${attempt}`);
      };

      client.onMessage((topic, message) => {
        const div = document.createElement('div');
        div.className = 'message';
        div.textContent = `[${topic}] ${message}`;
        messagesEl.prepend(div);
        log(`Message on ${topic}`);
      });

      try {
        // REPLACE THESE WITH YOUR CREDENTIALS
        await client.connectWithToken({
          host: 'wss://connect.cloudsignal.app:18885/',
          organizationId: 'YOUR_ORG_ID',
          secretKey: 'YOUR_SECRET_KEY',
          userEmail: '[email protected]',
        });
        log('Connected successfully');
      } catch (error) {
        log(`Connection failed: ${error.message}`);
      }
    };

    // Disconnect
    disconnectBtn.onclick = () => {
      log('Disconnecting...');
      client?.destroy();
      client = null;
      updateUI(false);
    };

    // Subscribe
    subscribeBtn.onclick = async () => {
      const topic = document.getElementById('subTopic').value;
      if (!topic) return alert('Enter a topic');
      
      try {
        await client.subscribe(topic);
        log(`Subscribed to: ${topic}`);
      } catch (error) {
        log(`Subscribe failed: ${error.message}`);
      }
    };

    // Publish
    publishBtn.onclick = () => {
      const topic = document.getElementById('pubTopic').value;
      const message = document.getElementById('pubMessage').value;
      if (!topic || !message) return alert('Enter topic and message');

      try {
        // Try to parse as JSON, otherwise send as string
        let payload;
        try {
          payload = JSON.parse(message);
        } catch {
          payload = message;
        }
        
        client.transmit(topic, payload);
        log(`Published to ${topic}: ${message}`);
      } catch (error) {
        log(`Publish failed: ${error.message}`);
      }
    };
  </script>
</body>
</html>

Minimal Example

Absolute minimum code:

<script src="https://unpkg.com/@cloudsignal/[email protected]/dist/index.global.js"></script>
<script>
(async () => {
  const client = new CloudSignal.default({
    tokenServiceUrl: 'https://auth.cloudsignal.app',
  });
  
  client.onMessage((topic, msg) => console.log(topic, msg));
  
  await client.connectWithToken({
    host: 'wss://connect.cloudsignal.app:18885/',
    organizationId: 'ORG_ID',
    secretKey: 'SECRET_KEY',
    userEmail: '[email protected]',
  });
  
  await client.subscribe('test/#');
  client.transmit('test/hello', { ts: Date.now() });
})();
</script>

Running Locally

To avoid CORS issues during development, serve your HTML file via a local server:

# Python 3
python -m http.server 8080

# Node.js
npx serve .

# PHP
php -S localhost:8080

Then open http://localhost:8080

Browser Compatibility

The SDK works in all modern browsers:

  • Chrome 80+
  • Firefox 75+
  • Safari 13.1+
  • Edge 80+

For older browsers, you may need polyfills for fetch, Promise, and TextEncoder/TextDecoder.

Common Issues

CloudSignal.default is undefined

Make sure you're using CloudSignal.default not just CloudSignal:

// Correct
const client = new CloudSignal.default({ ... });

// Wrong
const client = new CloudSignal({ ... });

CORS Errors

If you see CORS errors, ensure you're:

  1. Using the correct service URL (https://auth.cloudsignal.app)
  2. Serving your HTML from a web server (not file://)

Connection Failed

Check:

  1. Organization ID is correct
  2. Secret key is valid
  3. Token service URL is https://auth.cloudsignal.app