DEV Community

Vedika Intelligence
Vedika Intelligence

Posted on

Beyond the Loading Spinner: Implementing Real-time Features with SSE and Vedika API [2026-01]

In today's fast-paced web applications, users expect instant feedback. Traditional request-response cycles leave users staring at loading spinners, creating a disconnected experience. What if your astrology app could provide live insights as they're being generated? That's where Server-Sent Events (SSE) come in.

The Problem with Traditional APIs

Imagine building an astrology application where users submit their birth details and receive personalized insights. With a traditional REST API approach:

  1. User submits birth details
  2. Spinner appears
  3. User waits for complete response
  4. All insights appear at once

This approach has several drawbacks:

  • No feedback during processing
  • Poor perceived performance
  • No way to show progressive insights
  • Frustrating user experience

Introducing Server-Sent Events (SSE)

Server-Sent Events provide a way for servers to push updates to clients over a single HTTP connection. Unlike WebSockets, SSE is simpler to implement and works over standard HTTP ports.

Key advantages of SSE:

  • Unidirectional (server → client)
  • Automatic reconnection
  • Standard event types
  • Easy implementation with existing HTTP servers

Implementing SSE with the Vedika API

Let's build a real-time astrology insights interface using the Vedika API with SSE.

Step 1: Setting Up the SSE Connection

First, let's establish our SSE connection to the Vedika API:

// Connect to Vedika API with SSE
const vedikaConnection = new EventSource('/api/vedika-stream');

vedikaConnection.addEventListener('message', (event) => {
  const data = JSON.parse(event.data);
  handleVedikaUpdate(data);
});

vedikaConnection.addEventListener('error', (err) => {
  console.error('SSE Error:', err);
  // Implement reconnection logic
});
Enter fullscreen mode Exit fullscreen mode

Step 2: Processing Astrology Insights in Real-time

Now, let's handle the streaming insights:

function handleVedikaUpdate(data) {
  const insightsContainer = document.getElementById('insights');

  if (data.type === 'insight') {
    const insightElement = document.createElement('div');
    insightElement.className = 'insight-item';
    insightElement.innerHTML = `
      <h3>${data.category}</h3>
      <p>${data.insight}</p>
      <div class="confidence">Confidence: ${data.confidence}%</div>
    `;
    insightsContainer.appendChild(insightElement);

    // Smooth scroll to latest insight
    insightElement.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
  } 
  else if (data.type === 'progress') {
    updateProgress(data.percentage);
  }
  else if (data.type === 'complete') {
    vedikaConnection.close();
    showCompletionMessage();
  }
}
Enter fullscreen mode Exit fullscreen mode

Step 3: Backend Implementation with Express.js

Here's how to implement the SSE endpoint on your server:

const express = require('express');
const app = express();
const vedikaApi = require('./vedika-client');

app.post('/api/vedika-stream', async (req, res) => {
  // Set SSE headers
  res.writeHead(200, {
    'Content-Type': 'text/event-stream',
    'Cache-Control': 'no-cache',
    'Connection': 'keep-alive',
    'Access-Control-Allow-Origin': '*'
  });

  // Send initial connection confirmation
  res.write(`data: ${JSON.stringify({ type: 'connected' })}\n\n`);

  try {
    // Process birth details from request
    const { question, birthDetails } = req.body;

    // Stream insights as they're generated
    await vedikaApi.streamInsights(question, birthDetails, (insight) => {
      res.write(`data: ${JSON.stringify(insight)}\n\n`);
    });

    // Send completion signal
    res.write(`data: ${JSON.stringify({ type: 'complete' })}\n\n`);
    res.end();
  } catch (error) {
    res.write(`data: ${JSON.stringify({ type: 'error', message: error.message })}\n\n`);
    res.end();
  }
});
Enter fullscreen mode Exit fullscreen mode

Step 4: Client-Side Integration

Let's tie everything together in our React component:

import React, { useState, useEffect } from 'react';

const AstrologyInsights = () => {
  const [birthDetails, setBirthDetails] = useState({
    datetime: '',
    latitude: '',
    longitude: ''
  });
  const [question, setQuestion] = useState('');
  const [insights, setInsights] = useState([]);
  const [progress, setProgress] = useState(0);
  const [isAnalyzing, setIsAnalyzing] = useState(false);

  useEffect(() => {
    let eventSource;

    if (isAnalyzing) {
      eventSource = new EventSource(`/api/vedika-stream?question=${encodeURIComponent(question)}&datetime=${birthDetails.datetime}&lat=${birthDetails.latitude}&lng=${birthDetails.longitude}`);

      eventSource.onmessage = (event) => {
        const data = JSON.parse(event.data);

        if (data.type === 'insight') {
          setInsights(prev => [...prev, data]);
        } else if (data.type === 'progress') {
          setProgress(data.percentage);
        } else if (data.type === 'complete') {
          eventSource.close();
          setIsAnalyzing(false);
        }
      };

      eventSource.onerror = (err) => {
        console.error('SSE Error:', err);
        eventSource.close();
        setIsAnalyzing(false);
      };
    }

    return () => {
      if (eventSource) {
        eventSource.close();
      }
    };
  }, [isAnalyzing, question, birthDetails]);

  const handleSubmit = (e) => {
    e.preventDefault();
    setIsAnalyzing(true);
    setInsights([]);
    setProgress(0);
  };

  return (
    <div className="astrology-container">
      <form onSubmit={handleSubmit}>
        {/* Form fields for birth details and question */}
        <button type="submit" disabled={isAnalyzing}>
          {isAnalyzing ? 'Analyzing...' : 'Get Insights'}
        </button>
      </form>

      {isAnalyzing && (
        <div className="progress-bar">
          <div style={{ width: `${progress}%` }}></div>
          <span>{progress}% Complete</span>
        </div>
      )}

      <div className="insights-container">
        {insights.map((insight, index) => (
          <div key={index} className="insight-card">
            <h3>{insight.category}</h3>
            <p>{insight.insight}</p>
            <div className="confidence">Confidence: {insight.confidence}%</div>
          </div>
        ))}
      </div>
    </div>
  );
};
Enter fullscreen mode Exit fullscreen mode

Practical Tips and Gotchas

  1. Connection Management: Always implement proper error handling and reconnection logic. Network interruptions are common.

  2. Memory Management: For long-lived SSE connections, implement a timeout to close inactive connections.

  3. Message Batching: Consider batching multiple insights together to reduce network overhead.

  4. Security: Be cautious with sensitive data in SSE endpoints. Use proper authentication and validation.

  5. Fallback Options: Not all browsers support SSE natively. Consider implementing a fallback to traditional polling for older browsers.

  6. Backpressure: If the client can't process messages fast enough, implement a mechanism to signal the server to slow down.

Conclusion

Implementing SSE with the Vedika API transforms your astrology application from a static experience to a dynamic, engaging one. By streaming insights as they're generated, you provide immediate value to users and create a more natural interaction flow.

Next Steps

  1. Explore adding more event types (like insight_update for partial insights)
  2. Implement client-side caching for insights
  3. Add a retry mechanism with exponential backoff
  4. Consider integrating with WebSockets for bidirectional communication if needed
  5. Optimize your backend to handle concurrent SSE connections efficiently

The future of web applications is real-time, and SSE provides an elegant, efficient way to bring that experience to your users without the complexity of full bidirectional communication.

Top comments (0)