diff --git a/examples/nextjs-approuter/README.md b/examples/nextjs-approuter/README.md index c403366..71c946b 100644 --- a/examples/nextjs-approuter/README.md +++ b/examples/nextjs-approuter/README.md @@ -16,10 +16,6 @@ bun dev Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. -You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file. - -This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font. - ## Learn More To learn more about Next.js, take a look at the following resources: @@ -29,8 +25,51 @@ To learn more about Next.js, take a look at the following resources: You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome! -## Deploy on Vercel +## Using Rollbar with the Next.js App Router + +The first step to using Rollbar with the Next.js App Router is to configure your Rollbar instance. + +``` +// ./src/rollbar.ts +import Rollbar from 'rollbar'; + +const baseConfig = { + captureUncaught: true, + captureUnhandledRejections: true, + environment: process.env.NODE_ENV, +}; + +export const clientConfig = { + accessToken: process.env.NEXT_PUBLIC_POST_CLIENT_ITEM_TOKEN, + ...baseConfig, +}; + +export const serverInstance = new Rollbar({ + accessToken: process.env.POST_SERVER_ITEM_TOKEN, + ...baseConfig, +}); +``` + +We suggest you create a single instance for use server side, to be certain there are not more than one, and a config to use in your client side components. React Server Components limit you to passing simple objects as props from Server Components to Client Components. The config object can be used by the Rollbar Provider to construct your Rollbar instance. + +### Configuring the Rollbar Provider + +To be able to use the hooks consistently through your application. It is easiest if you configure your Rollbar Provider within your root layout. + +**_Note:_** The Rollbar Provider uses a React Context. This context, like hooks are only available for use in your client components. + +### Configuring the global-error handler + +To be certain that you are catching all errors within your application, you will want to [configure a `global-error.js/tsx`](./src/app/global-error.tsx). This handler will catch errors, including from your root layout and relay then to Rollbar. + +### Using the Next.js route error handler (Recommended) + +Next.js provides an [error handler]() this handler will automatically wrap your router, at the desired level, within an [Error Boundary](). It is recommended to [use your Rollbar instance within this error handler](./src/app//next_error_handler/error.tsx) to report errors to Rollbar. + +### Using the Rollbar ErrorBoundary + +The `` component provided by this library [may still be used](./src/app/rollbar_error_boundary/page.tsx) if you would prefer that over the built in Next.js error handler -The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. +#### Special note on Error boundaries -Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details. +The ErrorBoundary class is not perfect at catching and stopping the propagation of all errors. Be aware, that if you turn on `captureUncaught` or `captureUnhandledRejections` in your Rollbar config you may receive doubled occurrences. diff --git a/examples/nextjs-approuter/src/app/global-error.tsx b/examples/nextjs-approuter/src/app/global-error.tsx index b99f8ca..00b97ce 100644 --- a/examples/nextjs-approuter/src/app/global-error.tsx +++ b/examples/nextjs-approuter/src/app/global-error.tsx @@ -1,8 +1,8 @@ 'use client'; import { useEffect } from 'react'; -import { rollbarInstance } from '@/rollbar'; import { ResetPage } from '@/components/ResetPage'; +import { useRollbar } from '@rollbar/react'; export default function GlobalError({ error, @@ -11,8 +11,10 @@ export default function GlobalError({ error: Error & { digest?: string }; reset: () => void; }) { + const rollbar = useRollbar(); + useEffect(() => { - rollbarInstance.error(error); + rollbar.error(error); }, [error]); return ( diff --git a/examples/nextjs-approuter/src/app/layout.tsx b/examples/nextjs-approuter/src/app/layout.tsx index 08e7f6d..312fe58 100644 --- a/examples/nextjs-approuter/src/app/layout.tsx +++ b/examples/nextjs-approuter/src/app/layout.tsx @@ -2,7 +2,7 @@ import type { Metadata } from 'next'; import { Inter } from 'next/font/google'; import { Provider as RollbarProvider } from '@rollbar/react'; -import { rollbarInstance } from '@/rollbar'; +import { clientConfig } from '@/rollbar'; import './globals.css'; @@ -19,7 +19,7 @@ export default function RootLayout({ children: React.ReactNode; }>) { return ( - + {children} diff --git a/examples/nextjs-approuter/src/app/middleware.ts b/examples/nextjs-approuter/src/app/middleware.ts index 014caf9..1582211 100644 --- a/examples/nextjs-approuter/src/app/middleware.ts +++ b/examples/nextjs-approuter/src/app/middleware.ts @@ -1,8 +1,8 @@ -import { rollbarInstance } from '@/rollbar'; +import { serverInstance as rollbar } from '@/rollbar'; import { NextRequest, NextResponse } from 'next/server'; export function middleware(request: NextRequest) { - rollbarInstance.configure({ payload: { context: request.nextUrl.pathname } }); + rollbar.configure({ payload: { context: request.nextUrl.pathname } }); return NextResponse.next(); } diff --git a/examples/nextjs-approuter/src/app/next_error_handler/error.tsx b/examples/nextjs-approuter/src/app/next_error_handler/error.tsx index b9771c1..0b43ee7 100644 --- a/examples/nextjs-approuter/src/app/next_error_handler/error.tsx +++ b/examples/nextjs-approuter/src/app/next_error_handler/error.tsx @@ -1,8 +1,8 @@ 'use client'; // Error components must be Client Components import { useEffect } from 'react'; -import { rollbarInstance } from '@/rollbar'; import { ResetPage } from '@/components/ResetPage'; +import { useRollbar } from '@rollbar/react'; export default function Error({ error, @@ -11,8 +11,9 @@ export default function Error({ error: Error & { digest?: string }; reset: () => void; }) { + const rollbar = useRollbar(); useEffect(() => { - rollbarInstance.error(error); + rollbar.error(error); }, [error]); return ; diff --git a/examples/nextjs-approuter/src/app/rollbar_error_boundary/page.tsx b/examples/nextjs-approuter/src/app/rollbar_error_boundary/page.tsx index 3aa990b..cfd2897 100644 --- a/examples/nextjs-approuter/src/app/rollbar_error_boundary/page.tsx +++ b/examples/nextjs-approuter/src/app/rollbar_error_boundary/page.tsx @@ -1,3 +1,5 @@ +'use client'; + import { ErrorBoundary } from '@rollbar/react'; import { ResetPage } from '@/components/ResetPage'; diff --git a/examples/nextjs-approuter/src/rollbar.ts b/examples/nextjs-approuter/src/rollbar.ts index 82a14e4..3bf3ccf 100644 --- a/examples/nextjs-approuter/src/rollbar.ts +++ b/examples/nextjs-approuter/src/rollbar.ts @@ -1,11 +1,17 @@ import Rollbar from 'rollbar'; -export const rollbarInstance = new Rollbar({ - accessToken: - typeof window === 'undefined' - ? process.env.POST_SERVER_ITEM_TOKEN - : process.env.NEXT_PUBLIC_POST_CLIENT_ITEM_TOKEN, +const baseConfig = { captureUncaught: true, captureUnhandledRejections: true, environment: process.env.NODE_ENV, +}; + +export const clientConfig = { + accessToken: process.env.NEXT_PUBLIC_POST_CLIENT_ITEM_TOKEN, + ...baseConfig, +}; + +export const serverInstance = new Rollbar({ + accessToken: process.env.POST_SERVER_ITEM_TOKEN, + ...baseConfig, });