Documentation
← Back to Integrations

React Integration

Add real-time messaging to your React applications with hooks and components

Installation

bun add @postacksolutions/flux-relay-sdk

Custom Hook

Create a custom hook to manage Flux Relay state:

hooks/useFluxRelay.ts
import { useState, useEffect } from 'react';
import { FluxRelay, Conversation, Message } from '@postacksolutions/flux-relay-sdk';

export function useFluxRelay(serverId: string, apiKey: string) {
  const [client, setClient] = useState<FluxRelay | null>(null);
  const [conversations, setConversations] = useState<Conversation[]>([]);
  const [messages, setMessages] = useState<Record<string, Message[]>>({});
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<Error | null>(null);

  useEffect(() => {
    const init = async () => {
      try {
        const fluxRelay = new FluxRelay({
          apiUrl: 'https://flux.postacksolutions.com/api',
          serverId,
          apiKey,
        });

        // Authenticate user (replace with your auth logic)
        await fluxRelay.authenticateUser({
          externalUserId: 'user_123',
          username: 'john_doe',
        });

        // Load conversations
        const convos = await fluxRelay.getConversations();
        setConversations(convos);
        setClient(fluxRelay);
        setLoading(false);
      } catch (err) {
        setError(err as Error);
        setLoading(false);
      }
    };

    init();
  }, [serverId, apiKey]);

  const loadMessages = async (conversationId: string) => {
    if (!client) return;
    
    try {
      const msgs = await client.getMessages(conversationId);
      setMessages(prev => ({ ...prev, [conversationId]: msgs }));
    } catch (err) {
      setError(err as Error);
    }
  };

  const sendMessage = async (conversationId: string, content: string) => {
    if (!client) return;
    
    try {
      const message = await client.sendMessage(conversationId, {
        content,
        type: 'text',
      });
      
      setMessages(prev => ({
        ...prev,
        [conversationId]: [...(prev[conversationId] || []), message],
      }));
      
      return message;
    } catch (err) {
      setError(err as Error);
      throw err;
    }
  };

  return {
    client,
    conversations,
    messages,
    loading,
    error,
    loadMessages,
    sendMessage,
  };
}

Component Example

Use the hook in your components:

components/ChatApp.tsx
import { useFluxRelay } from './hooks/useFluxRelay';

export function ChatApp() {
  const {
    conversations,
    messages,
    loading,
    sendMessage,
    loadMessages,
  } = useFluxRelay('your-server-id', 'your-api-key');

  const [selectedConversation, setSelectedConversation] = useState<string | null>(null);

  useEffect(() => {
    if (selectedConversation) {
      loadMessages(selectedConversation);
    }
  }, [selectedConversation, loadMessages]);

  if (loading) {
    return <div>Loading...</div>;
  }

  return (
    <div className="flex h-screen">
      {/* Conversations List */}
      <div className="w-64 border-r">
        <h2 className="p-4 font-bold">Conversations</h2>
        {conversations.map(conv => (
          <div
            key={conv.id}
            onClick={() => setSelectedConversation(conv.id)}
            className={`p-4 cursor-pointer hover:bg-gray-100 ${
              selectedConversation === conv.id ? 'bg-slate-800' : ''
            }`}
          >
            {conv.name || `Chat with ${conv.participantIds.length} users`}
          </div>
        ))}
      </div>

      {/* Messages */}
      <div className="flex-1 flex flex-col">
        {selectedConversation && (
          <>
            <div className="flex-1 overflow-y-auto p-4">
              {(messages[selectedConversation] || []).map(msg => (
                <div key={msg.id} className="mb-4">
                  <div className="font-semibold">{msg.senderId}</div>
                  <div>{msg.content}</div>
                  <div className="text-sm text-gray-500">
                    {new Date(msg.createdAt).toLocaleString()}
                  </div>
                </div>
              ))}
            </div>
            <MessageInput
              onSend={(content) => sendMessage(selectedConversation, content)}
            />
          </>
        )}
      </div>
    </div>
  );
}

function MessageInput({ onSend }: { onSend: (content: string) => void }) {
  const [input, setInput] = useState('');

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    if (input.trim()) {
      onSend(input);
      setInput('');
    }
  };

  return (
    <form onSubmit={handleSubmit} className="p-4 border-t">
      <input
        type="text"
        value={input}
        onChange={(e) => setInput(e.target.value)}
        placeholder="Type a message..."
        className="w-full p-2 border rounded"
      />
      <button type="submit" className="mt-2 px-4 py-2 bg-[#d4d4d4] text-[#0a0a0a] rounded">
        Send
      </button>
    </form>
  );
}

Context Provider

Use React Context to share Flux Relay client across your app:

context/FluxRelayContext.tsx
import React, { createContext, useContext, ReactNode } from 'react';
import { FluxRelay } from '@postacksolutions/flux-relay-sdk';

interface FluxRelayContextType {
  client: FluxRelay | null;
  initialized: boolean;
}

const FluxRelayContext = createContext<FluxRelayContextType>({
  client: null,
  initialized: false,
});

export function FluxRelayProvider({
  children,
  serverId,
  apiKey,
}: {
  children: ReactNode;
  serverId: string;
  apiKey: string;
}) {
  const [client, setClient] = React.useState<FluxRelay | null>(null);
  const [initialized, setInitialized] = React.useState(false);

  React.useEffect(() => {
    const init = async () => {
      const fluxRelay = new FluxRelay({
        apiUrl: 'https://flux.postacksolutions.com/api',
        serverId,
        apiKey,
      });

      // Authenticate user
      await fluxRelay.authenticateUser({
        externalUserId: 'user_123',
        username: 'john_doe',
      });

      setClient(fluxRelay);
      setInitialized(true);
    };

    init();
  }, [serverId, apiKey]);

  return (
    <FluxRelayContext.Provider value={{ client, initialized }}>
      {children}
    </FluxRelayContext.Provider>
  );
}

export function useFluxRelayContext() {
  return useContext(FluxRelayContext);
}

Next Steps

  • Get your Server ID and API Key from your Flux Relay dashboard
  • Implement WebSocket support for real-time messaging (see API docs)
  • Check out the API Reference for all available endpoints
  • See the Next.js guide for Next.js-specific patterns