Building Dashboard Components#

Warning

Project Neo is currently in Technical Preview. Features described in this section may change before general availability.

Every dashboard in your extension is a standard React component. This page covers the component contract, available libraries, navigation, and TypeScript usage.

Component Signature#

Every dashboard component must accept a projectId prop. The host injects it automatically when rendering your dashboard.

interface Props {
  projectId: string;
}

export default function Analytics({ projectId }: Props) {
  return (
    <div className="p-6">
      <h1 className="text-xl font-semibold">Analytics</h1>
      <p className="text-sm text-muted-foreground">
        Showing data for project: {projectId}
      </p>
    </div>
  );
}

projectId is the identifier of the currently active Squirro project. Use it to scope API calls, display project-specific data, and construct URLs.

Project and User Context#

projectId is the only prop injected by the host. Additional context such as the project title, workspace, the current user role, or user identity is not passed directly. Fetch it from the Squirro API using the shared @tanstack/react-query library.

Fetching Project Metadata#

A single API call to GET /v0/projects/{projectId} returns the most commonly needed project fields:

Field

Description

title

Human-readable project name.

description

Project description, if set.

workspace

Workspace domain (used to construct API URLs).

workspace_title

Human-readable workspace name.

project_role

Role of the current user in this project (for example, admin, editor, viewer).

permissions

List of permission strings granted to the current user for this project.

Example using useQuery:

import { useQuery } from '@tanstack/react-query';

interface Project {
  id: string;
  title: string;
  description?: string;
  workspace?: string;
  workspace_title?: string;
  project_role?: string;
  permissions?: string[];
}

function Analytics({ projectId }: { projectId: string }) {
  const { data: project, isPending, isError } = useQuery<Project>({
    queryKey: ['project', projectId],
    queryFn: async () => {
      const response = await fetch(`/v0/projects/${projectId}`);
      if (!response.ok) throw new Error('Failed to fetch project');
      return response.json();
    },
  });

  if (isPending) return <p>Loading</p>;
  if (isError) return <p>Failed to load project.</p>;

  return (
    <div>
      <h1>{project.title}</h1>
      <p>Workspace: {project.workspace_title}</p>
      <p>Your role: {project.project_role}</p>
    </div>
  );
}

Fetching User Identity#

The current user identity is not available as a prop or a shared hook. Obtain it from the User API with two sequential requests:

  1. GET /api/auth/status: returns the tenant and user_id for the authenticated user.

  2. GET /api/user/v1/{tenant}/users/{user_id}: returns the user profile, including email and full name.

For full API reference and available user fields, see the Microservices APIs page.

Available Shared Libraries#

The following libraries are provided by the host application at runtime. You do not need to install them in your project.

Installed by the Scaffold (Do Not Bump These)#

These packages are included in the scaffolded package.json so that TypeScript can resolve their types during development. Do not change their versions independently. They must match the versions bundled into @squirro/nextgen-core.

Package

Description

react

JSX, hooks, and components.

react-dom

DOM rendering.

react-router-dom

useNavigate, Link, useParams, and other routing hooks.

Provided Only at Runtime (Do Not Add at All)#

These packages are not in the scaffolded package.json. The host supplies them exclusively at runtime via Module Federation. Do not add them to your package.json. Adding them causes duplicate versions and runtime errors.

Package

Description

zustand

Lightweight global state.

@tanstack/react-query

Data fetching, caching, and loading and error states.

i18next and react-i18next

Translations. For more information, see the Translations page.

Those libraries run as singletons shared with the host. Your dashboards share the same router context, query cache, and i18n instance as the host application, giving them full access to standard navigation and any cached data.

TypeScript#

TypeScript is fully configured in the generated project. TypeScript type-checks dashboard components against the shared library types automatically.

To check types manually:

npx tsc --noEmit

Avoid as for type casting. Use type guards or proper type narrowing instead:

// Avoid
const item = data as SearchResult;

// Prefer
function isSearchResult(value: unknown): value is SearchResult {
  return typeof value === 'object' && value !== null && 'id' in value;
}

Browser Support#

Project Neo targets the same browsers as the classic Squirro interface: the latest versions of Chrome, Edge, Firefox, and Safari. When choosing JavaScript or Web APIs for your dashboard components, you can rely on anything supported across those four browsers at their current release.

For the full client requirements, see the System Requirements page.

Runtime Environment#

Extensions run directly inside the host application’s JavaScript context via Module Federation. There is no iframe or Worker-based sandbox between extension code and the host: dashboards share the host’s React instance, router, query cache, and origin. Plan for the implications below before writing code that crosses a trust boundary.

Browser Storage#

Extensions share the same origin as the host and have full read and write access to localStorage and sessionStorage. Use a namespaced key prefix to avoid collisions with host data or other extensions:

localStorage.setItem('my-extension:user-preference', value);
const pref = localStorage.getItem('my-extension:user-preference');

Warning

Because all extensions share the same origin, any code running on the page can read any key in localStorage and sessionStorage. Do not store tokens, credentials, or other sensitive data there.

External APIs#

The Squirro instance is the only origin a dashboard can reach without additional setup. To call a third-party service, route the request through a server-side proxy you control rather than calling the external API directly from the browser. There is no built-in pass-through proxy for extension use.

Browser Permissions#

The host denies access to geolocation, microphone, and camera via the Permissions-Policy header. Extensions cannot request those browser APIs regardless of user consent.