a

Building Embedded Analytics on Elasticsearch Without Code | No SDK Required

Building Embedded Analytics on Elasticsearch Without Code No SDK Required

TL;DR

Building embedded Elasticsearch analytics from scratch takes 6-8 weeks (query layer, charting, dashboard framework, multi-tenancy). No-code platforms let you ship the same result in 1-2 days with ~15 lines of integration code. You get native Elasticsearch queries, automatic tenant isolation via tokens, and React/Vue components out of the box – without building infrastructure.

Table of Contents

You’re a developer. Your Elasticsearch cluster is running. Your PM wants customer-facing dashboards embedded in your app by next sprint.

The “standard” path involves weeks of work: building an aggregation layer, creating visualization components, implementing multi-tenancy, handling authentication, and maintaining it forever.

There’s an easier path.

The Traditional Approach (And Why Developers Abandon It)

What “Build It Yourself” Actually Looks Like

Step 1: Query Layer (Week 1-2)

// elasticsearch-service.js

class ElasticsearchService {

  async getAggregation(index, query, tenantId) {

    // Build aggregation query

    // Handle pagination

    // Implement caching

    // Add tenant filtering

    // Error handling

    // Rate limiting

    // Query optimization

  }

}

Step 2: Visualization Components (Week 2-4)

// You're now building a charting library

import * as d3 from 'd3';

class TimeSeriesChart {

  // Responsive sizing

  // Axis formatting

  // Tooltip handling

  // Legend management

  // Animation

  // Accessibility

  // Theme support

  // Export functionality

}

Step 3: Dashboard Framework (Week 4-6)

// Dashboard state, layout, filtering, drill-down...

class DashboardManager {

  // Widget layout engine

  // Cross-widget filtering

  // State persistence

  // URL parameter handling

  // Real-time updates

}

Step 4: Multi-Tenancy & Security (Week 6-8)

// The part that keeps you up at night

class TenantIsolationService {

  // Token validation

  // Query injection prevention

  // Tenant context propagation

  // Audit logging

  // Permission checking

}

Total: 6-8 weeks minimum, then ongoing maintenance forever.

Most teams abandon this approach around week 3 when they realize they’re building a BI platform, not shipping their product.

The No-Code Approach: How It Works

Modern embedded analytics platforms connect directly to Elasticsearch and handle the complexity for you.

What You Actually Write

// Your entire Elasticsearch embedded analytics integration

// 1. Backend: Generate secure embed token (5 lines)
app.get('/api/analytics-token', authenticate, (req, res) => {
  const token = knowi.generateEmbedToken({
    userId: req.user.id,
    tenantId: req.user.organizationId,
    dashboardId: 'customer-overview'
  });
  res.json({ token });
});

// 2. Frontend: Embed the dashboard (10 lines)
import { EmbedSDK } from '@knowi/embed';

function AnalyticsDashboard() {
  const containerRef = useRef(null);

  useEffect(() => {
    const token = await fetch('/api/analytics-token').then(r => r.json());
    const dashboard = new EmbedSDK({
      container: containerRef.current,
      token: token.token
    });
    dashboard.render();
  }, []);

  return <div ref={containerRef} style={{ height: '600px' }} />;
}

Total: 15 lines of code. Dashboards ship today.


React Integration Example

Complete Working Component

// AnalyticsDashboard.jsx
import React, { useEffect, useRef, useState } from 'react';

const AnalyticsDashboard = ({ dashboardId, filters = {} }) => {
  const containerRef = useRef(null);
  const dashboardRef = useRef(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    const initDashboard = async () => {
      try {
        // Get embed token from your backend
        const response = await fetch('/api/analytics/embed-token', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ dashboardId })
        });

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

        // Initialize dashboard
        dashboardRef.current = new window.KnowiEmbed({
          container: containerRef.current,
          token,

          // Theme to match your app
          theme: {
            primaryColor: '#4F46E5',
            fontFamily: 'Inter, system-ui, sans-serif'
          },

          // Remove all third-party branding
          whiteLabel: true,

          // Event handlers
          onLoad: () => setLoading(false),
          onError: (err) => setError(err.message),
          onClick: (data) => console.log('Chart clicked:', data)
        });

        await dashboardRef.current.render();
      } catch (err) {
        setError(err.message);
        setLoading(false);
      }
    };

    initDashboard();

    return () => {
      dashboardRef.current?.destroy();
    };
  }, [dashboardId]);

  // Update filters when they change
  useEffect(() => {
    if (dashboardRef.current && Object.keys(filters).length > 0) {
      dashboardRef.current.setFilters(filters);
    }
  }, [filters]);

  if (error) {
    return <div className="error">Failed to load analytics: {error}</div>;
  }

  return (
    <div className="analytics-container">
      {loading && <div className="loading-spinner">Loading...</div>}
      <div ref={containerRef} style={{ height: '100%', minHeight: '500px' }} />
    </div>
  );
};

export default AnalyticsDashboard;

Usage in Your App

// CustomerPortal.jsx
import AnalyticsDashboard from './AnalyticsDashboard';

