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 {
        styles: (
    } finally {

  render() {
    // Custom logic to send page view events to an analytics service can go here
    return (
          <Main />
          <NextScript />

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'routeChangeComplete', handleRouteChange);

    // Unsubscribe from route changes on cleanup
    return () => {'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 = '';

  // 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 '' 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.