pretty-print JSON using JavaScript
How can I display JSON in an easy-to-read (for human readers) format? I’m looking primarily for indentation and whitespace, with perhaps even colors / font-styles / etc.
If you’re just outputting to html, you can wrap it in a
tag.
all answer will work but you have to use javascript :: var str = JSON.stringify(obj, null, 2); in html //
Use JSON.stringify(data, null, 2) to format data, then use AceEditor, CodeMirror, or Monaco Editor to display it.
31 Answers 31
Pretty-printing is implemented natively in JSON.stringify() . The third argument enables pretty printing and sets the spacing to use:
var str = JSON.stringify(obj, null, 2); // spacing level = 2
If you need syntax highlighting, you might use some regex magic like so:
function syntaxHighlight(json) < if (typeof json != 'string') < json = JSON.stringify(json, undefined, 2); >json = json.replace(/&/g, '&').replace(//g, '>'); return json.replace(/("(\\u[a-zA-Z0-9]|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function (match) < var cls = 'number'; if (/^"/.test(match)) < if (/:$/.test(match)) < cls = 'key'; >else < cls = 'string'; >> else if (/true|false/.test(match)) < cls = 'boolean'; >else if (/null/.test(match)) < cls = 'null'; >return '' + match + ''; >); >
Or a full snippet provided below:
function output(inp) < document.body.appendChild(document.createElement('pre')).innerHTML = inp; >function syntaxHighlight(json) < json = json.replace(/&/g, '&').replace(//g, '>'); return json.replace(/("(\\u[a-zA-Z0-9]|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function (match) < var cls = 'number'; if (/^"/.test(match)) < if (/:$/.test(match)) < cls = 'key'; >else < cls = 'string'; >> else if (/true|false/.test(match)) < cls = 'boolean'; >else if (/null/.test(match)) < cls = 'null'; >return '' + match + ''; >); > var obj = >]>; var str = JSON.stringify(obj, undefined, 4); output(str); output(syntaxHighlight(str));
pre .string < color: green; >.number < color: darkorange; >.boolean < color: blue; >.null < color: magenta; >.key
Super awesome. I added a function to pop open this in a new window for debugging: var json = syntaxHighlight(JSON.stringify(obj,undefined,4);); var w = window.open(); var html = «
pre .string < color: green; >«; html+= » .number < color: darkorange; >.boolean < color: blue; >.null < color: magenta; >.key «; html+= «"+json+"
«; w.document.writeln(html);
Nice. Don’t forget it needs css and a
, though.
Note that stringify(. ) works on JSON objects, not on JSON strings. If you have a string, you need to JSON.parse(. ) first
Hello, this is awesome. It works but I get a lint warning on the second-to-last backslash in the regex- Unnecessary escape character: \- no-useless-escape. I don’t have it unit tested so afraid to // eslint-disable-next-line
User Pumbaa80’s answer is great if you have an object you want pretty printed. If you’re starting from a valid JSON string that you want to pretty printed, you need to convert it to an object first:
var jsonString = ''; var jsonPretty = JSON.stringify(JSON.parse(jsonString),null,2);
This builds a JSON object from the string, and then converts it back to a string using JSON stringify’s pretty print.
JSON.stringify(jsonobj,null,'\t')
this was great. and as a tip, load the result in
RESULT
to see formatted in html page too.
var jsonObj = ; document.getElementById("result-before").innerHTML = JSON.stringify(jsonObj);
In case of displaying in HTML, you should to add a balise
document.getElementById("result-after").innerHTML = "
"+JSON.stringify(jsonObj,undefined, 2) +""
var jsonObj = ; document.getElementById("result-before").innerHTML = JSON.stringify(jsonObj); document.getElementById("result-after").innerHTML = "
"+JSON.stringify(jsonObj,undefined, 2) +""
I think you’re looking for something like this :
This «pretty-prints» your JSON string, using a tab for indentation.
If you prefer to use spaces instead of tabs, you could also use a number for the number of spaces you’d like :
Based on Pumbaa80’s answer I have modified the code to use the console.log colours (working on Chrome for sure) and not HTML. Output can be seen inside console. You can edit the _variables inside the function adding some more styling.
function JSONstringify(json) < if (typeof json != 'string') < json = JSON.stringify(json, undefined, '\t'); >var arr = [], _string = 'color:green', _number = 'color:darkorange', _boolean = 'color:blue', _null = 'color:magenta', _key = 'color:red'; json = json.replace(/("(\\u[a-zA-Z0-9]|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function (match) < var style = _number; if (/^"/.test(match)) < if (/:$/.test(match)) < style = _key; >else < style = _string; >> else if (/true|false/.test(match)) < style = _boolean; >else if (/null/.test(match)) < style = _null; >arr.push(style); arr.push(''); return '%c' + match + '%c'; >); arr.unshift(json); console.log.apply(console, arr); >
Here is a bookmarklet you can use:
javascript:function JSONstringify(json) var arr = [],_string = 'color:green',_number = 'color:darkorange',_boolean = 'color:blue',_null = 'color:magenta',_key = 'color:red';json = json.replace(/("(\\u[a-zA-Z0-9]|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function (match) else > else if (/true|false/.test(match)) else if (/null/.test(match)) arr.push(style);arr.push('');return '%c' + match + '%c';>);arr.unshift(json);console.log.apply(console, arr);>;void(0);
var obj = >]>; JSONstringify(obj);
Edit: I just tried to escape the % symbol with this line, after the variables declaration:
But I find out that Chrome is not supporting % escaping in the console. Strange. Maybe this will work in the future.
You can use console.dir() , which is a shortcut for console.log(util.inspect()) . (The only difference is that it bypasses any custom inspect() function defined on an object.)
It uses syntax-highlighting, smart indentation, removes quotes from keys and just makes the output as pretty as it gets.
const object = JSON.parse(jsonString) console.dir(object, )
cat package.json | node -e «process.stdin.pipe(new stream.Writable( console.dir(JSON.parse(chunk), )>))»
I use the JSONView Chrome extension (it is as pretty as it gets :):
I’ve also released an online stand-alone JSON pretty print viewer, jsonreport.js, that provides a human readable HTML5 report you can use to view any JSON data.
If you are using ES5, simply call JSON.stringify with:
JSON.stringify(anObject, null, '\t');
Here’s user123444555621’s awesome HTML one adapted for terminals. Handy for debugging Node scripts:
function prettyJ(json) < if (typeof json !== 'string') < json = JSON.stringify(json, undefined, 2); >return json.replace(/("(\\u[a-zA-Z0-9]|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function (match) < let cls = "\x1b[36m"; if (/^"/.test(match)) < if (/:$/.test(match)) < cls = "\x1b[34m"; >else < cls = "\x1b[32m"; >> else if (/true|false/.test(match)) < cls = "\x1b[35m"; >else if (/null/.test(match)) < cls = "\x1b[31m"; >return cls + match + "\x1b[0m"; > ); >
// thing = any json OR string of json prettyJ(thing);
For debugging purpose I use:
You can use JSON.stringify(your object, null, 2) The second parameter can be used as a replacer function which takes key and Val as parameters.This can be used in case you want to modify something within your JSON object.
Unsatisfied with other pretty printers for Ruby, I wrote my own (NeatJSON) and then ported it to JavaScript including a free online formatter. The code is free under MIT license (quite permissive).
- Set a line width and wrap in a way that keeps objects and arrays on the same line when they fit, wrapping one value per line when they don’t.
- Sort object keys if you like.
- Align object keys (line up the colons).
- Format floating point numbers to specific number of decimals, without messing up the integers.
- ‘Short’ wrapping mode puts opening and closing brackets/braces on the same line as values, providing a format that some prefer.
- Granular control over spacing for arrays and objects, between brackets, before/after colons and commas.
- Function is made available to both web browsers and Node.js.
I’ll copy the source code here so that this is not just a link to a library, but I encourage you to go to the GitHub project page, as that will be kept up-to-date and the code below will not.
(function(exports) < exports.neatJSON = neatJSON; function neatJSON(value,opts)< opts = opts || <>if (!('wrap' in opts)) opts.wrap = 80; if (opts.wrap==true) opts.wrap = -1; if (!('indent' in opts)) opts.indent = ' '; if (!('arrayPadding' in opts)) opts.arrayPadding = ('padding' in opts) ? opts.padding : 0; if (!('objectPadding' in opts)) opts.objectPadding = ('padding' in opts) ? opts.padding : 0; if (!('afterComma' in opts)) opts.afterComma = ('aroundComma' in opts) ? opts.aroundComma : 0; if (!('beforeComma' in opts)) opts.beforeComma = ('aroundComma' in opts) ? opts.aroundComma : 0; if (!('afterColon' in opts)) opts.afterColon = ('aroundColon' in opts) ? opts.aroundColon : 0; if (!('beforeColon' in opts)) opts.beforeColon = ('aroundColon' in opts) ? opts.aroundColon : 0; var apad = repeat(' ',opts.arrayPadding), opad = repeat(' ',opts.objectPadding), comma = repeat(' ',opts.beforeComma)+','+repeat(' ',opts.afterComma), colon = repeat(' ',opts.beforeColon)+':'+repeat(' ',opts.afterColon); return build(value,''); function build(o,indent)< if (o===null || o===undefined) return indent+'null'; else< switch(o.constructor)< case Number: var isFloat = (o === +o && o !== (o|0)); return indent + ((isFloat && ('decimals' in opts)) ? o.toFixed(opts.decimals) : (o+'')); case Array: var pieces = o.map(function(v)< return build(v,'') >); var oneLine = indent+'['+apad+pieces.join(comma)+apad+']'; if (opts.wrap===false || oneLine.length<=opts.wrap) return oneLine; if (opts.short)< var indent2 = indent+' '+apad; pieces = o.map(function(v)< return build(v,indent2) >); pieces[0] = pieces[0].replace(indent2,indent+'['+apad); pieces[pieces.length-1] = pieces[pieces.length-1]+apad+']'; return pieces.join(',\n'); >else< var indent2 = indent+opts.indent; return indent+'[\n'+o.map(function(v)< return build(v,indent2) >).join(',\n')+'\n'+indent+']'; > case Object: var keyvals=[],i=0; for (var k in o) keyvals[i++] = [JSON.stringify(k), build(o[k],'')]; if (opts.sorted) keyvals = keyvals.sort(function(kv1,kv2)< kv1=kv1[0]; kv2=kv2[0]; return kv1kv2?1:0 >); keyvals = keyvals.map(function(kv)< return kv.join(colon) >).join(comma); var oneLine = indent+""; if (opts.wrap===false || oneLine.length); keyvals[0][0] = keyvals[0][0].replace(indent+' ',indent+'<'); if (opts.aligned)< var longest = 0; for (var i=keyvals.length;i--;) if (keyvals[i][0].length>longest) longest = keyvals[i][0].length; var padding = repeat(' ',longest); for (var i=keyvals.length;i--;) keyvals[i][0] = padRight(padding,keyvals[i][0]); > for (var i=keyvals.length;i--;) < var k=keyvals[i][0], v=keyvals[i][1]; var indent2 = repeat(' ',(k+colon).length); var oneLine = k+colon+build(v,''); keyvals[i] = (opts.wrap===false || oneLine.lengthreturn keyvals.join(',\n') + opad + '>'; >else< var keyvals=[],i=0; for (var k in o) keyvals[i++] = [indent+opts.indent+JSON.stringify(k),o[k]]; if (opts.sorted) keyvals = keyvals.sort(function(kv1,kv2)< kv1=kv1[0]; kv2=kv2[0]; return kv1kv2?1:0 >); if (opts.aligned)< var longest = 0; for (var i=keyvals.length;i--;) if (keyvals[i][0].length>longest) longest = keyvals[i][0].length; var padding = repeat(' ',longest); for (var i=keyvals.length;i--;) keyvals[i][0] = padRight(padding,keyvals[i][0]); > var indent2 = indent+opts.indent; for (var i=keyvals.length;i--;) < var k=keyvals[i][0], v=keyvals[i][1]; var oneLine = k+colon+build(v,''); keyvals[i] = (opts.wrap===false || oneLine.lengthreturn indent+'' > default: return indent+JSON.stringify(o); > > > function repeat(str,times)< // http://stackoverflow.com/a/17800645/405017 var result = ''; while(true)< if (times & 1) result += str; times >>= 1; if (times) str += str; else break; > return result; > function padRight(pad, str) < return (str + pad).substring(0, pad.length); >> neatJSON.version = "0.5"; >)(typeof exports === 'undefined' ? this : exports);
JSON pretty print with highlighting
I would like to pretty print JSON on a web page and highlight some text / lines in it. Ideally I am searching for a IFRAME — service to which I can link and URL where the JSON get’s donwloaded and displayed as HTML, but I would like to specify an search string, which should be highlighted or the whole line containing the search string should be highlighted. The JSON is public so there is no privacy issue. If there is no such service, is there a Javscript library which supports highlighting?
1 Answer 1
Focusing in more on your question about iframes — it’s an issue in itself. It’s not possible to do what you want in an iframe if the domain names aren’t the same. However there are some workarounds for the same-origin policy that could help you in this situation.
Ideally the service you’re pulling from supports jsonp so you don’t have to deal with iframes and can do what you like with the json response without worrying about the same-origin policy.
As mentioned in a previous answer of mine you can use Prettify to apply syntax highlighting, though you can’t highlight a specific line (from what I’ve found so far). For this example I’ll be using the GitHub API.
For the HTML, you would have:
And the JavaScript to fetch and pretty print the JSON response (switch out jquery if you’d like):
$.getJSON('https://api.github.com/users/trevorsenior?callback=?', function(data) < var jsonString = JSON.stringify(data, null, 4); $('#jsonCode').text(jsonString); prettyPrint(); //apply syntax highlighting to to JSON >);
If you do decide to use Prettify take a look at their getting started guide.
Update
To fully answer your question, it is easy enough to add in highlighting to some text by wrapping the text in tags with a specified class. I’ve thrown together another example of this that builds off of the previous one: http://plnkr.co/edit/FM6Ua4pOvMW7nFFggdBy?p=preview
$('#search').keyup(function() < var search = $('#search').val(); if(jsonString.match(search)) < var regex = new RegExp(search, 'g'); var highlighted = '' + search + ''; var newJsonString = jsonString.replace(regex, highlighted); $('#jsonCode').html(prettyPrintOne(newJsonString)); > else < $('#jsonCode').html(prettyPrintOne(jsonString)); >>);
If you want to remove the dynamic functionality & highlight on load simply move the logic out from the event listener:
var highlight = function(jsonString, searchFor) < var regex = new RegExp(searchFor, 'g'); var highlighted = '' + searchFor + ''; var newJsonString = jsonString.replace(regex, highlighted); return prettyPrintOne(newJsonString); >;
And call it just before you populate the area with the code
$('#jsonCode').html(highlight(jsonString, 'X-RateLimit'));