function CustomerPortal() {
  const [dateRange, setDateRange] = useState('7d');

  return (
    <div className="portal">
      <header>
        <h1>Your Analytics</h1>
        <select value={dateRange} onChange={e => setDateRange(e.target.value)}>
          <option value="24h">Last 24 Hours</option>
          <option value="7d">Last 7 Days</option>
          <option value="30d">Last 30 Days</option>
        </select>
      </header>

      <AnalyticsDashboard
        dashboardId="customer-overview"
        filters={{ dateRange }}
      />
    </div>
  );
}

Vue.js Integration Example

<!-- AnalyticsDashboard.vue -->
<template>
  <div class="analytics-wrapper">
    <div v-if="loading" class="loading">Loading analytics...</div>
    <div v-if="error" class="error">{{ error }}</div>
    <div ref="dashboardContainer" class="dashboard-container"></div>
  </div>
</template>

<script>
export default {
  name: 'AnalyticsDashboard',
  props: {
    dashboardId: { type: String, required: true },
    filters: { type: Object, default: () => ({}) }
  },
  data() {
    return {
      loading: true,
      error: null,
      dashboard: null
    };
  },
  async mounted() {
    try {
      const { token } = await this.$http.post('/api/analytics/embed-token', {
        dashboardId: this.dashboardId
      });

      this.dashboard = new window.KnowiEmbed({
        container: this.$refs.dashboardContainer,
        token,
        whiteLabel: true,
        theme: {
          primaryColor: this.$vuetify?.theme?.currentTheme?.primary || '#1976D2'
        },
        onLoad: () => { this.loading = false; },
        onError: (err) => { this.error = err.message; }
      });

      await this.dashboard.render();
    } catch (err) {
      this.error = err.message;
      this.loading = false;
    }
  },
  watch: {
    filters: {
      deep: true,
      handler(newFilters) {
        this.dashboard?.setFilters(newFilters);
      }
    }
  },
  beforeDestroy() {
    this.dashboard?.destroy();
  }
};
</script>

What Happens Behind the Scenes

When you use a no-code embedded analytics platform with Elasticsearch:

1. Direct Elasticsearch Connection

The platform connects natively to your Elasticsearch cluster, no ETL, no data copying.

# Connection configuration (done in UI, not code)
datasource:
  type: elasticsearch
  host: your-cluster.es.amazonaws.com
  port: 9243
  authentication: api_key
  indices: logs-*, metrics-*, events-*

2. Query Optimization

Native Elasticsearch queries are generated automatically:

{
  "query": {
    "bool": {
      "filter": [
        { "term": { "tenant_id": "{{tenant_from_token}}" } },
        { "range": { "@timestamp": { "gte": "now-7d" } } }
      ]
    }
  },
  "aggs": {
    "events_over_time": {
      "date_histogram": {
        "field": "@timestamp",
        "calendar_interval": "hour"
      }
    }
  }
}

The {{tenant_from_token}} is automatically injected from the embed token, you never write tenant filtering logic.

3. Visualization Rendering

Charts render in the embedded container with:

  • Responsive sizing
  • Interactive tooltips
  • Drill-down support
  • Export capabilities
  • Accessibility compliance

4. Real-Time Updates

Data refreshes automatically based on your configuration:

  • Polling intervals
  • WebSocket connections for streaming data
  • Manual refresh via SDK methods

For a complete architecture overview, see Embedded Analytics Architecture for SaaS.

Building Dashboards Without Code

The dashboard building happens in a visual interface, not in code.

Visual Query Builder

Instead of writing Elasticsearch JSON:

// You don't write this
{
  "aggs": {
    "status_breakdown": {
      "terms": { "field": "status.keyword", "size": 10 },
      "aggs": {
        "avg_duration": { "avg": { "field": "duration_ms" } }
      }
    }
  }
}

You drag and drop:

  1. Select index: logs-*
  2. Drag status to Group By
  3. Drag duration_ms to Metrics, select Average
  4. Choose visualization: Bar Chart

Native Elasticsearch Query Support

For complex queries, write native Elasticsearch syntax directly:

{
  "query": {
    "bool": {
      "must": [
        { "match": { "message": "error" } }
      ],
      "filter": [
        { "range": { "@timestamp": { "gte": "now-24h" } } }
      ]
    }
  },
  "aggs": {
    "error_types": {
      "significant_terms": { "field": "error.type.keyword" }
    }
  }
}

For query-building guidance, see Building Elasticsearch Queries Using Knowi.

Multi-Tenancy: Zero Code Required

The platform handles tenant isolation automatically.

How Token-Based Tenancy Works

// Backend: Include tenant in token
const token = generateEmbedToken({
  tenantId: customer.organizationId,  // This is all you specify
  dashboardId: 'main'
});

What happens automatically:

  1. Token contains encrypted tenant context
  2. Every Elasticsearch query includes tenant filter
  3. Impossible for queries to cross tenant boundaries
  4. No per-customer configuration needed

Compare to Manual Implementation

