There are some loading issues in the PLP pages as we need to fetch the complete items to display it on the website. To avoid the loading, we can use the json of the items with required details. Make sure the Json should automatically update when we remove, edit or add new items.
We can use a user event script to create the json file of complete items. Before that folder need to be added in the file cabinet to which the json file is created. When we add, delete or update the item record in NetSuite, the json file become updated.

Defines the function definition that is executed after record is submitted. and the script need to be deployed based on the available item types in the account.

User event script
/**
* @NApiVersion 2.1
* @NScriptType UserEventScript
* @NModuleScope SameAccount
* Author: Jobin & Jismi IT Services LLP
* Date: 26/02/2024
* Version: 1.0
*/
define(['N/record', 'N/runtime', 'N/search', 'N/file'],
/**
* @param{record} record
* @param{runtime} runtime
* @param{search} search
* @param{search} file
*/
(record, runtime, search, file) => {
/**
* Defines the function definition that is executed after record is submitted.
* @param {Object} scriptContext
* @param {Record} scriptContext.newRecord - New record
* @param {Record} scriptContext.oldRecord - Old record
* @param {string} scriptContext.type - Trigger type; use values from the context.UserEventType enum
* @since 2015.2
*/
const findWhere = (collection, properties) => {
return collection.find(item =>
Object.keys(properties).every(key =>
item[key] === properties[key]
)
)
}
const afterSubmit = (scriptContext) => {
try {
try {
var itemSearchObj = search.create({
type: "item",
filters:
[
["isavailable", "is", "T"],
"AND",
["isonline", "is", "T"],
"AND",
["isinactive", "is", "F"]
],
columns:
[
search.createColumn({
name: "itemid",
label: "Name"
}),
search.createColumn({
name: "displayname",
label: "Display Name"
}),
search.createColumn({
name: "internalid",
sort: search.Sort.ASC,
label: "Internal ID"
}),
search.createColumn({
name: "type",
label: "Type"
}),
search.createColumn({
name: "custitem_category_custom",
label: "Custom Category"
}),
search.createColumn({
name: "upccode",
label: "UPC Code"
}),
search.createColumn({
name: "weight",
label: "Weight"
}),
search.createColumn({
name: "custitem_chr_units_per_pallet",
label: "Units Per Pallet"
}),
search.createColumn({
name: "custitem_rfs_packing_length",
label: "Length"
}),
search.createColumn({
name: "custitem_rfs_packing_width",
label: "Width"
}),
search.createColumn({
name: "custitem_rfs_packing_height",
label: "Height"
}),
search.createColumn({
name: "custitem_jj_haschildren",
label: "Matrix Item"
}),
search.createColumn({
name: "custitem_webstore_parent_item",
label: "Parent Item"
}),
search.createColumn({
name: "internalid",
join: "CUSTITEM_WEBSTORE_PARENT_ITEM",
label: "Internal ID"
}),
search.createColumn({
name: "baseprice",
label: "Base Price"
}),
search.createColumn({
name: "custitem_retailitem",
label: "Retail Item"
}),
search.createColumn({
name: "custitem_item_mirror",
label: "Sku"
}),
search.createColumn({
name: "custitem_ecommerceproductstatus",
label: "Status"
}),
search.createColumn({
name: "baseprice",
label: "Base Price"
}),
search.createColumn({
name: "formulatext",
formula: "{itemid}",
label: "Formula (Text)"
}),
search.createColumn({
name: "internalid",
join: "pricing",
label: "Internal ID"
}),
search.createColumn({
name: "pricelevel",
join: "pricing",
label: "Price Level"
}),
search.createColumn({
name: "unitprice",
join: "pricing",
label: "Unit Price"
}),
search.createColumn({
name: "storedisplaythumbnail",
label: "Store Display Thumbnail"
}),
search.createColumn({
name: "thumbnailurl",
label: "Thumbnail URL"
}),
search.createColumn({
name: "custitem_modal_data",
label: "Modal Description"
}),
search.createColumn({
name: "quantityavailable",
label: "Available"
}),
search.createColumn({
name: "custitem_jj_item_availability_",
label: "Item Availability Date"
}),
search.createColumn({
name: "custitemcustitem_rize_qty_available2",
label: "Kit Item Availability"
}),
]
});
var items = [];
itemSearchObj.run().each(function (result) {
var itemModalData = result.getValue({
name: "custitem_modal_data",
label: "Modal Description"
});
var priceInternalID = result.getValue({
name: "internalid",
join: "pricing",
label: "Internal ID"
});
var itemType = result.getText({
name: "type",
label: "Type"
});
var storeThumbnail = result.getText({
name: "storedisplaythumbnail",
label: "Store Display Thumbnail"
});
var thumbUrl = result.getValue({
name: "thumbnailurl",
label: "Thumbnail URL"
});
var unitPrice = result.getValue({
name: "unitprice",
join: "pricing",
label: "Unit Price"
});
var itemId = result.getValue({
name: "displayname",
label: "Display Name"
});
var id = result.getValue({
name: "internalid",
sort: search.Sort.ASC,
label: "Internal ID"
});
var pricelevelArray = [];
var priceLevelObj = {
priceLevelId: priceInternalID,
priceValue: unitPrice
};
pricelevelArray.push(priceLevelObj);
var sku = result.getValue({
name: "formulatext",
formula: "{itemid}",
label: "Formula (Text)"
});
var displayName = result.getValue({
name: "displayname",
label: "Display Name"
});
var matrixitem = result.getValue({
name: "custitem_jj_haschildren",
label: "Matrix Item"
});
var parent = result.getValue({
name: "custitem_webstore_parent_item",
label: "Parent Item"
});
var parentId = result.getValue({
name: "internalid",
join: "CUSTITEM_WEBSTORE_PARENT_ITEM",
label: "Internal ID"
});
var category = result.getText({
name: "custitem_category_custom",
label: "Custom Category"
});
var categoryId = result.getValue({
name: "custitem_category_custom",
label: "Custom Category"
});
var pallet = result.getValue({
name: "custitem_chr_units_per_pallet",
label: "Units Per Pallet"
});
var upccode = result.getValue({
name: "upccode",
label: "UPC Code"
});
var length = result.getValue({
name: "custitem_rfs_packing_length",
label: "Length"
});
var width = result.getValue({
name: "custitem_rfs_packing_width",
label: "Width"
});
var height = result.getValue({
name: "custitem_rfs_packing_height",
label: "Height"
});
var weight = result.getValue({
name: "weight",
label: "Weight"
});
var retailitem = result.getValue({
name: "custitem_retailitem",
label: "Retail Item"
});
var item_mirror = result.getValue({
name: "custitem_item_mirror",
label: "Sku"
});
var status = result.getValue({
name: "custitem_ecommerceproductstatus",
label: "Status"
});
var baseprice = result.getValue({
name: "baseprice",
label: "Base Price"
});
var quantityAvailable;
var KitQtyAvailable = result.getValue({
name: "custitemcustitem_rize_qty_available2",
label: "Kit Item Availability"
});
var qtyAvailable = result.getValue({
name: "quantityavailable",
label: "Available"
});
if (itemType === "Kit/Package") {
quantityAvailable = KitQtyAvailable;
} else {
quantityAvailable = qtyAvailable;
}
var estimateDate = result.getValue({
name: "custitem_jj_item_availability_",
label: "Item Availability Date"
});
var thumbnail = !!storeThumbnail?storeThumbnail:"../Item Images/"+ sku +"_01.jpg";
var imageUrl = thumbUrl;
var data = findWhere(items, { "id": id })
var itemObj = {
id: id,
itemid: itemId,
sku: sku,
displayName: displayName,
matrixitem: matrixitem,
parent: parent,
parentId: parentId,
category: category,
categoryId: categoryId,
pallet: pallet,
upccode: upccode,
length: length,
width: width,
height: height,
weight: weight,
baseprice: baseprice,
thumbnail: thumbnail,
imageUrl: imageUrl,
quantityAvailable: quantityAvailable,
retailitem: retailitem,
item_mirror: item_mirror,
status: status,
priceLevelObj: pricelevelArray,
itemmodaldata: itemModalData,
estimateDate: estimateDate
}
if (data) {
var index = items.findIndex(item => item.id === id);
if (index !== -1) {
var exitingPrice = items[index].priceLevelObj;
var similarObjectExists = exitingPrice.some(item => item.priceLevelId === priceLevelObj.priceLevelId);
if (!similarObjectExists) {
exitingPrice.push(priceLevelObj);
items[index].priceLevelObj = exitingPrice;
}
}
} else {
items.push(itemObj);
}
return true;
});
var contentString = JSON.stringify(items);
let fileObj = file.create({
name: 'WebsiteItems',
fileType: file.Type.JSON,
contents: contentString,
folder: 6310000,// folder id
isOnline: true
});
fileObj.save();
} catch (error) {
log.debug("file loadingitem error", error);
}
} catch (error) {
log.debug("Error in categoryitem update", error);
}
}
return {
afterSubmit
}
});
The item json object will be as shown below.
{
"id": "431",
"itemid": "TOP DECK DB04",
"sku": "1200000",
"displayName": "TOP DECK DB04",
"matrixitem": false,
"parent": "",
"parentId": "",
"category": "TRUNDLE BEDS",
"categoryId": "14",
"pallet": "46",
"upccode": "710262009221",
"length": "40",
"width": "39",
"height": "4",
"weight": "44",
"baseprice": "99.99",
"thumbnail": "../Item Images/1200000_01.jpg",
"imageUrl": "",
"quantityAvailable": "184",
"retailitem": true,
"item_mirror": "1200000",
"status": "4",
"priceLevelObj": [
{
"priceLevelId": "1",
"priceValue": "99.99"
},
{
"priceLevelId": "3",
"priceValue": "94.99"
},
{
"priceLevelId": "2",
"priceValue": "91.99"
}
],
"itemmodaldata": "<link href="https://use.typekit.net/gpl6vsa.css" rel="stylesheet" bytes="2" /><style> rn .product-highlights, .highlight-text, .description-text {rn font-family: arial, sans-serif; rn color: black; rn}rnrn.product-highlights {rn -webkit-font-smoothing: antialiased;rn -webkit-tap-highlight-color: rgba(0, 0, 0, 0);rn -webkit-text-stroke-width: 0px;rn background-color: rgb(255, 255, 255);rn box-sizing: border-box;rn rn margin: 0px;rn padding: 0px;rn text-align: left;rn}rnrn.description-text {rn rn}rnrnul {rn padding-left: 50px; /* Add padding to align with the paragraph */rn list-style-position: outside; /* Adjust bullet position */rn margin: 0; /* Remove default margin */rn}rnrnli {rn margin-left: 0px; /* Remove additional margin from list items */rn}rnrnp.product-highlights {rn padding-left: 20px; /* Add padding to align with the list */rn margin: 0px; /* Adjust margin for consistency */rn}rn</style><p class="product-highlights"><span><i><span class="description-text">Rize trundle beds are made from strength-tested, tubular steel to hold up to a lifetime of use. Use as a single bunk with the included arms/legs, or as a day bed insert. This Twin-size stationary bed uses a welded wire deck for extra durability. There are no squeaking or pinching springs to worry about. Each bed holds up to 400 lb.rnrnNo need for a box spring - just use a Twin size mattress. Caps on the bottom of the legs prevent scratching.</span></i></span></p><p><br /> </p><hr /><br /><ul><li class="product-highlights"><span style="color:rgb(0, 0, 0);"><span class="highlight-text">Deck length is 75" (total length is 78.5" including the arms)</span></span></li><li class="product-highlights"><span style="color:rgb(0, 0, 0);"><span class="highlight-text">14" of storage space underneath</span></span></li><li class="product-highlights"><span style="color:rgb(0, 0, 0);"><span class="highlight-text">Space between the brackets on the underside of the bed is 74"</span></span></li><li class="product-highlights"><span style="color:rgb(0, 0, 0);"><span class="highlight-text">Height from top of deck to the floor is 16.25" (total height is 22.5")</span></li></ul>",
"estimateDate": ""
},