Add a simple Next.js reference integration example#153
Conversation
There was a problem hiding this comment.
Pull request overview
Adds a small App Router Next.js reference app under example/nextjs demonstrating an idiomatic Exceptionless integration across client + server hooks, with a tiny request adapter and tests.
Changes:
- Add
example/nextjsreference app (instrumentation hooks, error boundaries, route handler logging/flush, UI). - Add a Next.js request-shape adapter plus focused Vitest coverage.
- Wire the new example into repo tooling (Vitest project, clean script, gitignore, lockfile).
Reviewed changes
Copilot reviewed 19 out of 21 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| vitest.config.ts | Adds a dedicated Vitest project for the Next.js example tests. |
| package.json | Extends clean to remove Next.js .next build output. |
| package-lock.json | Adds the Next.js example workspace and its dependency tree. |
| .gitignore | Ignores the Next.js example .next/ directory. |
| example/nextjs/package.json | Defines the nextjs-example workspace and its runtime dependencies/scripts. |
| example/nextjs/next.config.mjs | Adds example-level webpack alias workaround for source-map. |
| example/nextjs/lib/next-request.js | Implements request context normalization for Next request shapes. |
| example/nextjs/test/next-request.test.js | Tests request context normalization for both web Request and onRequestError payload shape. |
| example/nextjs/lib/exceptionless-server.js | Server-side Exceptionless startup + Next/Vercel environment enrichment plugin. |
| example/nextjs/lib/exceptionless-browser.js | Browser-side Exceptionless startup + Next environment enrichment plugin. |
| example/nextjs/instrumentation.js | Registers server instrumentation and submits events from onRequestError. |
| example/nextjs/instrumentation-client.js | Starts browser client and logs router transitions via onRouterTransitionStart. |
| example/nextjs/components/ClientDemoPanel.jsx | Client UI to trigger logs/errors and hit the demo route handler. |
| example/nextjs/app/page.jsx | Home page describing integration coverage and rendering the demo panel. |
| example/nextjs/app/layout.jsx | Root layout + metadata wiring and global CSS import. |
| example/nextjs/app/globals.css | Styling for the demo UI. |
| example/nextjs/app/error.jsx | Route-level App Router error boundary with Exceptionless capture for client-only errors. |
| example/nextjs/app/global-error.jsx | Root-level App Router error boundary with Exceptionless capture for client-only errors. |
| example/nextjs/app/server-component-error/page.jsx | Server-component error route to exercise onRequestError. |
| example/nextjs/app/api/demo/route.js | Demo route handler logging + request metadata + after() queue flush. |
| example/nextjs/README.md | Documentation for running and understanding the example integration. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
dd29ae9 to
08e97b7
Compare
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…mple" This reverts commit b462d7e.
08e97b7 to
4351881
Compare
Co-authored-by: Blake Niemyjski <bniemyjski@gmail.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 19 out of 21 changed files in this pull request and generated 5 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 18 out of 20 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| await Exceptionless.createException(error).addTags("error-boundary").setProperty("handledBy", "app/error.jsx").submit(); | ||
| } catch (submitError) { | ||
| console.error("Exceptionless route boundary capture failed", submitError); | ||
| } | ||
| })(); |
There was a problem hiding this comment.
Inside the if (!error.digest) branch, error.digest is always falsy, so setting the digest property is redundant (and setProperty no-ops on undefined). Removing this line (or moving it behind a separate truthy check) would make the intent clearer.
Summary
This adds a small
example/nextjsApp Router reference app that shows an Exceptionless integration in a way that stays close to native Next.js conventions.The example covers:
instrumentation-client.jsonRouterTransitionStartinstrumentation.jsonRequestErrorafter()-based queue flushingWhy
We wanted a concrete Next.js example that helps answer two product questions:
@exceptionless/nextjspackage is justified?This PR deliberately keeps the example close to the framework file conventions and uses Exceptionless APIs directly in the integration points instead of layering on a large custom abstraction.
Implementation Notes
A few details are worth calling out explicitly:
@environment.datato attach Next.js-specific context like framework, router, runtime, and Vercel deployment metadata.packages/browser/distandpackages/node/distbecause the package entrypoints still re-export internal#/*imports that Next does not currently like in this setup.next dev --webpackandnext build --webpackfor now. Turbopack still rejects the current node bundle path because ofnode-localstorage's dynamicrequire.next.config.mjscontains a scoped webpack alias forsource-mapas an example-level workaround for the unusedstacktrace-gpsAMD branch. This keeps that workaround out of@exceptionless/browseritself.Validation
npm test -- --project nextjs-examplenpm run build --workspace=nextjs-exampleFollow-ups
I think the main follow-up after this lands is not more example abstraction, but fixing the SDK packaging issues that forced the example to lean on built bundle imports and webpack mode. Once those are cleaned up, we can evaluate whether a thin
@exceptionless/nextjshelper is still worth having.