cloudsignal-websocket

Generate a production-grade React MQTT context for CloudSignal real-time notifications over WebSocket. Supports Clerk, Supabase, Auth0, Firebase, and custom OIDC auth providers. Use when implementing real-time notifications, live updates, job progress tracking, or WebSocket messaging with CloudSignal.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "cloudsignal-websocket" with this command: npx skills add cloudsignal/agent-skills/cloudsignal-agent-skills-cloudsignal-websocket

CloudSignal WebSocket — React MQTT Context Generator

Generate a production-grade React context provider for real-time messaging over CloudSignal's MQTT broker using WebSocket. The generated code handles the full connection lifecycle: authentication via external auth providers, reconnection, proactive token refresh, message routing, and cleanup.

What You Generate

  1. mqtt-context.tsx — React context provider with:

    • Auth-provider token exchange (Clerk, Supabase, Auth0, Firebase, or custom OIDC)
    • WebSocket connection to CloudSignal MQTT broker
    • Auth error circuit-breaker (max 3 retries, 10s delay)
    • Proactive token refresh at 50 minutes (before 60-min TTL expiry)
    • Exact topic routing with safe JSON parsing
    • React StrictMode double-mount protection
    • Tab visibility reconnection
    • Typed subscription hooks (jobs, notifications, transactions, or custom)
  2. cloudsignal.d.ts — TypeScript declarations for @cloudsignal/mqtt-client (the npm package does not ship types)

Before You Start

Ask the user for these inputs (use defaults if not provided):

InputExampleDefault
Auth providerClerk, Supabase, Auth0, FirebaseAsk (required)
Organization IDorg_k7xm4pqr2n5tAsk (required)
Topic namespacemyappApp name from package.json
Message types needednotifications, jobs, transactionsAll three
Target directorysrc/lib/ or src/contexts/src/lib/

Generation Steps

Step 1: Read the Reference Implementation

Read references/mqtt-context.tsx in this skill's directory. This is the canonical reference — a production-tested context provider extracted from a live SaaS. Use it as the base for all generated code.

Step 2: Adapt the Auth Provider Hooks

The reference contains two placeholder functions that MUST be replaced based on the user's auth provider:

useCurrentUser() — must return { id: string } | null:

ProviderImplementation
Clerkimport { useUser } from "@clerk/nextjs"; const { user } = useUser(); return user ? { id: user.id } : null;
Supabaseimport { useSession } from "@supabase/auth-helpers-react"; const session = useSession(); return session ? { id: session.user.id } : null;
Auth0import { useAuth0 } from "@auth0/auth0-react"; const { user, isAuthenticated } = useAuth0(); return isAuthenticated && user ? { id: user.sub! } : null;
Firebaseimport { useAuthState } from "react-firebase-hooks/auth"; import { auth } from "@/lib/firebase"; const [user] = useAuthState(auth); return user ? { id: user.uid } : null;

useGetToken() — must return () => Promise<string | null>:

ProviderImplementation
Clerkimport { useAuth } from "@clerk/nextjs"; const { getToken } = useAuth(); return getToken;
Supabaseimport { useSupabaseClient } from "@supabase/auth-helpers-react"; const supabase = useSupabaseClient(); return async () => { const { data } = await supabase.auth.getSession(); return data.session?.access_token ?? null; };
Auth0import { useAuth0 } from "@auth0/auth0-react"; const { getAccessTokenSilently } = useAuth0(); return async () => { try { return await getAccessTokenSilently(); } catch { return null; } };
Firebaseimport { auth } from "@/lib/firebase"; return async () => auth.currentUser?.getIdToken() ?? null;

Step 3: Customize Message Types

Replace the reference message interfaces with the user's domain. Keep the structure (interface + handler type + registry pattern) but adapt field names and types.

Default message types from reference: ProgressMessage, StatusMessage, TransactionMessage, NotificationMessage.

Step 4: Set Configuration Constants

const CLOUDSIGNAL_ORG_ID = process.env.NEXT_PUBLIC_CLOUDSIGNAL_ORG_ID;
const CLOUDSIGNAL_HOST = process.env.NEXT_PUBLIC_CLOUDSIGNAL_HOST || "wss://connect.cloudsignal.app:18885/";
const TOPIC_ROOT = "{user's namespace}";

Step 5: Write the Type Declarations

Read references/cloudsignal.d.ts and write it to the user's types/ directory (or wherever their project keeps type declarations). This file is required because @cloudsignal/mqtt-client does not ship .d.ts files.

Step 6: Write the Context Provider

Combine the adapted auth hooks, customized message types, and the full provider logic from the reference into the final mqtt-context.tsx. Preserve ALL of these production patterns:

  • Stable ref pattern: connectRef updated every render, used by timers
  • Auth error circuit-breaker: authErrorCountRef with MAX_AUTH_ERRORS = 3
  • Proactive token refresh: scheduleTokenRefresh() at 50 minutes
  • StrictMode guard: connectingRef + mountedRef prevent double connections
  • Exact topic matching: topic === \${prefix}/notifications`not.includes()`
  • Safe JSON parsing: try/catch around JSON.parse in message handler
  • Client destruction on auth error: Stops SDK's stale-token reconnect loop
  • Tab visibility reconnect: visibilitychange event listener

Step 7: Show Usage

Provide a usage example showing:

  1. Provider wrapping in app/providers.tsx (nested inside the auth provider)
  2. A consumer component using useMQTT() hook
  3. Environment variable setup (.env.local)

Critical SDK Pitfalls

Read references/sdk-pitfalls.md for the full list. These MUST be handled in generated code:

  1. Token expiry reconnect loop: Destroy client on onAuthError, don't rely on SDK reconnect
  2. externalToken not idToken: Use externalToken in connectWithToken()
  3. No TypeScript declarations: Always generate cloudsignal.d.ts
  4. React StrictMode double-mount: Use connectingRef + mountedRef guards
  5. Token service version: SDK v2.x expects /v2/tokens/exchange
  6. CJS require() breaks mqtt.connect(): Always use ESM import, never require()

Environment Variables

Tell the user to add these to .env.local:

NEXT_PUBLIC_CLOUDSIGNAL_ORG_ID=org_xxxxxxxxxxxxx    # From CloudSignal dashboard
NEXT_PUBLIC_CLOUDSIGNAL_HOST=wss://connect.cloudsignal.app:18885/  # Optional, this is default

CloudSignal Dashboard Setup

Remind the user they need to configure their CloudSignal organization:

  1. Create an organization at https://dashboard.cloudsignal.app
  2. Configure an External Auth Provider integration (select their provider, enter JWKS URL)
  3. Note the org_xxx ID for the environment variable

npm Dependency

The user needs to install the CloudSignal MQTT client:

npm install @cloudsignal/mqtt-client

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Automation

cloudsignal-rest

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

vercel-composition-patterns

React composition patterns that scale. Use when refactoring components with boolean prop proliferation, building flexible component libraries, or designing reusable APIs. Triggers on tasks involving compound components, render props, context providers, or component architecture. Includes React 19 API changes.

Repository Source
87.2K23.1Kvercel
Automation

vercel-react-native-skills

React Native and Expo best practices for building performant mobile apps. Use when building React Native components, optimizing list performance, implementing animations, or working with native modules. Triggers on tasks involving React Native, Expo, mobile performance, or native platform APIs.

Repository Source
61.2K23.1Kvercel
Automation

supabase-postgres-best-practices

Postgres performance optimization and best practices from Supabase. Use this skill when writing, reviewing, or optimizing Postgres queries, schema designs, or database configurations.

Repository Source
35.8K1.6Ksupabase