rollbar-pharmacy
v1.0.5
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.
- GDPR-friendly — IP addresses anonymised by default (last octet truncated)
- Secure — sensitive fields (
password,token,card_number, …) scrubbed from all payloads - Noise-resistant — known browser noise (ResizeObserver, hydration warnings) filtered out
- ChunkLoadError-aware — CDN timeout errors sent as
warningwith chunk ID, URL, and hint; not silently ignored, not misfiled ascritical - Server errors captured —
instrumentation.tshook captures real server component error messages before Next.js strips them
Contents
| Export | Source | Description |
|---|---|---|
| buildRollbarConfig | rollbar-pharmacy | Opinionated Rollbar config factory |
| RollbarProvider | rollbar-pharmacy | React provider — initialises SDK + top-level ErrorBoundary |
| RollbarUserSync | rollbar-pharmacy | Headless component — syncs any user into Rollbar's person context |
| useRollbar | rollbar-pharmacy | Typed hook — debug / info / warn / error / critical / setUser / clearUser |
| reportGlobalError | rollbar-pharmacy | Standalone function for global-error.tsx — no React context required |
| createRollbarInstrumentationHandler | rollbar-pharmacy/instrumentation | Server-side onRequestError hook for instrumentation.ts |
| 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
Client-side (prefix NEXT_PUBLIC_)
| Variable | Required | Description |
|---|---|---|
| NEXT_PUBLIC_ROLLBAR_TOKEN | Yes | Client-side write token from Rollbar → Project Settings → Access Tokens |
| NEXT_PUBLIC_APP_ENV | Recommended | Environment label sent with every event (production, staging, dev) |
| NEXT_PUBLIC_APP_VERSION | Recommended | Git SHA or release tag — used for source-map correlation |
| NEXT_PUBLIC_ROLLBAR_ENABLED | Dev/CI only | Set "true" to force-enable Rollbar outside NODE_ENV=production |
Server-side (never shipped to browser)
| Variable | Required | Description |
|---|---|---|
| ROLLBAR_SERVER_TOKEN | Yes (for instrumentation.ts) | Server-side write token — same project, separate token scoped to server |
| ROLLBAR_ENABLED | Dev/CI only | Set "true" to force-enable server-side reporting outside NODE_ENV=production |
Rollbar is disabled by default in development and test. Set
NEXT_PUBLIC_ROLLBAR_ENABLED=truein.env.localto test locally.
Vercel environment variable setup
In Vercel → Project Settings → Environment Variables, add:
| Name | Environment | Notes |
|---|---|---|
| NEXT_PUBLIC_ROLLBAR_TOKEN | Production, Preview | Client write token |
| ROLLBAR_SERVER_TOKEN | Production, Preview | Server write token |
| NEXT_PUBLIC_APP_ENV | Production → production, Preview → staging | Separate per environment |
| NEXT_PUBLIC_APP_VERSION | All | Set to $VERCEL_GIT_COMMIT_SHA via Vercel system env |
To expose VERCEL_GIT_COMMIT_SHA as NEXT_PUBLIC_APP_VERSION, add a build step or use Vercel's "Automatically expose System Environment Variables" option in project settings.
Integration steps (new project)
Step 1 — Install
pnpm add rollbar-pharmacy rollbar @rollbar/reactStep 2 — Add the provider
// src/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>
);
}Mount it in the root layout:
// src/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>
);
}Step 3 — Sync the authenticated user
RollbarUserSync is decoupled from any state management library. Wrap it with your state selector:
// src/app/_components/rollbar-user-sync.tsx
"use client";
import { RollbarUserSync } from "rollbar-pharmacy";
import { useAppSelector } from "@/store/hooks"; // your Redux/Zustand selector
export function AppRollbarUserSync() {
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
}
/>
);
}Place it inside <RollbarProvider> (and inside your Redux/Zustand <Provider> if applicable):
// src/app/providers.tsx
"use client";
import { RollbarProvider } from "rollbar-pharmacy";
import "rollbar-pharmacy/styles.css";
import { Provider as ReduxProvider } from "react-redux";
import { store } from "@/store";
import { AppRollbarUserSync } from "./_components/rollbar-user-sync";
export function Providers({ children }: { children: React.ReactNode }) {
return (
<ReduxProvider store={store}>
<RollbarProvider>
<AppRollbarUserSync />
{children}
</RollbarProvider>
</ReduxProvider>
);
}Step 4 — Segment-level error boundary
// src/app/error.tsx
"use client";
import "rollbar-pharmacy/styles.css";
import { useEffect } from "react";
import { useRollbar } from "rollbar-pharmacy";
export default function ErrorPage({
error,
reset,
}: {
error: Error & { digest?: string };
reset: () => void;
}) {
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>
);
}Step 5 — Root layout error boundary
Next.js replaces the entire app shell here — RollbarProvider context is unavailable. Use reportGlobalError instead:
// src/app/global-error.tsx
"use client";
import "rollbar-pharmacy/styles.css";
import { useEffect } from "react";
import { reportGlobalError } from "rollbar-pharmacy";
export default function GlobalError({
error,
reset,
}: {
error: Error & { digest?: string };
reset: () => void;
}) {
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 reads NEXT_PUBLIC_ROLLBAR_TOKEN and NEXT_PUBLIC_APP_ENV automatically. It is a no-op when no token is set or when not in production.
ChunkLoadErrors (CDN/network timeouts) are automatically sent as warning — not critical — with chunk_id, chunk_url, and a human-readable hint attached to the Rollbar item.
Step 6 — Server-side error capture
Next.js strips server component error messages before they reach the client. instrumentation.ts is the only place the real unredacted message is available.
// src/instrumentation.ts (at project root alongside next.config.ts, or inside src/)
import { createRollbarInstrumentationHandler } from "rollbar-pharmacy/instrumentation";
export const onRequestError = createRollbarInstrumentationHandler();Requires ROLLBAR_SERVER_TOKEN set in Vercel. No other configuration needed.
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 | Description |
|---|---|
| debug(message, extra?) | Verbose trace |
| info(message, extra?) | User actions, flow milestones |
| warn(message, extra?) | Recoverable unexpected state |
| error(message, extra?) | Caught exceptions, failed requests |
| critical(message, extra?) | Data loss risk, complete outage |
| setUser({ id, username?, email? }) | Tag all subsequent events with a user |
| clearUser() | Remove user context — call on logout |
| instance | Raw Rollbar SDK for advanced use |
RollbarProvider props
| Prop | Type | Default | Description |
|---|---|---|---|
| children | ReactNode | — | App tree to wrap |
| token | string | NEXT_PUBLIC_ROLLBAR_TOKEN | Override client access token |
| configOverrides | Partial<Rollbar.Configuration> | {} | Merged over defaults from buildRollbarConfig |
| fallbackUI | ComponentType | Built-in error screen | Custom component shown when top-level ErrorBoundary catches a render error |
Theming the error screen
Override CSS custom properties 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 verify events reach the Rollbar dashboard locally:
// src/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 guard it behind an admin check.
Source maps (optional but recommended)
Without source maps, Rollbar stack traces show minified/bundled paths. Two options:
Option A — Public source maps (simplest)
// next.config.ts
productionBrowserSourceMaps: true,Source maps are publicly accessible at /_next/static/…/*.map. Fine for most projects. Anyone can read your source code via devtools.
Option B — Private upload to Rollbar (recommended for sensitive codebases)
- Build with source maps enabled (Option A above)
- After build, upload
.next/staticmap files to Rollbar's source map API usingROLLBAR_SERVER_TOKEN - Delete map files from the deployment output before publishing
The Rollbar SDK is already configured with source_map_enabled: true and guess_uncaught_frames: true — no additional SDK changes needed for either option.
Integration checklist
[ ] pnpm add rollbar-pharmacy rollbar @rollbar/react
[ ] src/app/providers.tsx — RollbarProvider wrapping app tree
[ ] src/app/layout.tsx — Providers mounted in root layout
[ ] src/app/_components/ — RollbarUserSync wired to your auth state
[ ] src/app/error.tsx — useRollbar().error() in useEffect
[ ] src/app/global-error.tsx — reportGlobalError() in useEffect
[ ] src/instrumentation.ts — createRollbarInstrumentationHandler()
[ ] Vercel env vars — NEXT_PUBLIC_ROLLBAR_TOKEN + ROLLBAR_SERVER_TOKEN
[ ] Rollbar dashboard — confirm events arrive after first deployPackage structure
rollbar-pharmacy/
├── package.json
├── tsconfig.json
├── tsup.config.ts
├── README.md
└── src/
├── index.ts # Barrel re-exports
├── config.ts # buildRollbarConfig factory
├── provider.tsx # <RollbarProvider>
├── user-sync.tsx # <RollbarUserSync>
├── use-rollbar.ts # useRollbar() hook
├── global-error.ts # reportGlobalError()
├── instrumentation-handler.ts # createRollbarInstrumentationHandler()
└── styles.cssBuilding and publishing
npm run build # compiles CJS + ESM + .d.ts, copies styles.css
npm version patch && npm publish