// Without a platform, you'd build:
class TenantQueryService {
  async executeQuery(query, tenantId) {
    // Validate tenantId
    // Inject tenant filter into query
    // Verify filter wasn't bypassed
    // Audit log the query
    // Execute with tenant context
    // Verify results belong to tenant
    // Handle errors without leaking tenant info
  }
}

// 200+ lines of security-critical code

Feature Comparison: Build vs No-Code

CapabilityBuild YourselfNo-Code Platform
Time to first dashboard6-8 weeks1-2 days
Elasticsearch query optimizationYou build itBuilt-in
Visualization libraryYou build/integrate30+ chart types included
Multi-tenancyYou build itAutomatic
White-labelingYou build itConfiguration
Mobile responsiveYou build itBuilt-in
Real-time updatesYou build itBuilt-in
Export (PDF, CSV)You build itBuilt-in
Maintenance burdenOngoingPlatform handles
Security responsibility100% yoursShared with platform

When “No-Code” Still Needs Code

To be clear: “no-code” refers to building dashboards and visualizations. You still write code for:

  1. Token generation (5-10 lines in your backend)
  2. Embed component (10-20 lines in your frontend)
  3. Custom event handling (optional, for drill-down navigation)

What you don’t write:

  • Query execution layer
  • Visualization components
  • Dashboard framework
  • Multi-tenant security
  • Caching infrastructure
  • Real-time update logic

Getting Started

Step 1: Connect Elasticsearch

In the platform UI:

  1. Add datasource → Elasticsearch
  2. Enter connection details
  3. Select indices to expose

Step 2: Build Dashboard

  1. Create new dashboard
  2. Add widgets using visual builder or native queries
  3. Configure filters and interactions
  4. Preview with sample data

Step 3: Generate Embed Code

  1. Enable embedding for dashboard
  2. Copy SDK snippet
  3. Integrate token generation in backend

Step 4: Ship

<AnalyticsDashboard dashboardId=”customer-metrics” />

For a complete walkthrough, see The Complete Guide to Embedded Analytics with Knowi.

The Bottom Line

Building embedded Elasticsearch analytics from scratch is a multi-month project that becomes a permanent maintenance burden.

No-code platforms let you:

  • Ship dashboards in days, not months
  • Focus engineering on your core product
  • Get native Elasticsearch performance without building infrastructure
  • Scale to thousands of tenants without additional configuration

The code you write is integration code, not infrastructure code.

Next Steps

Ready to skip the build phase?

Start Free Trial →

Frequently Asked Questions

What does “no-code” mean for Elasticsearch embedded analytics?

“No-code” means you can build dashboards, visualizations, and multi-tenant configurations without writing application logic.
You still write minimal integration code, typically:

  • 5–10 lines for backend token generation
  • 10–20 lines for frontend embedding

What you don’t build from scratch:

  • Elasticsearch query layer
  • Visualization components
  • Dashboard framework
  • Multi-tenant isolation logic

Can I use native Elasticsearch queries with a no-code platform?

Yes. No-code platforms like Knowi support both:

  • Visual, drag-and-drop query builders for common aggregations
  • Native Elasticsearch JSON queries for advanced use cases

You can switch to raw Elasticsearch DSL for:

  • Significant terms
  • Nested aggregations
  • Geo queries
  • Custom filters and scripts

How does a no-code platform connect to my Elasticsearch cluster?

The platform connects directly to Elasticsearch using native APIs.
There are:

  • No ODBC drivers
  • No SQL translation layers
  • No data replication or ETL

You provide:

  • Cluster host and port
  • Authentication details
  • Indices to expose

All queries run in real time against your Elasticsearch cluster.

Is no-code embedded analytics secure for multi-tenant SaaS?

Yes. Security is handled through token-based embedding.

Your backend generates a cryptographically signed token that includes:

  • Tenant ID
  • Access scope
  • Optional filters

Every Elasticsearch query is automatically scoped to the tenant’s data.
Tenants cannot access each other’s data, and no per-customer security rules are required.

How do I integrate Elasticsearch embedded analytics with React or Vue?

The flow is the same for both frameworks:

  1. Request a secure embed token from your backend
  2. Initialize the embed SDK with:
    • Token
    • Dashboard ID
    • DOM container

The SDK handles:

  • Rendering
  • Theming
  • Events
  • Filter synchronization

Typical integration is under 30 lines of code.

How long does it take to go from Elasticsearch data to embedded dashboards?

Most teams ship their first embedded dashboard in 1–2 days.

Typical timeline:

  • Connect Elasticsearch: minutes
  • Build dashboards: a few hours
  • Embed and secure with tokens: a few hours

Building the same capability in-house usually takes 6–8 weeks.

Can I join Elasticsearch data with SQL databases in a no-code platform?

Yes. Platforms like Knowi support query-time federation.

You can join Elasticsearch with:

  • MySQL
  • PostgreSQL
  • MongoDB
  • REST APIs
  • Other supported data sources

All joins happen at query time, without ETL pipelines or data duplication.

Share This Post

Share on facebook
Share on linkedin
Share on twitter
Share on email
About the Author:

RELATED POSTS