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

# Next.js

export const VersionRequirements = ({versions = []}) => {
  if (!Array.isArray(versions) || versions.length === 0) {
    return null;
  }
  const boundaries = {
    upper: " or lower",
    exact: "",
    lower: " or higher"
  };
  const containerStyle = {
    marginTop: "0.5rem",
    marginBottom: "1.5rem"
  };
  const lineStyle = {
    display: "block",
    margin: "0 0 0.35rem 0",
    fontSize: "0.875rem",
    lineHeight: "1.4"
  };
  const pillBaseStyle = {
    display: "inline-block",
    padding: "0.1em 0.4em",
    borderRadius: "0.25rem",
    border: "1px solid",
    fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace",
    fontSize: "0.85em",
    fontWeight: 500
  };
  const pillColors = {
    "AppSignal for Elixir": {
      background: "#f3e8ff",
      borderColor: "#e9d5ff",
      color: "#9333ea"
    },
    "AppSignal for Front-end": {
      background: "#fef9c3",
      borderColor: "#fde68a",
      color: "#ca8a04"
    },
    "AppSignal for Go": {
      background: "#ccfbf1",
      borderColor: "#99f6e4",
      color: "#0d9488"
    },
    "AppSignal for JavaScript": {
      background: "#fef9c3",
      borderColor: "#fde68a",
      color: "#ca8a04"
    },
    "AppSignal for Node.js": {
      background: "#dcfce7",
      borderColor: "#bbf7d0",
      color: "#16a34a"
    },
    "AppSignal for Python": {
      background: "#dbeafe",
      borderColor: "#bfdbfe",
      color: "#2563eb"
    },
    "AppSignal for Ruby": {
      background: "#fee2e2",
      borderColor: "#fecaca",
      color: "#dc2626"
    },
    "AppSignal for Rust": {
      background: "#ffedd5",
      borderColor: "#fed7aa",
      color: "#ea580c"
    }
  };
  const defaultPillColor = {
    background: "#f4f4f5",
    borderColor: "#e4e4e7",
    color: "#52525b"
  };
  const getPillStyle = name => ({
    ...pillBaseStyle,
    ...pillColors[name] || defaultPillColor
  });
  const getBoundText = bound => {
    return boundaries[bound] || boundaries.lower;
  };
  return <div style={containerStyle}>
      {versions.map((v, i) => <p key={`${v.name}-${v.version}-${v.bound || "lower"}-${i}`} style={lineStyle}>
          This feature requires{" "}
          <code style={getPillStyle(v.name)}>{v.name}</code> version {v.version}
          {getBoundText(v.bound)}.
        </p>)}
    </div>;
};

<VersionRequirements
  versions={[
{ name: "AppSignal for Node.js", version: "3.0.14" },
{ name: "Next.js", version: "13.3.0" }
]}
/>

