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 |
|---|---|
|
Human-readable project name. |
|
Project description, if set. |
|
Workspace domain (used to construct API URLs). |
|
Human-readable workspace name. |
|
Role of the current user in this project (for example, |
|
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:
GET /api/auth/status: returns thetenantanduser_idfor the authenticated user.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.
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.