> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/AslamSDM/mentiq-sdk/llms.txt
> Use this file to discover all available pages before exploring further.

# Next.js Integration

> Complete guide to integrating MentiQ Analytics with Next.js App Router and Pages Router

# Next.js Integration

MentiQ Analytics provides seamless integration with Next.js applications, supporting both the App Router (app/) and Pages Router (pages/) patterns with automatic page tracking and server-side analytics.

## App Router Integration

The App Router (Next.js 13+) uses React Server Components. Here's how to integrate MentiQ Analytics:

<Steps>
  <Step title="Install MentiQ SDK">
    ```bash theme={null}
    npm install mentiq-sdk
    # or
    yarn add mentiq-sdk
    ```
  </Step>

  <Step title="Create Analytics Provider">
    Wrap your application with the `AnalyticsProvider` in your root layout:

    ```tsx app/layout.tsx theme={null}
    import { AnalyticsProvider } from "mentiq-sdk";

    export default function RootLayout({
      children,
    }: {
      children: React.ReactNode;
    }) {
      return (
        <html lang="en">
          <body>
            <AnalyticsProvider
              config={{
                apiKey: process.env.NEXT_PUBLIC_MENTIQ_API_KEY!,
                projectId: process.env.NEXT_PUBLIC_MENTIQ_PROJECT_ID!,
                enableAutoPageTracking: true,
                enablePerformanceTracking: true,
                enableErrorTracking: true,
                batchSize: 20,
                flushInterval: 10000,
              }}
            >
              {children}
            </AnalyticsProvider>
          </body>
        </html>
      );
    }
    ```
  </Step>

  <Step title="Use Analytics in Client Components">
    Mark your component with `'use client'` and use the analytics hooks:

    ```tsx app/components/TrackingButton.tsx theme={null}
    'use client';

    import { useAnalytics } from "mentiq-sdk";

    export function TrackingButton() {
      const { track } = useAnalytics();

      const handleClick = () => {
        track("button_clicked", {
          button_id: "hero-cta",
          location: "homepage",
        });
      };

      return <button onClick={handleClick}>Get Started</button>;
    }
    ```
  </Step>
</Steps>

### Alternative: Using withAnalytics Wrapper

For more control over page tracking, use the `withAnalytics` wrapper:

```tsx app/layout.tsx theme={null}
import { withAnalytics } from "mentiq-sdk/nextjs";

const AnalyticsWrapper = withAnalytics({
  apiKey: process.env.NEXT_PUBLIC_MENTIQ_API_KEY!,
  projectId: process.env.NEXT_PUBLIC_MENTIQ_PROJECT_ID!,
  enableAutoPageTracking: true,
});

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>
        <AnalyticsWrapper>{children}</AnalyticsWrapper>
      </body>
    </html>
  );
}
```

<Info>
  The `withAnalytics` wrapper automatically tracks route changes by intercepting `window.history.pushState` and `window.history.replaceState`.
</Info>

## Pages Router Integration

For applications using the traditional Pages Router:

<Steps>
  <Step title="Wrap Application in _app.tsx">
    ```tsx pages/_app.tsx theme={null}
    import type { AppProps } from "next/app";
    import { AnalyticsProvider } from "mentiq-sdk";
    import { useRouter } from "next/router";
    import { useEffect } from "react";
    import { useAnalytics } from "mentiq-sdk";

    function AnalyticsPageTracker() {
      const router = useRouter();
      const { page } = useAnalytics();

      useEffect(() => {
        // Track initial page load
        page({
          url: window.location.href,
          path: router.pathname,
          title: document.title,
        });

        // Track route changes
        const handleRouteChange = (url: string) => {
          page({
            url,
            path: new URL(url, window.location.origin).pathname,
            title: document.title,
          });
        };

        router.events.on("routeChangeComplete", handleRouteChange);
        return () => {
          router.events.off("routeChangeComplete", handleRouteChange);
        };
      }, [router, page]);

      return null;
    }

    export default function App({ Component, pageProps }: AppProps) {
      return (
        <AnalyticsProvider
          config={{
            apiKey: process.env.NEXT_PUBLIC_MENTIQ_API_KEY!,
            projectId: process.env.NEXT_PUBLIC_MENTIQ_PROJECT_ID!,
            enableAutoPageTracking: false, // We handle manually
          }}
        >
          <AnalyticsPageTracker />
          <Component {...pageProps} />
        </AnalyticsProvider>
      );
    }
    ```
  </Step>

  <Step title="Track Events in Pages">
    ```tsx pages/index.tsx theme={null}
    import { useAnalytics } from "mentiq-sdk";

    export default function HomePage() {
      const { track, identify } = useAnalytics();

      const handleSignup = async (email: string) => {
        // Your signup logic...
        
        identify(userId, { email });
        track("signup_completed", {
          method: "email",
          source: "homepage",
        });
      };

      return (
        <div>
          {/* Your page content */}
        </div>
      );
    }
    ```
  </Step>
