Next.js

Real User Monitoring for Next.js applications with Raygun is available using the Raygun4JS provider.

Raygun4JS is a library you can easily add to your website and web applications which allows you to then monitor frontend performance issues affecting your users.


Next.js has transitioned from Page Routing to App Routing since version 13. Page Routing is still supported alongside App Routing for legacy applications, but it is recommended that new applications use App Routing.

  • If your application uses Page Routing, we'll need to use the Custom Document system from Next.js.

  • If your application uses App Routing, we'll need to modify the Root Layout.

  • If your application is currently migrating from Page Routing to App Routing, you will require Raygun in two locations. See Next's App Router Incremental Adoption Guide for details. In this case, please follow Step 2a and Step 2b for both routing types.


If you do not already have a custom document located at pages/_document.js / .ts, save the following as pages/_document.js / .ts:

import Document, { Html, Head, Main, NextScript } from "next/document";

class MyDocument extends Document {
  static async getInitialProps(ctx) {
    const initialProps = await Document.getInitialProps(ctx);
    return { ...initialProps };
  }

  render() {
    return (
      <Html>
        <script
          type="text/javascript"
          dangerouslySetInnerHTML={{
            __html: `
              !function(a,b,c,d,e,f,g,h){a.RaygunObject=e,a[e]=a[e]||function(){
              (a[e].o=a[e].o||[]).push(arguments)},f=b.createElement(c),g=b.getElementsByTagName(c)[0],
              f.async=1,f.src=d,g.parentNode.insertBefore(f,g),h=a.onerror,a.onerror=function(b,c,d,f,g){
              h&&h(b,c,d,f,g),g||(g=new Error(b)),a[e].q=a[e].q||[],a[e].q.push({
              e:g})}}(window,document,"script","//cdn.raygun.io/raygun4js/raygun.min.js","rg4js");

              rg4js('apiKey', 'paste_your_api_key_here');
              rg4js('enablePulse', true);`,
          }}
        />
        <Head />
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    );
  }
}

export default MyDocument;

If you do already have a custom document located at pages/_document.js / .ts, add the above Raygun <script /> immediately below the opening <Html> tag in the same manner.

Insert the following into your root layout located at app/layout.tsx immediately below the opening <html> tag:

  <html>
    <head>
      <script
        type="text/javascript"
        dangerouslySetInnerHTML={{
          __html: `
            !function(a,b,c,d,e,f,g,h){a.RaygunObject=e,a[e]=a[e]||function(){
            (a[e].o=a[e].o||[]).push(arguments)},f=b.createElement(c),g=b.getElementsByTagName(c)[0],
            f.async=1,f.src=d,g.parentNode.insertBefore(f,g),h=a.onerror,a.onerror=function(b,c,d,f,g){
            h&&h(b,c,d,f,g),g||(g=new Error(b)),a[e].q=a[e].q||[],a[e].q.push({
            e:g})}}(window,document,"script","//cdn.raygun.io/raygun4js/raygun.min.js","rg4js");

            rg4js('apiKey', 'paste_your_api_key_here');
            rg4js('enablePulse', true);`,
        }}
      />
      //...
    </head>
    //...

This will add the Raygun fetch script to the head, applying to all routes.

Note: If you encounter a situation where no events are appearing within Raygun, you may need to hard code the protocol so that the CDN matches your hosting environment. This could look like one of the following -

  • https://cdn.raygun.io/raygun4js/raygun.min.js
  • http://cdn.raygun.io/raygun4js/raygun.min.js

This will be in replacement of //cdn.raygun.io/raygun4js/raygun.min.js.


To track page changes in a SPA we need to add some custom logic that is triggered everytime the route changes. In your pages/_app.js add the following code:

...

import { useEffect } from 'react'
import { useRouter } from 'next/router'

...

export default function MyApp({ Component, pageProps }) {
  const router = useRouter()
 
  useEffect(() => {
    const handleRouteChange = (url, { shallow }) => {
        rg4js('trackEvent', {
            type: 'pageView',
            path: '/' + url
        });
    }
 
    router.events.on('routeChangeStart', handleRouteChange)
 
    // If the component is unmounted, unsubscribe
    // from the event with the `off` method:
    return () => {
        router.events.off('routeChangeStart', handleRouteChange)
    }
  }, [router])
    
    ...
    
}

For more information on using Raygun with Single Page Applications see this docs page



Enable Crash Reporting to also track errors and exceptions occurring in your website.

<script type="text/javascript">
  rg4js('enableCrashReporting', true);
</script>

The provider is open source and available at the Raygun4JS repository.