Blog>
Snippets

Next.js Custom Analytics with Telemetry

Extend Next.js telemetry to collect custom analytics data and send it to an external monitoring service.
import Document, { Html, Head, Main, NextScript } from 'next/document';
import { ServerStyleSheet } from 'styled-components';

class MyDocument extends Document {
  // This gets called before rendering the page server-side
  static async getInitialProps(ctx) {
    const sheet = new ServerStyleSheet();
    const originalRenderPage = ctx.renderPage;

    try {
      ctx.renderPage = () => originalRenderPage({
        enhanceApp: (App) => (props) => sheet.collectStyles(<App {...props} />),
      });

      const initialProps = await Document.getInitialProps(ctx);
      return {
        ...initialProps,
        styles: (
          <>
            {initialProps.styles}
            {sheet.getStyleElement()}
          </>
        ),
      };
    } finally {
      sheet.seal();
    }
  }

  render() {
    // Custom logic to send page view events to an analytics service can go here
    return (
      <Html>
        <Head>
          {/*...*/}
        </Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    );
  }
}

export default MyDocument;
This code extends the default Next.js _document.js to include styled-components server-side rendering and a placeholder for custom analytics. In the render method, you can insert your custom analytics logic to send page view events to your external monitoring service.
import { useEffect } from 'react';

export default function MyApp({ Component, pageProps }) {
  useEffect(() => {
    // Client-side-only code for custom analytics
    const handleRouteChange = (url) => {
      // Send page view event to monitoring service
      sendAnalyticsData({ eventType: 'pageview', url });
    };

    // Subscribe to route changes
    router.events.on('routeChangeComplete', handleRouteChange);

    // Unsubscribe from route changes on cleanup
    return () => {
      router.events.off('routeChangeComplete', handleRouteChange);
    };
  }, []);

  return <Component {...pageProps} />;
}
This code snippet shows how to set up a client-side custom analytics hook inside the custom _app.js Next.js component. It uses an effect to subscribe to route changes upon component mount (using Next.js router events) and send a page view event to a hypothetical 'sendAnalyticsData' function every time the route changes. It also includes cleanup logic to unsubscribe from the route change events when the component unmounts.
function sendAnalyticsData(data) {
  // Replace with your analytics service endpoint
  const analyticsEndpoint = 'https://your-analytics-endpoint.com/track';

  // Send a post request with the analytics data
  fetch(analyticsEndpoint, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify(data),
  })
    .then((response) => response.json())
    .then((data) => {
      console.log('Success:', data);
    })
    .catch((error) => {
      console.error('Error:', error);
    });
}
This function sends the custom analytics data to an external monitoring service. It posts the data to a specified endpoint using fetch API. Replace 'https://your-analytics-endpoint.com/track' with the actual URL of your monitoring service. The function handles both successful data submission by printing the result to the console and errors by logging them.