</Steps>

### Alternative: Using trackPageView Helper

For simpler integration with Pages Router:

```tsx pages/_app.tsx theme={null}
import { useRouter } from "next/router";
import { useEffect } from "react";
import { Analytics } from "mentiq-sdk";
import { trackPageView } from "mentiq-sdk/nextjs";

const analytics = new Analytics({
  apiKey: process.env.NEXT_PUBLIC_MENTIQ_API_KEY!,
  projectId: process.env.NEXT_PUBLIC_MENTIQ_PROJECT_ID!,
});

export default function App({ Component, pageProps }) {
  const router = useRouter();

  useEffect(() => {
    const handleRouteChange = (url: string) => {
      trackPageView(analytics, url);
    };

    router.events.on("routeChangeComplete", handleRouteChange);
    return () => router.events.off("routeChangeComplete", handleRouteChange);
  }, [router.events]);

  return <Component {...pageProps} />;
}
```

## Server-Side Analytics

Track events from API routes and server components:

<Tabs>
  <Tab title="App Router API Route">
    ```ts app/api/signup/route.ts theme={null}
    import { NextRequest, NextResponse } from "next/server";
    import { trackServerEvent } from "mentiq-sdk/nextjs";

    export async function POST(request: NextRequest) {
      const body = await request.json();
      const { email, name } = body;

      // Your signup logic...
      const userId = await createUser(email, name);

      // Track server-side event
      await trackServerEvent(
        {
          apiKey: process.env.MENTIQ_API_KEY!,
          projectId: process.env.MENTIQ_PROJECT_ID!,
        },
        "signup_completed",
        {
          method: "api",
          email_domain: email.split("@")[1],
        },
        {
          userId,
          userAgent: request.headers.get("user-agent") || undefined,
          ip: request.headers.get("x-forwarded-for") || request.ip,
        }
      );

      return NextResponse.json({ success: true, userId });
    }
    ```
  </Tab>

  <Tab title="Pages Router API Route">
    ```ts pages/api/signup.ts theme={null}
    import type { NextApiRequest, NextApiResponse } from "next";
    import { trackServerEvent } from "mentiq-sdk/nextjs";

    export default async function handler(
      req: NextApiRequest,
      res: NextApiResponse
    ) {
      if (req.method !== "POST") {
        return res.status(405).json({ error: "Method not allowed" });
      }

      const { email, name } = req.body;

      // Your signup logic...
      const userId = await createUser(email, name);

      // Track server-side event
      try {
        await trackServerEvent(
          {
            apiKey: process.env.MENTIQ_API_KEY!,
            projectId: process.env.MENTIQ_PROJECT_ID!,
          },
          "signup_completed",
          {
            method: "api",
            email_domain: email.split("@")[1],
          },
          {
            userId,
            userAgent: req.headers["user-agent"],
            ip: req.headers["x-forwarded-for"] as string || req.socket.remoteAddress,
          }
        );
      } catch (error) {
        console.error("Analytics error:", error);
        // Don't fail the request if analytics fails
      }

      return res.status(200).json({ success: true, userId });
    }
    ```
  </Tab>
</Tabs>

### Server Event Context

The `trackServerEvent` function accepts a context object for server-side enrichment:

```ts theme={null}
interface ServerContext {
  userId?: string;       // User ID to associate with event
  userAgent?: string;    // Browser user agent
  ip?: string;          // Client IP address
}
```

<Note>
  Server-side events are sent directly to the MentiQ API without queuing or batching. Make sure to handle errors appropriately.
</Note>

## API Route Analytics Helper

For consistent tracking across multiple API routes, use the `createAnalyticsApiHandler`:

```ts lib/analytics.ts theme={null}
import { createAnalyticsApiHandler } from "mentiq-sdk/nextjs";

export const apiAnalytics = createAnalyticsApiHandler({
  apiKey: process.env.MENTIQ_API_KEY!,
  projectId: process.env.MENTIQ_PROJECT_ID!,
  debug: process.env.NODE_ENV === "development",
});
```

Then use it in your API routes:

```ts pages/api/purchase.ts theme={null}
import { apiAnalytics } from "@/lib/analytics";
import type { NextApiRequest, NextApiResponse } from "next";

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  const { userId, productId, amount } = req.body;

  // Process purchase...
  const orderId = await processPurchase(userId, productId, amount);

  // Track with helper
  apiAnalytics.track(
    "purchase_completed",
    {
      product_id: productId,
      amount,
      order_id: orderId,
    },
    userId
  );

  // Optionally flush immediately
  await apiAnalytics.flush();

  return res.status(200).json({ orderId });
}
```

