rollbar-pharmacy
v1.0.3
Published
Shared Rollbar error-tracking integration for pharmacy Next.js websites
Maintainers
Readme
rollbar-pharmacy
Shared Rollbar error-tracking integration for pharmacy Next.js websites.
Provides a typed, opinionated Rollbar setup that is:
- GDPR-friendly — IP addresses are anonymised by default
- Secure — sensitive field names (
password,token,card_number, …) are scrubbed from all payloads - Noise-resistant — common browser/library errors (ResizeObserver, ChunkLoadError, hydration warnings) are filtered out
- Framework-agnostic for state management —
RollbarUserSyncaccepts any user object; no Redux dependency in the package
Contents
| Export | Description |
|---|---|
| buildRollbarConfig | Opinionated Rollbar config factory |
| RollbarProvider | React provider — initialises SDK + top-level ErrorBoundary |
| RollbarUserSync | Headless component — syncs any user into Rollbar's person context |
| useRollbar | Typed hook — debug / info / warn / error / critical / setUser / clearUser |
| reportGlobalError | Standalone function for global-error.tsx — reports critical errors without React context |
| rollbar-pharmacy/styles.css | Portable error-screen CSS (BEM, CSS custom properties, zero dependencies) |
Installation
npm install rollbar-pharmacy rollbar @rollbar/react
# or
pnpm add rollbar-pharmacy rollbar @rollbar/reactEnvironment variables
| Variable | Required | Description |
|---|---|---|
| NEXT_PUBLIC_ROLLBAR_TOKEN | Yes (production) | Client-side Rollbar access token |
| NEXT_PUBLIC_APP_ENV | Recommended | Environment label (production, staging, …) sent with every event |
| NEXT_PUBLIC_APP_VERSION | Recommended | Code version / Git SHA for source-map correlation |
| NEXT_PUBLIC_ROLLBAR_ENABLED | Dev/CI only | Set to "true" to force-enable Rollbar outside NODE_ENV=production |
Rollbar is disabled by default in development and test environments.
SetNEXT_PUBLIC_ROLLBAR_ENABLED=truein.env.localto test locally.
Quick start (Next.js App Router)
1. Add the provider to your app
// app/providers.tsx
"use client";
import { RollbarProvider } from "rollbar-pharmacy";
import "rollbar-pharmacy/styles.css";
export function Providers({ children }: { children: React.ReactNode }) {
return (
<RollbarProvider>
{children}
</RollbarProvider>
);
}2. Mount the provider in the root layout
// app/layout.tsx
import { Providers } from "./providers";
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
<Providers>{children}</Providers>
</body>
</html>
);
}3. Sync the authenticated user (optional but recommended)
RollbarUserSync is intentionally decoupled from any state management library.
Create a thin wrapper in your app that pulls the user from wherever you store it:
// app/_components/rollbar-user-sync.tsx
"use client";
import { RollbarUserSync } from "rollbar-pharmacy";
import { useAppSelector } from "@/store/types"; // your Redux selector
export function ReduxRollbarUserSync() {
const user = useAppSelector((state) => state.user?.user ?? null);
return (
<RollbarUserSync
user={
user
? {
id: user.id,
username: [user.first_name, user.last_name].filter(Boolean).join(" ") || undefined,
email: user.email,
}
: null
}
/>
);
}Then place it inside the provider (and inside your Redux <Provider>):
// app/providers.tsx
"use client";
import { RollbarProvider } from "rollbar-pharmacy";
import "rollbar-pharmacy/styles.css";
import { Provider } from "react-redux";
import { store } from "@/store";
import { ReduxRollbarUserSync } from "./_components/rollbar-user-sync";
export function Providers({ children }: { children: React.ReactNode }) {
return (
<Provider store={store}>
<RollbarProvider>
<ReduxRollbarUserSync />
{children}
</RollbarProvider>
</Provider>
);
}Next.js error boundaries
Segment-level errors — app/error.tsx
The RollbarProvider context is available here, so use the hook directly:
// app/error.tsx
"use client";
import "rollbar-pharmacy/styles.css";
import { useEffect } from "react";
import { useRollbar } from "rollbar-pharmacy";
interface ErrorPageProps {
error: Error & { digest?: string };
reset: () => void;
}
export default function ErrorPage({ error, reset }: ErrorPageProps) {
const { error: reportError } = useRollbar();
useEffect(() => {
reportError(error, { digest: error.digest, location: "error-boundary" });
}, [error, reportError]);
return (
<div className="rollbar-error-screen">
<h2 className="rollbar-error-screen__title">Something went wrong</h2>
<p className="rollbar-error-screen__message">
We've been notified and are looking into the issue. Please try again.
</p>
<button onClick={reset} className="rollbar-error-screen__btn">Try again</button>
</div>
);
}Root-layout errors — app/global-error.tsx
Next.js replaces the entire app shell here, so the RollbarProvider context is not available.
Use reportGlobalError from the package — it handles the standalone Rollbar instantiation internally:
// app/global-error.tsx
"use client";
import "rollbar-pharmacy/styles.css";
import { useEffect } from "react";
import { reportGlobalError } from "rollbar-pharmacy";
interface GlobalErrorProps {
error: Error & { digest?: string };
reset: () => void;
}
export default function GlobalError({ error, reset }: GlobalErrorProps) {
useEffect(() => {
reportGlobalError(error, { digest: error.digest });
}, [error]);
return (
<html lang="en">
<body>
<div className="rollbar-error-screen">
<h2 className="rollbar-error-screen__title">A critical error occurred</h2>
<p className="rollbar-error-screen__message">
We've been notified and are working on a fix. Please refresh the page.
</p>
<button onClick={reset} className="rollbar-error-screen__btn">Try again</button>
</div>
</body>
</html>
);
}reportGlobalError(error, extra?) reads NEXT_PUBLIC_ROLLBAR_TOKEN and NEXT_PUBLIC_APP_ENV automatically, only runs in production (or when NEXT_PUBLIC_ROLLBAR_ENABLED=true), and is a no-op when no token is present.
Using the hook
"use client";
import { useRollbar } from "rollbar-pharmacy";
export function CheckoutButton() {
const { error, warn, info } = useRollbar();
async function handleCheckout() {
try {
info("Checkout started", { cartSize: 3 });
await submitOrder();
} catch (err) {
error(err instanceof Error ? err : new Error("Checkout failed"), {
location: "CheckoutButton",
});
}
}
return <button onClick={handleCheckout}>Pay now</button>;
}Hook API
| Method | Signature | Description |
|---|---|---|
| debug | (message, extra?) => void | Verbose trace — only forwarded at debug log level |
| info | (message, extra?) => void | Informational — user actions, flow milestones |
| warn | (message, extra?) => void | Non-fatal warning — recoverable unexpected state |
| error | (message, extra?) => void | Application error — caught exception, failed request |
| critical | (message, extra?) => void | Critical failure — data loss risk, complete outage |
| setUser | ({ id, username?, email? }) => void | Tag all subsequent events with a user |
| clearUser | () => void | Remove user context (call on logout) |
| instance | Rollbar | Raw SDK instance for advanced use |
RollbarProvider props
| Prop | Type | Default | Description |
|---|---|---|---|
| children | ReactNode | — | App tree to wrap |
| token | string | NEXT_PUBLIC_ROLLBAR_TOKEN | Rollbar client access token |
| configOverrides | Partial<Rollbar.Configuration> | {} | Merged over defaults from buildRollbarConfig |
| fallbackUI | ComponentType | Built-in error screen | Custom component shown when the ErrorBoundary catches a render error |
buildRollbarConfig defaults
| Setting | Value | Notes |
|---|---|---|
| enabled | true in production, opt-in in dev | Set NEXT_PUBLIC_ROLLBAR_ENABLED=true to enable locally |
| captureUncaught | true | Captures unhandled JS errors |
| captureUnhandledRejections | true | Captures unhandled Promise rejections |
| captureIp | "anonymize" | Truncates last IP octet (GDPR) |
| scrubFields | See src/config.ts | Removes secrets from all payloads |
| checkIgnore | See src/config.ts | Silences known noisy browser/library errors |
Use configOverrides to change any of these per-app:
<RollbarProvider configOverrides={{ captureUncaught: false }}>
{children}
</RollbarProvider>Theming the error screen
The built-in error screen uses CSS custom properties.
Override them in your app's global stylesheet:
:root {
--rollbar-error-btn-bg: #your-brand-colour;
--rollbar-error-btn-color: #ffffff;
--rollbar-error-btn-radius: 0.5rem;
--rollbar-error-title-size: 1.75rem;
}See src/styles.css for all available variables.
Development test page
Add this page to any app to verify events reach the Rollbar dashboard during development:
// app/rollbar-test/page.tsx
"use client";
import { useRollbar } from "rollbar-pharmacy";
import "rollbar-pharmacy/styles.css";
if (process.env.NODE_ENV === "production") {
throw new Error("rollbar-test page must not be included in production builds.");
}
export default function RollbarTestPage() {
const { debug, info, warn, error, critical } = useRollbar();
return (
<main className="rollbar-test-page">
<h1 className="rollbar-test-page__title">Rollbar Integration Test</h1>
<p className="rollbar-test-page__subtitle">
Each button sends a real event to Rollbar. Check your dashboard after clicking.
</p>
<div className="rollbar-test-page__btn-row">
<button className="rollbar-test-btn rollbar-test-btn--outline" onClick={() => debug("[Test] debug")}>debug</button>
<button className="rollbar-test-btn rollbar-test-btn--outline" onClick={() => info("[Test] info")}>info</button>
<button className="rollbar-test-btn rollbar-test-btn--outline" onClick={() => warn("[Test] warn")}>warn</button>
<button className="rollbar-test-btn rollbar-test-btn--destructive" onClick={() => error(new Error("[Test] error"))}>error</button>
<button className="rollbar-test-btn rollbar-test-btn--destructive" onClick={() => critical("[Test] critical")}>critical</button>
</div>
</main>
);
}Remove this route before shipping to production, or protect it behind an admin/staff check.
Package structure
rollbar-pharmacy/
├── package.json # main / module / exports / peerDeps
├── tsconfig.json # TypeScript compiler config
├── tsup.config.ts # Build config — CJS + ESM + .d.ts
├── README.md
└── src/
├── index.ts # Barrel — re-exports everything
├── config.ts # buildRollbarConfig factory
├── provider.tsx # <RollbarProvider> — SDK init + ErrorBoundary
├── user-sync.tsx # <RollbarUserSync user={…}> — headless user context sync
├── use-rollbar.ts # useRollbar() hook with typed methods
├── global-error.ts # reportGlobalError() — context-free critical reporter
└── styles.css # Portable error-screen & test-page CSSBuilding
npm run build # compiles CJS + ESM + .d.ts into dist/, copies styles.css
npm run dev # watch mode
npm run typecheck