How to Use React in Suitelet

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

Leave a comment

Your email address will not be published. Required fields are marked *