## Middleware for Request Tracking

Track all API requests automatically with the analytics middleware:

<Warning>
  This middleware tracks **all** API requests. Use carefully in production as it may generate high event volumes.
</Warning>

```ts middleware.ts theme={null}
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
import { createAnalyticsMiddleware } from "mentiq-sdk/nextjs";

const analyticsMiddleware = createAnalyticsMiddleware({
  apiKey: process.env.MENTIQ_API_KEY!,
  projectId: process.env.MENTIQ_PROJECT_ID!,
});

export async function middleware(request: NextRequest) {
  // Only track API routes
  if (request.nextUrl.pathname.startsWith("/api/")) {
    const response = NextResponse.next();
    
    // Track request (fire and forget)
    analyticsMiddleware(request, response, () => {}).catch(console.error);
    
    return response;
  }

  return NextResponse.next();
}

export const config = {
  matcher: "/api/:path*",
};
```

The middleware automatically tracks:

* `api_request_start` - When request begins
* `api_request_complete` - When request completes (with duration and status code)

## Environment Variables

Create a `.env.local` file in your project root:

```bash .env.local theme={null}
# Public keys (safe for client-side)
NEXT_PUBLIC_MENTIQ_API_KEY=your_public_api_key
NEXT_PUBLIC_MENTIQ_PROJECT_ID=your_project_id

# Private keys (server-side only)
MENTIQ_API_KEY=your_private_api_key
MENTIQ_PROJECT_ID=your_project_id
MENTIQ_ENDPOINT=https://api.mentiq.io
```

<Info>
  Use `NEXT_PUBLIC_*` prefixed variables for client-side code and unprefixed variables for server-side code to maintain security.
</Info>

## TypeScript Configuration

Ensure your `tsconfig.json` includes proper type resolution:

```json tsconfig.json theme={null}
{
  "compilerOptions": {
    "moduleResolution": "bundler",
    "resolveJsonModule": true,
    "paths": {
      "@/*": ["./src/*"]
    }
  }
}
```

## Best Practices

<Steps>
  <Step title="Separate Client and Server Keys">
    Use different API keys for client-side and server-side tracking to maintain security and enable proper rate limiting.
  </Step>

  <Step title="Handle Errors Gracefully">
    Always wrap analytics calls in try-catch blocks to prevent analytics failures from breaking your application:

    ```ts theme={null}
    try {
      await trackServerEvent(config, event, properties);
    } catch (error) {
      console.error("Analytics error:", error);
      // Continue with application logic
    }
    ```
  </Step>

  <Step title="Optimize Batch Settings">
    Configure appropriate batch sizes and flush intervals based on your traffic:

    ```ts theme={null}
    // High-traffic apps
    batchSize: 50,
    flushInterval: 5000, // 5 seconds

    // Low-traffic apps
    batchSize: 10,
    flushInterval: 30000, // 30 seconds
    ```
  </Step>

  <Step title="Use Debug Mode in Development">
    Enable debug logging during development:

    ```ts theme={null}
    config={{
      debug: process.env.NODE_ENV === "development",
      // ... other config
    }}
    ```
  </Step>
</Steps>

## Troubleshooting

### Page Views Not Tracking

<Accordion title="App Router">
  Make sure `enableAutoPageTracking: true` is set in your config, and that the `AnalyticsProvider` wraps your entire application in the root layout.
</Accordion>

<Accordion title="Pages Router">
  Ensure you're tracking route changes with `router.events.on("routeChangeComplete")` or using the `trackPageView` helper.
</Accordion>

### Server-Side Events Failing

<Check>Verify your server-side API key is correct and has proper permissions</Check>
<Check>Ensure the endpoint URL is accessible from your server</Check>
<Check>Check that you're using the private API key (not the public one)</Check>

### TypeScript Errors

```bash theme={null}
# Regenerate types
npm run type-check

# Or install type definitions
npm install --save-dev @types/node
```

## Next Steps

<CardGroup cols={2}>
  <Card title="TypeScript Types" icon="code" href="/guides/typescript">
    Learn about TypeScript interfaces and types
  </Card>

  <Card title="Event Batching" icon="layer-group" href="/guides/event-batching">
    Understand batching and queuing system
  </Card>

  <Card title="Privacy Compliance" icon="shield" href="/guides/privacy-compliance">
    Implement privacy features and data masking
  </Card>
</CardGroup>
