Here I am going to give a walkthrough to include library of react components in Suitelet.
Schematic representation

suitelet_react.js
/**
* @NApiVersion 2.1
* @NModuleScope Public
* @NScriptType Suitelet
* @NAmdConfig ./config.json
*/
define(["N/file", "N/ui/serverWidget", "react_library"], /**
* @param{file} file
* @param{serverWidget} serverWidget
*/
(file, serverWidget, react_library) => {
/**
* Defines the Suitelet script trigger point.
* @param {Object} scriptContext
* @param {ServerRequest} scriptContext.request - Incoming request
* @param {ServerResponse} scriptContext.response - Suitelet response
* @since 2015.2
*/
const onRequest = (scriptContext) => {
try {
if (scriptContext.request.method === "GET") {
let form = serverWidget.createForm({
title: "React Suitelet DEMO",
});
let field = form.addField({
id: "custom_inline",
type: serverWidget.FieldType.INLINEHTML,
label: "Inline",
});
field.defaultValue =
react_library.getReactCDNLinks() +
'<div id="dynHTML"/>' +
react_library.getComponents("DemoComponent", "dynHTML", file);
scriptContext.response.writePage(form);
}
} catch (error) {
log.error("Error @onRequest", error);
}
};
return { onRequest };
});
config.json
{
"paths": {
"react_library": "SuiteScripts/react_lib"
},
"shim": {
"react_library": {
"exports": "react_lib"
}
}
}
react_lib.js
/**
* @NApiVersion 2.1
* @NModuleScope public
*/
var react_lib = {
getReactCDNLinks: function () {
return [
'',
'<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>',
'<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>',
'<script crossorigin src="https://unpkg.com/@babel/standalone/babel.min.js"></script>',
'<script crossorigin src="https://unpkg.com/react@18/umd/react.production.min.js"></script>',
'<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>',
'',
].join('\n');
},
getComponents: function (componentName, tagName, file) {
switch (componentName) {
case "DemoComponent":
return [
'',
'<script type="text/babel">',
this.DemoComponent(file),
'ReactDOM.render(',
'<DemoComponent/>,',
'document.getElementById("{tagName}")'.replace("{tagName}", tagName),
');',
'</script>',
'',
].join("\n");
}
},
DemoComponent: function (file) {
var fileObj = file.load({
id: 499,//internal id of demo_component.js
});
return fileObj.getContents();
},
};
demo_component.js
function DemoComponent(props) {
const [partname, setPartname] = React.useState();
const [vendor, setVendor] = React.useState();
const handleSubmit = event => {
alert(partname + ' - ' + vendor);
event.preventDefault();
};
return (
<form onSubmit={handleSubmit}>
First Name:<br />
<input type="text"
value={partname}
onChange={(e) => setPartname(e.target.value)}
/><br />
<br />
Last Name:<br />
<input type="text"
value={vendor}
onChange={(e) => setVendor(e.target.value)}
/><br />
<br />
<button>Submit</button>
</form>
);
}
Final Page
