JSFiddle - React, Tailwind, and code Playground

HTML

<table border id="results"></table>

CSS

th { font-weight:bold }
th, td { padding: 2px }

JavaScript

console.clear();
var data = {
	'books': [
		{
		  "sku": "{1234}",
		  "title": "Moby Dick",
		  "type": "paperback",
		  "category1": "fiction",
		  "category2": "classic",
		  "category3": "",
		  "image": "",
		  "ctaLabel": "Learn More"
		},
		{
		  "sku": "{5678}",
		  "title": "Another Title",
		  "type": "paperback",
		  "category1": "nonfiction",
		  "category2": "youngadult",
		  "category3": "",
		  "image": "",
		  "ctaLabel": "Learn More"
		},
		{
		  "sku": "{2345}",
		  "title": "Another Title",
		  "type": "paperback",
		  "category1": "nonfiction",
		  "category2": "religion",
		  "category3": "",
		  "image": "",
		  "ctaLabel": "Learn More"
		},
		{
		  "sku": "{7890}",
		  "title": "1984",
		  "type": "hardcover",
		  "category1": "fiction",
		  "category2": "adventure",
		  "category3": "",
		  "image": "",
		  "ctaLabel": "Learn More"
		}
	]
}.books;

function multiLevelSort(arr, criteria) {
	return arr.sort(function(x, y) {
		return criteria.reduce(function(prev, curr) {
			var dir = (curr.dir < 0) ? -1 : 1,
				x_ = x[curr.prop],
				y_ = y[curr.prop];
			return prev || (x_ == y_ ? 0 : x_ > y_ ? dir : -dir);
		}, 0);
	});
}

var criteria = [ 
	{prop: "type", dir: 1}, 
	{prop: "category1", dir: 1}, 
	{prop: "category2", dir: 1} 
];
multiLevelSort(data, criteria);

for (var i=0; i<data.length; i++) {
	$("<tr/>").append(
		'<th>'+criteria[0].prop + "</th><td>" + data[i][criteria[0].prop] + '</td>' + 
		'<th>'+criteria[1].prop + "</th><td>" + data[i][criteria[1].prop] + '</td>' + 
		'<th>'+criteria[2].prop + "</th><td>" + data[i][criteria[2].prop] + '</td>'
	).appendTo("#results");
}