Title: Debug a Node.js application
Author: WordPress VIP Documentation
Published: July 22, 2022
Last modified: January 1, 2026

---

 1. [Node.js on VIP](https://docs.wpvip.com/node-js/)
 2. Debug a Node.js application

#  Debug a Node.js application

Debugging against a remote environment, such as a [VIP Platform environment](https://docs.wpvip.com/vip-platform/environments/),
can be limiting and challenging. For this reason, it is recommended to debug Node.
js application issues on a local development environment. Make an effort to reproduce
issues locally, and to keep the local development environment in close synchronization
with remote environments.

Avoid writing environment-specific code that runs on one environment type but is
skipped on others (e.g., on Production but not on Develop). Environment-specific
code can lead to issues that are very difficult to debug. If environment-specific
code cannot be avoided, log liberally to clearly indicate when the conditional code
is running, and when it is not.

**Note**

VIP Support does not provide assistance with questions or issues related to the 
application code of a Node.js application. Node.js applications are not eligible
for the debugging feature regardless of [the contracted pricing plan](https://wpvip.com/pricing/)
that an organization has with VIP.

## Web browser developer tools

Most web browsers include [developer tools](https://developer.mozilla.org/en-US/docs/Learn/Common_questions/What_are_browser_developer_tools)
that make it possible for developers to inspect network requests made by visitors
to an application.

Using developer tools regularly in a local development environment is helpful for
gaining a familiarity with the normal network activity generated by an application.
This familiarity can be a helpful reference for recognizing issues before they are
pushed to production. Be cautious when modifying some settings in the developer 
tools dashboard that might change the behavior of network requests (e.g., “Disable
cache”).

## cURL

[cURL](https://curl.se/docs/manpage.html) is a command-line tool that can be used
to simulate requests to an application and provide a response for inspection. cURL
commands are easily shared, enable issues to be replicated by multiple team members,
and are a quick way to communicate the _how_ and _why_ of a problem.

By including the `-I` option in a cURL command, only the response headers will be
returned in the output. Header responses can provide insights into page cache behavior,
payload size, and more.

In this command example, `curl -I` is run against a VIP Platform Node.js application
running at `https://nodejstestsite.go-vip.net`:

    ```wp-block-preformatted
    $ curl -I "https://nodejstestsite.go-vip.net/latest/post"
    HTTP/2 200
    server: nginx
    date: Tue, 14 Jun 2022 15:40:40 GMT
    content-type: text/html; charset=utf-8
    content-length: 5160
    x-powered-by: Next.js
    cache-control: public, max-age=300
    age: 4
    x-cache: hit
    vary: X-Mobile-Class, Accept-Encoding
    accept-ranges: bytes
    strict-transport-security: max-age=31536000
    ```

In the example command output above:

 * The returned HTTP status code `200` indicates a healthy response.
 * The `x-cache` header is evidence that the request passed through the VIP Platform’s
   [page cache](https://docs.wpvip.com/caching/page-cache/), and the header’s `[hit](https://docs.wpvip.com/caching/page-cache/#h-review-details-about-cache-behavior)`
   value indicates that the response was served from cache.

cURL can also be used to expose and investigate problems.

In this command example, `curl -I` is run against `http://localhost:3000`:

    ```wp-block-preformatted
    $ curl -I "http://localhost:3000"
    curl: (7) Failed to connect to localhost port 3000 after 9 ms: Connection refused
    ```

The command output returns a “Failed” message instead of an HTTP status code, indicating
that no application is listening on port 3000.

### Limitations

cURL is a powerful tool but it does not behave the same way as a web browser. In
particular, requests made with cURL do not automatically send the request headers
that are typically sent by some web browsers. If an application’s behavior varies
based on the presence of browser-specific request headers, use the [“Copy as cURL” feature](https://developer.chrome.com/blog/replay-a-network-request-in-curl/)
provided by many web browser’s development tools. This will ensure that the cURL
requests will include the expected request headers.

## Node.js inspector

Node.js includes a [debugging inspector](https://nodejs.org/en/docs/guides/debugging-getting-started/)
that allows developers to set breakpoints, step through code, inspect variables,
and more—for both client and server-side applications. Most web browsers include
a client that connects to the inspection port opened by Node.js and provides a graphical
interface for debugging. This approach can be more effective than “manually” debugging
an application, and is worth the time required to set it up.

[Instructions for enabling the inspector](https://nodejs.org/en/docs/guides/debugging-getting-started/#enable-inspector)—
as well as a [command-line debugging utility](https://nodejs.org/api/debugger.html)
option—can be found in Node.js documentation.

**Caution**

[For security reasons](https://nodejs.org/en/docs/guides/debugging-getting-started/#security-implications),
only run the Node.js inspector on local, non-public applications.

## Logging

Logging can be used to inspect requests and responses as they flow through an application’s
code. Logging is useful for gathering context around issues and debugging them, 
especially in remote environments.

On the VIP Platform, [`console.*`](https://nodejs.org/api/console.html#class-console)
can be used by Node.js applications to log information and make it available in 
[application logs](https://docs.wpvip.com/vip-dashboard/health-logs/). For maximum
readability, always convert non-string values to strings (e.g., using `[JSON.stringify](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify)`).

Knowing _what_ and _where_ to log is critical to logging effectively. Next.js and
Apollo are two examples of useful locations within certain frameworks and libraries
where logging can be most effective.

### Next.js

Next.js recently introduced the construct of [middleware](https://nextjs.org/docs/advanced-features/middleware),
which provides a way to inspect every request and potentially modify the response.
The main function of Next.js middleware is to respond to [health checks](https://docs.wpvip.com/node-js/health-checks/),
but it can also be extended to log information about incoming requests. An [example implementation of middleware](https://github.com/Automattic/vip-go-nextjs-skeleton/blob/trunk/middleware.ts)
is provided in the [vip-go-nextjs-skeleton](https://github.com/Automattic/vip-go-nextjs-skeleton)
GitHub repository.

### Apollo

[Apollo](https://www.apollographql.com/) is a GraphQL client that is used for communication
between a Node.js front end and a WordPress back end. [`ApolloLink`](https://www.apollographql.com/docs/react/api/link/introduction/)
is an Apollo module that makes it possible to customize the flow of data between
the Apollo client and the GraphQL server. `ApolloLink` is a useful location to add
logging, and can be helpful for understanding data that is requested by an application.
A [custom `ApolloLink`](https://github.com/Automattic/vip-go-nextjs-skeleton/blob/trunk/graphql/apollo-link.ts)
for logging information about requests is included in [vip-go-nextjs-skeleton](https://github.com/Automattic/vip-go-nextjs-skeleton)
and can be used to correlate front-end and back-end requests.

Last updated: January 01, 2026