@provenancekit/ui is a theme-aware React component library. Add a <ProvenanceBadge> to any piece of AI-generated content and users can instantly inspect its full provenance chain.
Installation
pnpm add @provenancekit/ui
@xyflow/react (the interactive graph engine) is included as a dependency and installed automatically — no extra steps needed.
Setup
1. Add the stylesheet
Import the design tokens and graph base styles once in your global CSS:
/* globals.css */
@import "@provenancekit/ui/styles.css";
This single import provides:
- All
--pk-* CSS custom properties (light and dark mode)
- ReactFlow base styles for
<ProvenanceGraph>
No additional CSS configuration required.
2. Wrap your app with the provider
// app/layout.tsx (Next.js App Router)
import { ProvenanceKitProvider } from "@provenancekit/ui";
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
<ProvenanceKitProvider
apiUrl="https://api.provenancekit.com"
apiKey={process.env.NEXT_PUBLIC_PK_API_KEY}
>
{children}
</ProvenanceKitProvider>
</body>
</html>
);
}
That’s it. Components auto-fetch provenance data and render correctly in light and dark mode with no further configuration.
Provider props
| Prop | Type | Description |
|---|
pk | ProvenanceKit | Pre-built SDK instance (takes priority over apiUrl/apiKey) |
apiUrl | string | API base URL |
apiKey | string | API key |
theme | ProvenanceKitTheme | CSS custom property overrides |
Next.js App Router
Components are marked "use client" internally. Re-export from a client boundary so Server Components can import them without errors:
// components/ui/pk-ui.tsx
"use client";
export {
ProvenanceBadge,
ProvenanceBundleView,
ProvenanceGraph,
ProvenanceTracker,
} from "@provenancekit/ui";
Then import from components/ui/pk-ui in any Server Component.
Dark Mode
Add the .dark class to your root <html> element. All components — cards, popovers, graph canvas, node cards — switch to dark surfaces automatically.
// With next-themes
import { ThemeProvider } from "next-themes";
<ThemeProvider attribute="class">
<ProvenanceKitProvider apiUrl="...">
{children}
</ProvenanceKitProvider>
</ThemeProvider>
Headless Mode
Every data-fetching component accepts data directly — no network requests needed. Useful for SSR, testing, and Storybook:
// Pass nodes/edges directly — no auto-fetch
<ProvenanceGraph nodes={myNodes} edges={myEdges} />
// Pass a pre-fetched bundle
<ProvenanceBadge bundle={myBundle}>…</ProvenanceBadge>
// Pass a session object directly
<ProvenanceTracker session={mySession} />
CSS Design Tokens
All styling uses CSS custom properties. Override any token globally or per-scope. Light-mode defaults are in :root; dark-mode overrides apply under .dark.
:root {
/* ── Node type colors ── */
--pk-node-resource: #3b82f6; /* blue */
--pk-node-action: #22c55e; /* green */
--pk-node-entity: #f59e0b; /* amber */
/* ── Entity role colors ── */
--pk-role-human: #3b82f6; /* blue */
--pk-role-ai: #7c3aed; /* violet */
--pk-role-org: #22c55e; /* green */
/* ── Badge (Pr squircle) ── */
--pk-badge-bg: #0f172a; /* always dark — stands out on any background */
--pk-badge-fg: #f8fafc;
--pk-badge-font-family: 'Red Hat Display', system-ui, sans-serif;
/* ── Graph canvas ── */
--pk-graph-bg: #f1f5f9;
--pk-graph-dot: #cbd5e1;
--pk-graph-node-bg: #ffffff;
--pk-graph-node-text: #0f172a;
--pk-graph-control-bg: rgba(255,255,255,0.92);
--pk-graph-control-border: #e2e8f0;
/* ── Surfaces ── */
--pk-surface: #ffffff;
--pk-surface-muted: #f8fafc;
--pk-surface-border: #e2e8f0;
--pk-foreground: #0f172a;
--pk-muted-foreground: #64748b;
--pk-radius: 0.75rem;
}
--pk-badge-bg stays dark in both light and dark mode by design — the “Pr” tag is a permanent provenance mark that needs to stand out on any background.
Or use the theme prop on ProvenanceKitProvider for common overrides without touching CSS:
<ProvenanceKitProvider
apiUrl="..."
theme={{
nodeResourceColor: "#6366f1",
nodeActionColor: "#22c55e",
badgeBg: "rgba(0,0,0,0.9)",
radius: "0.5rem",
}}
>
{children}
</ProvenanceKitProvider>
Font — Red Hat Display
The "Pr" squircle badge defaults to Red Hat Display (700/800 weight). Load it from Google Fonts once in your app’s <head>:
<link
href="https://fonts.googleapis.com/css2?family=Red+Hat+Display:wght@700;800&display=swap"
rel="stylesheet"
/>
In Next.js use next/font/google and expose it as a CSS variable:
// app/layout.tsx
import { Red_Hat_Display } from "next/font/google";
const redHatDisplay = Red_Hat_Display({
subsets: ["latin"],
weight: ["700", "800"],
variable: "--font-red-hat-display",
display: "swap",
});
export default function RootLayout({ children }) {
return (
<html lang="en">
<body className={redHatDisplay.variable}>
...
</body>
</html>
);
}
Then in your global CSS wire the variable into the badge token:
:root {
--pk-badge-font-family: var(--font-red-hat-display, 'Red Hat Display', system-ui, sans-serif);
}
Override with any font via --pk-badge-font-family if you prefer a different typeface.
Available Hooks
import {
useProvenanceBundle,
useProvenanceGraph,
useSessionProvenance,
useDistribution,
useProvenanceKit,
} from "@provenancekit/ui";
// Access the configured SDK instance
const { pk } = useProvenanceKit();
// Fetch a provenance bundle
const { data: bundle, loading, error } = useProvenanceBundle("bafybei...");
// Fetch a provenance graph
const { data: graph } = useProvenanceGraph("bafybei...", { depth: 5 });
// Poll a session in real-time
const { data: session } = useSessionProvenance("session-xyz", { pollInterval: 3000 });
// Compute contribution weights from a bundle
const { data: distribution } = useDistribution("bafybei...");
Troubleshooting
Graph doesn’t render / canvas is blank
You forgot @import "@provenancekit/ui/styles.css" in your global CSS. This import includes the ReactFlow base styles that the graph canvas requires.
“Pr” badge font looks wrong
The badge uses --pk-badge-font-family. Set it to your loaded font variable — see the Font section above.
Badge popover doesn’t open
Make sure you are not wrapping the <ProvenanceBadge> in a container that intercepts click events (e.g. an <a> tag or a draggable layer). If you need to nest it inside a link, use e.stopPropagation() on the link’s click handler.
TypeScript error: “Property ‘x’ does not exist on type ‘IntrinsicAttributes’”
You are likely on a stale cached version of @provenancekit/ui. Run npm install @provenancekit/ui@latest to get the current types.
Server Component import error in Next.js
Components are "use client" internally. Re-export them from a client wrapper file:
// components/ui/pk-ui.tsx
"use client";
export {
ProvenanceBadge,
ProvenanceBundleView,
ProvenanceGraph,
ProvenanceTracker,
} from "@provenancekit/ui";
Then import from components/ui/pk-ui in Server Components.