BlogNode.js

Pretty print JSON responses with Express

Written by Codemzy on June 27th, 2024

Here are some ways you can pretty print your JSON responses to the browser with Express in Node.js - either globally or for a single route, using the `space` property of `JSON.stringify()`.

To send JSON with Express in Node.js, you can do this:

let myObject = {
  name: "codemzy",
  likes: [ "javascript", "blogging" ],
  isWriting: true,
};
res.json(myObject); // send as JSON response

res.json() will automatically turn your object into JSON (using JSON.stringify()), and set all the necessary headers to send your data as JSON.

Most of my API responses are JSON, so I use this all the time.

The data mostly goes to my front-end React app, and pretty printing the response doesn’t matter.

But I have a few API routes that return JSON to display in the browser. Mostly admin data and sales reports - not something for end users, but information for site admins to see. 

And when I use res.json(), the response shows all in one line in the browser.

Like this:

'{"name":"codemzy","likes":["javascript","blogging"],"isWriting":true}'

It's not very... pretty!

Ok, not a huge deal for my tiny demo JSON response, but for my real-life JSON strings that can be far larger, I really want something more readable.

I need to pretty print the JSON response!

JSON.stringify() has a space parameter that can be used for indentation:

JSON.stringify(value, replacer, space);

And here are a few ways I found to use it in Express.

Globally with "json spaces"

If this is something you need everywhere for your JSON responses, Express has a handy global setting you can use.

The "json spaces" property in application settings.

Since Express uses JSON.stringify(), we can set the space property of JSON.stringify() using this setting.

Here's how it looks:

app.set("json spaces", 2);

From what I've looked at, you can't set this at the router level and sub-apps inherit the value of this setting, so it is pretty global once you've set it.

I didn't want to set this globally, so I continued my quest!

Per response with JSON.stringify()

If, like me, you only need to prettify your JSON on a couple of responses, you might want to do it per response. I thought, since res.json() uses JSON.stringify() under the hood, I could maybe just pass the parameters directly.

// ❌
res.json(myObject, null, 2);

But that doesn't work!

Since res.json() didn't give me direct access to JSON.stringify() and its helpful parameters, I skipped it altogether and did something like this:

res
  .set("Content-type", "application/json; charset=utf-8")
  .send(JSON.stringify(myObject, null, 2));

I set the headers myself for a JSON response and stringified the object to JSON directly.

It gets the job done, but there’s a much cleaner way to set the JSON headers in Express without doing it manually each time. res.type('json') will set the Content-Type header for me, so I can use it like this:

res.type('json').send(JSON.stringify(myObject, null, 2));

Yay!

Much neater.

Let the browser handle it

If you're viewing the JSON in the browser, and it's just for you to view, there's a neat little "Pretty print" toggle in Chrome.

Here's it off:

chrome pretty print off

And when we click that checkbox, our JSON becomes pretty - as if by magic!

chrome pretty print on

It looks like they use 2 spaces for the indention. If this is what you want, and you're using Chrome, you could let the browser handle pretty printing. But I still set up pretty print in Express when I need it so that it works in any browser and I don't get that ugly wall of text on the initial load.