DEV Community

Rohit
Rohit

Posted on

Fully-interactive analytics for your Next.js App

If you're looking to launch fully-interactive analytics in your app but don't want to take on the scope of building it all in-house — which can be monumental (read here to learn why) — you've come to the right place.

The fastest way to launch analytics in your product is by decoupling analytic content from your application code. Why? Because this separation doubles your shipping velocity. It allows you to modify analytics independently — adding new visuals or tweaking existing ones — without touching your product code. As a result, your dashboards can evolve without requiring you to rebuild and redeploy your app.

This approach creates two parallel, non-blocking paths for executing your product roadmap. Dashboard development is a highly iterative process that can occur independently without involving your core product team. It also scales seamlessly as the scope of your product grows. Your product engineers can focus on developing core features, while customer success teams create personalized analytics experiences for clients. These complementary, non-blocking efforts allow you to ship faster and in a more modular way. Let's see it in action.

For a quick start, you can simply clone this Git repository and run it locally on your machine as shown below. This repository includes a demo dashboard.

git clone git@github.com:rohitspujari/nextjs-semaphor-demo.git
cd nextjs-semaphor-demo
npm install
npm run dev
Enter fullscreen mode Exit fullscreen mode

The remainder of this blog post provides a detailed, step-by-step walkthrough of the code.

Step 1: Request Semaphor free trial here.

Once you log in, you'll see a demo dashboard created for you. With Semaphor, you can connect to any SQL-compatible data source, including CSV files, Parquet files in Amazon S3, or responses from REST APIs.

Step 2: Create a dashboard using natural language, SQL, or Python.

The Semaphor console allows you to customize the dashboard's appearance—including colors, fonts, corner styles, and layouts for various devices—giving you precise control over how it renders in your app. See a sneak peak here.

Step 3: Integrate the dashboard into your Next JS app.

Create a new Next.js app. Skip this step if you already have an existing one.

npx create-next-app@latest

✔ What is your project named? nextjs-semaphor-demo
✔ Would you like to use TypeScript? Yes
✔ Would you like to use ESLint? Yes
✔ Would you like to use Tailwind CSS? Yes
✔ Would you like to use `src/` directory? Yes
✔ Would you like to use App Router? (recommended) Yes
✔ Would you like to customize the default import alias (@/\*)? No

cd nextjs-semaphor-demo
Enter fullscreen mode Exit fullscreen mode

Install the Semaphor package and start the app.

npm i semaphor@latest
npm run dev
Enter fullscreen mode Exit fullscreen mode

Now create a client component dashboard-component.tsx as a container for your Semaphor dashboard. Note that the Semaphor dashboard is designed as a client component because it needs to support UI interactions such as drop-downs and on-click events.

src/components/dashboard-component.tsx

'use client';
import dynamic from 'next/dynamic';
import { type AuthToken } from 'semaphor';
import 'semaphor/style.css'; // IMPORTANT! Impport the CSS file. This is the default style, you can customize it.

// Dynamic import to prevent server-side rendering.
const Dashboard = dynamic(
  () => import('semaphor').then((mod) => mod.Dashboard),
  {
    ssr: false,
  }
);

type DashboardProps = {
  authToken: AuthToken;
};

export default function DashboardComponent({ authToken }: DashboardProps) {
  return <Dashboard authToken={authToken} />; // one line of code to render the dashboard
}
Enter fullscreen mode Exit fullscreen mode

The DashboardComponent accepts AuthToken as a prop, authorizing the user to view the dashboard. This token-based approach allows dynamically display different dashboard depending on your app user or tenant.

To generate the AuthToken you need dashboard credentials. You can get your dashboard id and dashboard secret from the Semaphor console.

IMPORTANT: You must use the server-side environment to request the token. This prevents the accidental exposure of the dashboard secret in client-side code. In Next.js, we can easily do that with a server-side function as shown below.

This function makes a simple fetch call to the Seamphor endpoint to generate the token. The use server notation ensures that this code only runs on the server.

src/server-utils.ts

'use server';

export async function postRequest<T>(
  url: string,
  data: Record<string, any> = {}
): Promise<T> {
  try {
    const response = await fetch(url, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(data),
    });

    if (!response.ok) {
      const errorResponse = await response.json();
      console.error(
        `Error: ${response.status} - ${response.statusText}`,
        errorResponse
      );
      throw new Error(`Request failed with status ${response.status}`);
    }

    const jsonResponse: T = await response.json();
    return jsonResponse;
  } catch (error) {
    console.error('Network or processing error:', error);
    throw error;
  }
}
Enter fullscreen mode Exit fullscreen mode

We're almost done. In your page.tsx file, you can use the postRequest server function as shown below.

Note that we use export const revalidate = 0 at the top of the page to tell Next.js not to cache the token during build time. This is important because Semaphor tokens expire every 30 minutes.

src/app/page.tsx

export const revalidate = 0; // This is to disable the Nextjs caching behavior.
import { AuthToken } from 'semaphor';
import DashboardComponent from './components/dashboard-component';
import { postRequest } from '@/server-utils';

const DASHBOARD_ID = 'd_cf007a8b-19bc-46ad-8787-2915445b7b86'; // Replace with your actual dashboard ID
const DASHBOARD_SECRET = 'ds_f32f0b30-b7e1-40f9-ba6a-9804a5b9d635'; // Replace with your actual dashboard secret
const TOKEN_URL = 'https://semaphor.cloud/api/v1/token';

export default async function HomePage() {
  // TODO: perform user authentication here

  // generate token for the user
  const token = await postRequest<AuthToken>(TOKEN_URL, {
    dashboardId: DASHBOARD_ID,
    dashboardSecret: DASHBOARD_SECRET,
  });

  return <DashboardComponent authToken={token} />;
}
Enter fullscreen mode Exit fullscreen mode

That's it! Refresh your page and see your fully interactive dashboard, powered by Semaphor, come to life.

In our next blog post, we'll explore how you can add multi-tenancy and row-level security to your Semaphor dashboards.

If you have any questions, feel free to drop us a note at support@semaphor.cloud

Top comments (0)