The AppSignal integration for [Next.js](https://nextjs.org/).

To report both back-end traces and front-end errors, it is recommended to use `@appsignal/nodejs` in combination with [`@appsignal/javascript`](/front-end) and [`@appsignal/react`](/front-end/integrations/react) on the client-side for full-stack performance monitoring and error tracking.

<Tip>
  Due to technical limitations of the AppSignal agent, it is not possible to use
  `@appsignal/nodejs` on Vercel's serverless environment. We recommend using our
  [Vercel log drain](/vercel/logs) and our [front-end
  JavaScript](/front-end) and [React](/front-end/integrations/react)
  packages instead.
</Tip>

## Installation

First, follow the [`@appsignal/nodejs` installation instructions](/nodejs/3.x/installation).

Then, modify your Next project's `next.config.js` configuration file in order to enable instrumentation hooks:

If you are using Next 15:

<CodeGroup>
  ```javascript JavaScript theme={null}
  const nextConfig = {
    serverExternalPackages: ["@appsignal/nodejs"],
  };
  ```
</CodeGroup>

If you are using Next 13 or 14:

<CodeGroup>
  ```javascript JavaScript theme={null}
  const nextConfig = {
    // Add the `experimental` object if not present
    experimental: {
      // Add the following lines inside the object
      instrumentationHook: true,
      serverComponentsExternalPackages: ["@appsignal/nodejs"],
    },
  };
  ```
</CodeGroup>

Then, add the following file to the root of your Next.js project as `instrumentation.js`:

<Tip>
  If your project has an `src` directory, then the `instrumentation.js` file should be placed in that directory.

  If your project is using the [Next.js App Router](https://nextjs.org/docs/app/building-your-application/routing/defining-routes), the file should not be placed inside the `app` folder, but in the folder that contains the `app` folder.
</Tip>

<CodeGroup>
  ```javascript JavaScript theme={null}
  export function register() {
    if (process.env.NEXT_RUNTIME === "nodejs") {
      require("./appsignal.cjs");
    }
  }
  ```
</CodeGroup>

The instrumentation hook file references the `appsignal.cjs` file that was created [when configuring AppSignal](/nodejs/3.x/configuration#minimal-required-configuration). Make sure that the `appsignal.cjs` file is in the same folder as the `instrumentation.js` file, or adjust the path of the `require` in the `instrumentation.js` file accordingly.

Finally, modify your `appsignal.cjs` configuration file in order to disable the HTTP instrumentation, which would otherwise generate redundant traces:

<CodeGroup>
  ```javascript JavaScript theme={null}
  const { Appsignal } = require("@appsignal/nodejs");

  new Appsignal({
    // Add the `disableDefaultInstrumentations` list if not present
    disableDefaultInstrumentations: [
      // Add the following line inside the list
      "@opentelemetry/instrumentation-http",
    ],
  });
  ```
</CodeGroup>

### TypeScript support

When using TypeScript, the backtraces emitted by server-side Next.js errors will refer to the compiled JavaScript files. Follow these steps to configure Next.js so that the backtraces refer to the original TypeScript code.

First, configure Next.js to emit source maps by adding the following lines to your application's `next.config.js` file:

<CodeGroup>
  ```javascript JavaScript theme={null}
  const nextConfig = {
    // Add the `webpack` function if not present
    webpack: (config, { isServer }) => {
      // Add the following lines inside the function
      if (isServer) {
        config.devtool = "eval-source-map";
      }

      return config;
    },
  };
  ```
</CodeGroup>

Then, in your `package.json`, modify how your Next.js application is started when running `npm run start`, using the `NODE_OPTIONS` environment variable to pass the `--enable-source-maps` flag to the Node.js runtime:

<CodeGroup>
  ```json JSON theme={null}
  {
    "scripts": {
      // Modify the `start` script as follows
      "start": "NODE_OPTIONS=--enable-source-maps next start"
    }
  }
  ```
</CodeGroup>

Finally, if using the `@appsignal/javascript` front-end integration package to track client-side errors, add the `productionBrowserSourceMaps` option to the `next.config.js` file for Next.js to emit public source maps:

<CodeGroup>
  ```javascript JavaScript theme={null}
  const nextConfig = {
    // Add the `productionBrowserSourceMaps` flag
    productionBrowserSourceMaps: true,
  };
  ```
</CodeGroup>

## Features

The Next.js integration will send AppSignal a performance sample for each request.

Within each sample, the event timeline will show events, along with their duration, corresponding to:

* Rendering the document
* Running the `getServerSideProps` function *(pages router only)*
* Running the route handler
* Performing HTTP requests using Next.js' server-side `fetch` *(app router only)*

## Standalone output

No data may be reported when Next.js is configured with `output: "standalone"` in `next.config.js`. When Next.js optimizes its app size to only include what is used by the app, it omits the AppSignal extension and agent, which report the data to our servers.

When using the [Next.js "with-docker" starter](https://github.com/vercel/next.js/tree/canary/examples/with-docker), specifically the [Dockerfile](https://github.com/vercel/next.js/blob/canary/examples/with-docker/Dockerfile), a modification is required to make sure the AppSignal extension and agent are included in the production Docker image.

Add the following line to your `Dockerfile`, after similar `COPY` lines near the end of the file:

<CodeGroup>
  ```docker Dockerfile theme={null}
  # Dockerfile
  COPY --from=builder --chown=nextjs:nodejs /app/node_modules/@appsignal/nodejs ./node_modules/@appsignal/nodejs
  ```
</CodeGroup>

The change in Git will look something like this, but your Dockerfile may be slightly different:

<CodeGroup>
  ```diff Diff theme={null}
  --- Dockerfile
  +++ Dockerfile
  @@ -48,6 +48,7 @@ COPY --from=builder /app/public ./public
   # https://nextjs.org/docs/advanced-features/output-file-tracing
   COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
   COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
  +COPY --from=builder --chown=nextjs:nodejs /app/node_modules/@appsignal/nodejs ./node_modules/@appsignal/nodejs

   USER nextjs
  ```
</CodeGroup>
