Setup
Install the SDK, configure tokens, and run Data Apps locally.
Install
For a new app, use the bootstrapper:
npx create-semaphor-app@latest my-data-app
cd my-data-app
npm run devOptional scaffold-time choice:
npx create-semaphor-app@latest my-data-app --shadcn-preset <preset-id><preset-id> is a shadcn preset from shadcn create,
not a Semaphor package or component registry.
The starter includes Semaphor components and samples by default, so there is no separate Semaphor component install step for new apps.
Use manual setup when you are adding Semaphor to an existing React app or you want to control the Vite/shadcn initialization yourself.
npm install react-semaphorUse the Data App SDK subpath:
import {
SemaphorDataAppProvider,
semaphor,
useSemaphorInput,
useSemaphorQuery,
} from 'react-semaphor/data-app-sdk';shadcn And Semaphor Components
If the app uses shadcn, initialize it with the customer's preset or style before adapting any component source.
npx shadcn@latest init --template viteWith a shadcn preset from shadcn create:
npx shadcn@latest init --preset <preset-id> --template viteFor new apps, create-semaphor-app already includes Semaphor source components
for query state, filters, KPI cards, server tables, matrix tables, and sample
dashboards. For existing apps, prefer your app's own UI components and copy or
adapt starter source only when you need those reusable mechanics. These
components do not replace react-semaphor/data-app-sdk.
Runtime Provider
Every query hook must run under SemaphorDataAppProvider.
import { SemaphorDataAppProvider } from 'react-semaphor/data-app-sdk';
export function DataAppRoot({
token,
children,
}: {
token: string;
children: React.ReactNode;
}) {
return (
<SemaphorDataAppProvider token={token}>
{children}
</SemaphorDataAppProvider>
);
}If the app is running inside Semaphor's published Data App runtime, the provider can read the runtime token automatically. For local development, pass a token explicitly.
API Base URL
Hosted Semaphor uses the API URL encoded in the token. For local development or a self-hosted environment, pass apiBaseUrl.
<SemaphorDataAppProvider
token={token}
apiBaseUrl="http://localhost:3000/api"
>
<App />
</SemaphorDataAppProvider>Token Handling
Generate tokens on your server. The browser should receive only the scoped access token it needs to render the Data App.
async function createDataAppToken() {
const response = await fetch('https://semaphor.cloud/api/v1/token', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
dashboardId: process.env.SEMAPHOR_DASHBOARD_ID,
dashboardSecret: process.env.SEMAPHOR_DASHBOARD_SECRET,
}),
});
if (!response.ok) {
throw new Error(`Token request failed: ${response.status}`);
}
return response.json();
}Keep secrets server-side
Do not ship dashboard secrets, project secrets, or long-lived tokens in browser code.
Suggested File Structure
For small experiments, one file is fine. For real apps, keep query ownership visible.
src/
data-app/
sources.ts
fields.ts
queries.ts
inputs.ts
components/
filters/
CampaignFilter.tsx
DateRangeFilter.tsx
insights/
RevenueKpi.tsx
RevenueByCampaign.tsx
OrdersTable.tsx
App.tsxThis structure helps humans and agents answer: "Which visual owns which query?"
Local Development Checklist
- Confirm the token can access the target project and semantic domain.
- Keep query specs source-bearing. Include
sourceon every field that comes from a semantic dataset. - Prefer semantic
metric,records,matrix, andanalysisqueries before SQL. - Add loading and error states to every visual.
- Use server-side pagination for large tables.
- Check
executionResultand relationship diagnostics when a query returns partial data or fails.