logoSemaphor

iFrame

Learn how to use the iframe to embed the self-service analytics experience in your app.

Overview

Zero-Dependency Embeds with iFrame

When you embed Semaphor using an iFrame, you don’t need to bundle any analytics libraries, UI components, or dependencies into your application. Everything: visualization libraries, state management, styling, and interactive features lives fully within the Semaphor frame.

This gives you two major advantages:

  1. No extra dependencies in your codebase Your app stays lightweight. You’re not shipping chart libraries, SDKs, or custom components just to display analytics. Semaphor handles all of that inside the frame.

  2. Analytics stays isolated from your product code There’s no risk of CSS collisions, version conflicts, or package bloat. Semaphor runs in its own sandbox, so your product and your analytics never step on each other.

1. Obtain the Auth Token

Before rendering an iframe, you need to retrieve an Auth Token. This token ensures secure access to your embed session.

const PROJECT_ID = 'your-project-id';
const PROJECT_SECRET = 'your-project-secret';
const END_USER_ID = 'tenant-user-id';
const ALLOWED_SEMANTIC_DOMAINS = ['your-semantic-domain-id'];
const INITIAL_DASHBOARD = 'your-dashboard-id';
 

const TOKEN_URL = 'https://semaphor.cloud/api/v1/token';
 
const response = await fetch(url, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify(tokenRequest),
});
 
const authToken = await response.json();

Do not expose projectSecret in client-side code in production. Use a backend service to fetch the token securely.

2. Build the Embed URL

Use the token to generate the iframe URL. You can control the experience with query parameters.

const url = `https://semaphor.cloud/embed/${authToken?.accessToken}?showAssistant=true&showControls=true&currentTheme=light`; 

3. Render the Iframe

Render the iframe inside a responsive container.

<iframe src={url} width="100%" height="100%" /> 
src/App.tsx
import { useEffect, useState } from 'react';
 
const PROJECT_ID = 'your-project-id';
const PROJECT_SECRET = 'your-project-secret';
const END_USER_ID = 'tenant-user-id';
const ALLOWED_SEMANTIC_DOMAINS = ['your-semantic-domain-id'];
const INITIAL_DASHBOARD = 'your-dashboard-id';
 
const TOKEN_URL = 'https://semaphor.cloud/api/v1/token';
 
type AuthToken = {
  accessToken: string;
};
 
function App() {
  const [authToken, setAuthToken] = useState<AuthToken>();
 
  const tokenRequest = {
    projectId: PROJECT_ID,
    projectSecret: PROJECT_SECRET,
    endUserId: END_USER_ID,
    allowedSemanticDomains: ALLOWED_SEMANTIC_DOMAINS,
    initialDashboardId: INITIAL_DASHBOARD,
    allowEdit: true, // This will allow the user to edit the dashboard
    tokenExpiry: 60 * 30, // 30 minutes
    // sls: 'corp_a', // This will route the user to the corp_a schema
  };
 
  useEffect(() => {
    async function fetchToken() {
      try {
        const response = await fetch(TOKEN_URL, {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
          },
          body: JSON.stringify(tokenRequest),
        });
        if (!response.ok) {
          throw new Error(`HTTP error! status: ${response.status}`);
        }
 
        const token = await response.json();
        if (token?.accessToken) {
          setAuthToken(token);
        }
      } catch (error) {
        console.error('There was an error!', error);
      }
    }
    fetchToken();
  }, []);
 
  const url = `https://semaphor.cloud/embed/${authToken?.accessToken}?showAssistant=true&showControls=true&currentTheme=light`; 
 
  if (!authToken) {
    return <div>Loading...</div>;
  }
 
  return (
    <div style={{ width: '100%', height: '100vh' }}>
      <iframe src={url} width="100%" height="100%" />
    </div>
  );
}
 
export default App;

URL Parameters

  • showAssistant: Enable the AI assistant panel in the embed (true/false)
  • showControls: Show header controls for the embed (true/false)
  • currentTheme: Set theme for the embed (light, dark, or system)

Append these as query parameters to the embed URL as needed.

Key Considerations

  • Security: Always generate tokens server-side; never expose secrets in client code.
  • Sizing: Wrap the iframe in a container with explicit width/height for proper layout.
  • Token expiry: Use tokenExpiry in your token request to control session duration.

On this page