Next.js is the framework behind a huge chunk of the web right now, and its monitoring requirements are different from a traditional server-rendered app. The hybrid rendering model — SSR, SSG, ISR, and client-side rendering all potentially on the same site — creates failure modes that standard HTTP monitoring doesn't cover.
Here's how I think about monitoring a Next.js app properly.
The failure modes unique to Next.js
Hydration errors. Next.js pre-renders HTML on the server, then "hydrates" it on the client — attaching React event handlers and making the page interactive. If the server-rendered HTML doesn't match what React renders on the client, you get a hydration error. The page usually still loads, but it can be in a broken state, and in some cases the content flickers or disappears.
HTTP monitoring sees: 200, content delivered. Reality: the page may be partially broken.
ISR stale content. Incremental Static Regeneration (ISR) serves cached static pages and regenerates them in the background after a revalidation period. If the background regeneration fails — because an API it depends on is down, or because the build process throws — the page continues serving the stale cached version indefinitely. It might be hours or days old.
HTTP monitoring sees: 200, page served. Reality: the content is stale, potentially significantly.
Missing environment variables in production. Next.js has two types of environment variables: server-side (only available in Node.js context) and client-side (prefixed with NEXT_PUBLIC_, bundled into the JavaScript). Client-side env vars are evaluated at build time. If a NEXT_PUBLIC_ variable wasn't set during the production build, it's undefined in the JavaScript bundle, and any code that uses it will either silently produce wrong output or crash.
Client-side navigation crashes. Next.js uses client-side navigation between pages to avoid full page reloads. A component that crashes during client-side navigation (not initial load) won't show up in server logs and won't be caught by an HTTP monitor checking the route. It's a pure client-side failure.
The monitoring approach
HTTP checks on your key routes. Standard stuff: monitor your homepage, main product pages, API health endpoint if you have one. This catches hard server failures. Run them every minute.
Visual screenshot monitoring on rendered pages. This is the critical addition for Next.js. GrabDiff runs headless Chrome, fully executes the JavaScript, waits for the page to render, takes a screenshot, and compares it to your baseline. A hydration error that blanks out content, a missing env var that crashes a component, or a page that loads the shell but not the content — all of these show up as visual diffs.
I monitor my homepage, key feature pages, and the logged-in dashboard (by pointing the monitor at a specific test URL that doesn't require auth). Each one has a baseline set from when everything was working correctly.
Alerting on 5xx rates. Next.js surfaces server errors through standard HTTP status codes when they happen at the SSR level. A spike in 5xx responses in your server logs or from your hosting provider (Vercel, Netlify, etc.) is a signal worth monitoring separately from uptime checks.
Build monitoring. If you're using ISR, monitor whether your regeneration builds are succeeding. Vercel provides this through their dashboard; other platforms vary. A build that silently fails means your ISR pages freeze at their last successful build.
The combination that works
HTTP checks + visual screenshot monitoring + build/deploy alerting covers the major Next.js failure modes without being excessive. The visual monitoring is the piece most Next.js developers are missing, and it's the one that catches the failures that feel most embarrassing — blank screens, broken hydration, missing content — because they're the ones where your monitor says everything is fine while users are complaining.