> ## Documentation Index
> Fetch the complete documentation index at: https://docs.codeqr.io/llms.txt
> Use this file to discover all available pages before exploring further.

# NextAuth.js

> Learn how to track lead conversion events with NextAuth.js and CodeQR

<Note>
  Conversion tracking requires a [Pro plan](https://codeqr.io/pricing)
  subscription or higher (or an active conversion trial).
</Note>

When it comes to [conversion tracking](/conversions/quickstart), a `lead` event happens when a user performs an action that indicates interest in your product or service. This could be anything from:

* Signing up for an account
* Adding a product to cart
* Joining a mailing list

<Frame>
  <img className="rounded-lg border border-gray-100" src="https://assets.codeqr.io/help/conversion-lead-event.png" alt="A diagram showing how lead events are tracked in the conversion funnel" />
</Frame>

In this guide, we will be focusing on tracking new user sign-ups for a SaaS application that uses NextAuth.js for user authentication.

## Prerequisites

Before you get started, make sure you follow the [CodeQR Conversions quickstart guide](/conversions/quickstart) to get CodeQR Conversions set up for your links:

1. [Enable conversion tracking for your links](/conversions/quickstart#step-1-enable-conversion-tracking-for-your-links)
2. [Install the @codeqr/analytics client-side SDK](/sdks/client-side/introduction)
3. [Install the CodeQR server-side SDK](/conversions/quickstart#step-3-install-the-codeqr-server-side-sdk)

## Configure NextAuth.js Options

Then, set up your NextAuth.js configuration options to track lead conversion events using the `codeqr` TypeScript SDK.

Here's how it works in a nutshell:

1. Use NextAuth's [`signIn` event](https://next-auth.js.org/configuration/events#signin) to detect when there's a new sign up.
2. If the user is a new sign up, check if the `cq_id` cookie is present.
3. If the `cq_id` cookie is present, send a lead event to CodeQR using `codeqr.track.lead`
4. Delete the `cq_id` cookie.

Under the hood, CodeQR records the user as a customer and associates them with the click event that they came from. The user's unique ID is now the source of truth for all future events – hence why we don't need the `cq_id` cookie anymore.

<CodeGroup>
  ```typescript App Router theme={null}
  // app/api/auth/[...nextauth]/options.ts
  import type { NextAuthOptions } from "next-auth";
  import { cookies } from "next/headers";
  import { codeqr } from "@/lib/codeqr";

  export const authOptions: NextAuthOptions = {
    ...otherAuthOptions, // your other NextAuth options
    events: {
      async signIn(message) {
        // if it's a new sign up
        if (message.isNewUser) {
          // check if cq_id cookie is present
          const cq_id = cookies().get("cq_id")?.value;
          if (cq_id) {
            // send lead event to CodeQR
            await codeqr.track.lead({
              clickId: cq_id,
              eventName: "Sign Up",
              customerExternalId: user.id,
              customerName: user.name,
              customerEmail: user.email,
              customerAvatar: user.image,
            });
            // delete the cq_id cookie
            cookies().set("cq_id", "", {
              expires: new Date(0),
            });
          }
        }
      },
    },
  };
  ```

  ```typescript Pages Router theme={null}
  // pages/api/auth/[...nextauth]/options.ts
  import type { NextApiRequest } from "next";
  import type { NextAuthOptions } from "next-auth";
  import { codeqr } from "@/lib/codeqr";

  export const getOptions = (req: NextApiRequest): NextAuthOptions => ({
    ...otherAuthOptions, // your other NextAuth options
    events: {
      async signIn(message) {
        // if it's a new sign up
        if (message.isNewUser) {
          // check if cq_id cookie is present
          const { cq_id } = req.cookies;
          if (cq_id) {
            // send lead event to CodeQR
            await codeqr.track.lead({
              clickId: cq_id,
              eventName: "Sign Up",
              customerExternalId: user.id,
              customerName: user.name,
              customerEmail: user.email,
              customerAvatar: user.image,
            });
          }
        }
      },
    },
  });
  ```
</CodeGroup>

<Tip>
  In NextAuth.js, the `isNewUser` flag will [only be available if you're using
  `next-auth`'s database
  implementation](https://next-auth.js.org/configuration/options#callbacks)
  (otherwise it'll return `undefined`). In that case, you should move the logic
  above to the [`signIn`
  `callback`](https://next-auth.js.org/configuration/callbacks) instead.
</Tip>

Here's the full list of attributes you can pass when sending a lead event:

| Property             | Required | Description                                                                                                              |
| :------------------- | :------- | :----------------------------------------------------------------------------------------------------------------------- |
| `clickId`            | **Yes**  | The unique `cq_id` parameter that the lead conversion event is attributed to.                                            |
| `eventName`          | **Yes**  | The name of the event. Example: "Sign up".                                                                               |
| `customerExternalId` | **Yes**  | The unique ID of the customer in your system. Will be used to identify and attribute all future events to this customer. |
| `customerEmail`      | No       | The email address of the customer.                                                                                       |
| `customerName`       | No       | The name of the customer. If not passed, a random name will be generated (e.g. "Big Red Caribou").                       |
| `customerAvatar`     | No       | The avatar URL of the customer.                                                                                          |

## Create a NextAuth.js Route Handler

Finally, import the `authOptions` variable you created earlier and use `NextAuth` to create a handler for your NextAuth.js routes.

<CodeGroup>
  ```typescript App Router theme={null}
  // app/api/auth/[...nextauth]/index.ts
  import { authOptions } from "./options";
  import NextAuth from "next-auth";

  const handler = NextAuth(authOptions);

  export { handler as GET, handler as POST };
  ```

  ```typescript Pages Router theme={null}
  // pages/api/auth/[...nextauth]/index.ts
  import type { NextApiRequest, NextApiResponse } from "next";
  import NextAuth from "next-auth";
  import { getOptions } from "./options";

  const handler = (req: NextApiRequest, res: NextApiResponse) =>
    NextAuth(req, res, getOptions(req));

  export default handler;
  ```
</CodeGroup>

## View your conversions

Once you've enabled conversion tracking for your links, all your tracked conversions will show up on your [Analytics dashboard](https://app.codeqr.io/analytics). We provide 3 different views to help you understand your conversions:

* **Time-series**: A [time-series view](https://codeqr.io/help/article/codeqr-analytics#1-time-series-analytics-chart) of the number clicks, leads and sales.

<Frame>
  <img src="https://mintcdn.com/codeqr/Dit-PkrrSHQLOViA/images/conversions/timeseries-chart.png?fit=max&auto=format&n=Dit-PkrrSHQLOViA&q=85&s=c7bac376603cd71f967f5f7b33f3cadc" alt="Time-series line chart" width="1600" height="900" data-path="images/conversions/timeseries-chart.png" />
</Frame>

* **Funnel chart**: A funnel chart view visualizing the conversion & dropoff rates across the different steps in the conversion funnel (clicks → leads → sales).

<Frame>
  <img src="https://mintcdn.com/codeqr/Dit-PkrrSHQLOViA/images/conversions/funnel-chart.png?fit=max&auto=format&n=Dit-PkrrSHQLOViA&q=85&s=001b9b2dad0f759c4031d81122069a75" alt="Funnel chart view showing the conversion & dropoff rates from clicks → leads → sales" width="1600" height="900" data-path="images/conversions/funnel-chart.png" />
</Frame>

* **Real-time events stream**: A [real-time events stream](https://codeqr.io/help/article/real-time-events-stream) of every single conversion event that occurs across all your links in your project.

<Frame>
  <img src="https://mintcdn.com/codeqr/Dit-PkrrSHQLOViA/images/conversions/events-table.png?fit=max&auto=format&n=Dit-PkrrSHQLOViA&q=85&s=93b55a350e472e6d7fbafa7e082bbc69" alt="The Events Stream dashboard on CodeQR" width="1600" height="900" data-path="images/conversions/events-table.png" />
</Frame>
