SuiteCommerce Site Development September 9, 2020 2020.2 Copyright © 2005, 2020, Oracle and/or its affiliates. All rights reserved. This software and related documentation are provided under a license agreement containing restrictions on use and disclosure and are protected by intellectual property laws. Except as expressly permitted in your license agreement or allowed by law, you may not use, copy, reproduce, translate, broadcast, modify, license, transmit, distribute, exhibit, perform, publish, or display any part, in any form, or by any means. Reverse engineering, disassembly, or decompilation of this software, unless required by law for interoperability, is prohibited. The information contained herein is subject to change without notice and is not warranted to be errorfree. If you find any errors, please report them to us in writing. If this is software or related documentation that is delivered to the U.S. Government or anyone licensing it on behalf of the U.S. Government, then the following notice is applicable: U.S. GOVERNMENT END USERS: Oracle programs, including any operating system, integrated software, any programs installed on the hardware, and/or documentation, delivered to U.S. Government end users are "commercial computer software" pursuant to the applicable Federal Acquisition Regulation and agency-specific supplemental regulations. As such, use, duplication, disclosure, modification, and adaptation of the programs, including any operating system, integrated software, any programs installed on the hardware, and/or documentation, shall be subject to license terms and license restrictions applicable to the programs. No other rights are granted to the U.S. Government. This software or hardware is developed for general use in a variety of information management applications. It is not developed or intended for use in any inherently dangerous applications, including applications that may create a risk of personal injury. If you use this software or hardware in dangerous applications, then you shall be responsible to take all appropriate fail-safe, backup, redundancy, and other measures to ensure its safe use. Oracle Corporation and its affiliates disclaim any liability for any damages caused by use of this software or hardware in dangerous applications. Oracle and Java are registered trademarks of Oracle and/or its affiliates. Other names may be trademarks of their respective owners. Intel and Intel Xeon are trademarks or registered trademarks of Intel Corporation. All SPARC trademarks are used under license and are trademarks or registered trademarks of SPARC International, Inc. AMD, Opteron, the AMD logo, and the AMD Opteron logo are trademarks or registered trademarks of Advanced Micro Devices. UNIX is a registered trademark of The Open Group. This software or hardware and documentation may provide access to or information about content, products, and services from third parties. Oracle Corporation and its affiliates are not responsible for and expressly disclaim all warranties of any kind with respect to third-party content, products, and services unless otherwise set forth in an applicable agreement between you and Oracle. Oracle Corporation and its affiliates will not be responsible for any loss, costs, or damages incurred due to your access to or use of third-party content, products, or services, except as set forth in an applicable agreement between you and Oracle. If this document is in public or private pre-General Availability status: This documentation is in pre-General Availability status and is intended for demonstration and preliminary use only. It may not be specific to the hardware on which you are using the software. Oracle Corporation and its affiliates are not responsible for and expressly disclaim all warranties of any kind with respect to this documentation and will not be responsible for any loss, costs, or damages incurred due to the use of this documentation. If this document is in private pre-General Availability status: The information contained in this document is for informational sharing purposes only and should be considered in your capacity as a customer advisory board member or pursuant to your pre-General Availability trial agreement only. It is not a commitment to deliver any material, code, or functionality, and should not be relied upon in making purchasing decisions. The development, release, and timing of any features or functionality described in this document remains at the sole discretion of Oracle. This document in any form, software or printed matter, contains proprietary information that is the exclusive property of Oracle. Your access to and use of this confidential material is subject to the terms and conditions of your Oracle Master Agreement, Oracle License and Services Agreement, Oracle PartnerNetwork Agreement, Oracle distribution agreement, or other license agreement which has been executed by you and Oracle and with which you agree to comply. This document and information contained herein may not be disclosed, copied, reproduced, or distributed to anyone outside Oracle without prior written consent of Oracle. This document is not part of your license agreement nor can it be incorporated into any contractual agreement with Oracle or its subsidiaries or affiliates. For information about Oracle's commitment to accessibility, visit the Oracle Accessibility Program website at http://www.oracle.com/pls/topic/lookup?ctx=acc&id=docacc Oracle customers that have purchased support have access to electronic support through My Oracle Support. For information, visit http://www.oracle.com/pls/topic/lookup?ctx=acc&id=info or visit http:// www.oracle.com/pls/topic/lookup?ctx=acc&id=trs if you are hearing impaired. Sample Code Oracle may provide sample code in SuiteAnswers, the Help Center, User Guides, or elsewhere through help links. All such sample code is provided "as is” and “as available”, for use only with an authorized NetSuite Service account, and is made available as a SuiteCloud Technology subject to the SuiteCloud Terms of Service at www.netsuite.com/tos. Oracle may modify or remove sample code at any time without notice. No Excessive Use of the Service As the Service is a multi-tenant service offering on shared databases, Customer may not use the Service in excess of limits or thresholds that Oracle considers commercially reasonable for the Service. If Oracle reasonably concludes that a Customer’s use is excessive and/or will cause immediate or ongoing performance issues for one or more of Oracle’s other customers, Oracle may slow down or throttle Customer’s excess use until such time that Customer’s use stays within reasonable limits. If Customer’s particular usage pattern requires a higher limit or threshold, then the Customer should procure a subscription to the Service that accommodates a higher limit and/or threshold that more effectively aligns with the Customer’s actual usage pattern. Beta Features This software and related documentation are provided under a license agreement containing restrictions on use and disclosure and are protected by intellectual property laws. Except as expressly permitted in your license agreement or allowed by law, you may not use, copy, reproduce, translate, broadcast, modify, license, transmit, distribute, exhibit, perform, publish, or display any part, in any form, or by any means. Reverse engineering, disassembly, or decompilation of this software, unless required by law for interoperability, is prohibited. The information contained herein is subject to change without notice and is not warranted to be errorfree. If you find any errors, please report them to us in writing. If this is software or related documentation that is delivered to the U.S. Government or anyone licensing it on behalf of the U.S. Government, then the following notice is applicable: U.S. GOVERNMENT END USERS: Oracle programs (including any operating system, integrated software, any programs embedded, installed or activated on delivered hardware, and modifications of such programs) and Oracle computer documentation or other Oracle data delivered to or accessed by U.S. Government end users are "commercial computer software" or “commercial computer software documentation” pursuant to the applicable Federal Acquisition Regulation and agency-specific supplemental regulations. As such, the use, reproduction, duplication, release, display, disclosure, modification, preparation of derivative works, and/or adaptation of i) Oracle programs (including any operating system, integrated software, any programs embedded, installed or activated on delivered hardware, and modifications of such programs), ii) Oracle computer documentation and/or iii) other Oracle data, is subject to the rights and limitations specified in the license contained in the applicable contract. The terms governing the U.S. Government’s use of Oracle cloud services are defined by the applicable contract for such services. No other rights are granted to the U.S. Government. This software or hardware is developed for general use in a variety of information management applications. It is not developed or intended for use in any inherently dangerous applications, including applications that may create a risk of personal injury. If you use this software or hardware in dangerous applications, then you shall be responsible to take all appropriate fail-safe, backup, redundancy, and other measures to ensure its safe use. Oracle Corporation and its affiliates disclaim any liability for any damages caused by use of this software or hardware in dangerous applications. Oracle and Java are registered trademarks of Oracle and/or its affiliates. Other names may be trademarks of their respective owners. Intel and Intel Inside are trademarks or registered trademarks of Intel Corporation. All SPARC trademarks are used under license and are trademarks or registered trademarks of SPARC International, Inc. AMD, Epyc, and the AMD logo are trademarks or registered trademarks of Advanced Micro Devices. UNIX is a registered trademark of The Open Group. This software or hardware and documentation may provide access to or information about content, products, and services from third parties. Oracle Corporation and its affiliates are not responsible for and expressly disclaim all warranties of any kind with respect to third-party content, products, and services unless otherwise set forth in an applicable agreement between you and Oracle. Oracle Corporation and its affiliates will not be responsible for any loss, costs, or damages incurred due to your access to or use of third-party content, products, or services, except as set forth in an applicable agreement between you and Oracle. This documentation is in pre-General Availability status and is intended for demonstration and preliminary use only. It may not be specific to the hardware on which you are using the software. Oracle Corporation and its affiliates are not responsible for and expressly disclaim all warranties of any kind with respect to this documentation and will not be responsible for any loss, costs, or damages incurred due to the use of this documentation. The information contained in this document is for informational sharing purposes only and should be considered in your capacity as a customer advisory board member or pursuant to your pre-General Availability trial agreement only. It is not a commitment to deliver any material, code, or functionality, and should not be relied upon in making purchasing decisions. The development, release, and timing of any features or functionality described in this document remains at the sole discretion of Oracle. This document in any form, software or printed matter, contains proprietary information that is the exclusive property of Oracle. Your access to and use of this confidential material is subject to the terms and conditions of your Oracle Master Agreement, Oracle License and Services Agreement, Oracle PartnerNetwork Agreement, Oracle distribution agreement, or other license agreement which has been executed by you and Oracle and with which you agree to comply. This document and information contained herein may not be disclosed, copied, reproduced, or distributed to anyone outside Oracle without prior written consent of Oracle. This document is not part of your license agreement nor can it be incorporated into any contractual agreement with Oracle or its subsidiaries or affiliates. Send Us Your Feedback We'd like to hear your feedback on this document. Answering the following questions will help us improve our help content: ■ Did you find the information you needed? If not, what was missing? ■ Did you find any errors? ■ Is the information clear? ■ Are the examples correct? ■ Do you need more examples? ■ What did you like most about this document? Click here to send us your comments. If possible, please provide a page number or section title to identify the content you're describing. To report software issues, contact NetSuite Customer Support. Table of Contents Developer Tools .................................................................................................................... Overview .......................................................................................................................... Developer Environment ...................................................................................................... Install Node.js ............................................................................................................... Install Gulp.js ................................................................................................................ Set Up Theme Developer Tools ........................................................................................ Set Up Extension Developer Tools .................................................................................... Theme Developer Tools ...................................................................................................... Fetch Active Theme Files ................................................................................................. Test a Theme on a Local Server ....................................................................................... Deploy a Theme to NetSuite ........................................................................................... Extension Developer Tools .................................................................................................. Create Extension Files .................................................................................................... Create a Baseline Extension ........................................................................................ Create Additional Modules for an Extension ................................................................... Create Custom Content Types for an Extension .............................................................. Fetch Active Theme and Extension Files ............................................................................ Test an Extension on a Local Server ................................................................................. Deploy an Extension to NetSuite ...................................................................................... Developer Tools Reference ................................................................................................. Developer Tools Roles and Permissions ............................................................................ Confirm That You Have the SCDeployer Role .................................................................. Prepare the SCDeployer Role ...................................................................................... Set Up the SCDeployer Role Manually ........................................................................... Gulp Command Reference for Themes and Extensions ........................................................ Theme Development Files and Folders .............................................................................. Extension Development Files and Folders .......................................................................... Mixed Domains in a Local Server ..................................................................................... Secure HTTP (HTTPS) with the Local Server ........................................................................ Deploy to a NetSuite Sandbox ......................................................................................... Deploy to a Custom SSP Application ................................................................................. Troubleshooting the Developer Tools ............................................................................... Site Configuration .................................................................................................................. Overview .......................................................................................................................... Configure Properties .......................................................................................................... Configuration Properties Reference ...................................................................................... Advanced Tab ............................................................................................................... Backend Subtab ........................................................................................................ Cache Subtab ........................................................................................................... Custom Fields Subtab ................................................................................................ Favicon Path Subtab .................................................................................................. Filter Site Subtab ....................................................................................................... Image Resize Subtab ................................................................................................. Pagination Subtab ..................................................................................................... Search Results Subtab ................................................................................................ Security Subtab ......................................................................................................... Checkout Tab ................................................................................................................ Credit Card Subtab .................................................................................................... Forms Subtab ........................................................................................................... Payment Methods Subtab ........................................................................................... Integrations Tab ............................................................................................................ AddThis Subtab ......................................................................................................... Bronto Subtab .......................................................................................................... 11 11 12 13 14 14 15 17 18 20 22 26 26 27 30 31 32 34 35 38 38 38 38 39 41 45 47 50 51 54 55 60 64 64 65 68 68 69 71 72 72 72 73 74 76 77 77 81 82 83 84 84 86 Categories Subtab ..................................................................................................... 86 Facebook Subtab ....................................................................................................... 90 Google AdWords Subtab ............................................................................................ 93 GooglePlus Subtab .................................................................................................... 95 Google Tag Manager Subtab ....................................................................................... 98 Google Universal Analytics Subtab ............................................................................... 99 Pinterest Subtab ...................................................................................................... 100 Site Management Tools Subtab .................................................................................. 104 Twitter Subtab ......................................................................................................... 105 Layout Tab .................................................................................................................. 108 Bottom Banner Images Subtab .................................................................................. 109 Carousel Images Subtab ........................................................................................... 109 Color Palettes Subtab ............................................................................................... 110 Cookies Warning Banner Subtab ................................................................................ 111 Footer Subtab ......................................................................................................... 112 Header Subtab ........................................................................................................ 112 Images Subtab ........................................................................................................ 113 Light Colors Subtab ................................................................................................. 113 Navigation Subtab ................................................................................................... 114 Legacy Tab ................................................................................................................. 114 Newsletter Subtab ................................................................................................... 115 Footer Subtab ......................................................................................................... 116 Multi-Domain Tab ........................................................................................................ 116 Hosts Subtab .......................................................................................................... 117 Translations Subtab .................................................................................................. 118 My Account Tab ........................................................................................................... 119 Addresses Subtab .................................................................................................... 119 Cases Subtab .......................................................................................................... 120 List Header Subtab .................................................................................................. 121 Overview Subtab ...................................................................................................... 121 Quotes Subtab ........................................................................................................ 122 Return Authorization Subtab ...................................................................................... 126 SCIS Integration Subtab ............................................................................................ 127 Subscriptions Subtab ................................................................................................ 128 Transaction List Columns Subtab ................................................................................ 130 Search Tab ................................................................................................................. 133 Result Display Options Subtab ................................................................................... 134 Result Sorting Subtab ............................................................................................... 135 Search Results Subtab .............................................................................................. 136 Search Results per Page Subtab ................................................................................. 137 Type Ahead Subtab .................................................................................................. 137 Shopping Tab .............................................................................................................. 138 Item Options Subtab ................................................................................................ 138 Newsletter Subtab ................................................................................................... 138 Quick Order Subtab ................................................................................................. 139 Reviews Subtab ....................................................................................................... 139 Wishlist Subtab ........................................................................................................ 142 Shopping Catalog Tab .................................................................................................. 144 Facets Subtab ......................................................................................................... 147 Facets Delimiters Subtab ........................................................................................... 149 Facets SEO Subtab ................................................................................................... 151 Item Options Subtab ................................................................................................ 152 Multi-Image Option Subtab ....................................................................................... 155 Product Details Information Subtab ............................................................................ 156 Recently Viewed Items Subtab ................................................................................... 157 Structured Data Markup Subtab ................................................................................. Store Locator Tab ........................................................................................................ Store Locator Subtab ............................................................................................... Store Locator Google Maps Subtab ............................................................................ Configuration File Types .................................................................................................... JSON Configuration Files ............................................................................................... Create JSON Configuration Files ................................................................................. JavaScript Configuration Files ......................................................................................... Site Management Tools Configuration ................................................................................. Upgrade from SMT Version 2 to SMT Version 3 ................................................................ SMT Templates and Areas ............................................................................................. Site Management Tools Areas .................................................................................... Templates and Areas for SCA .................................................................................... SMT Custom Preview Screen Sizes .................................................................................. Working with SMT Landing Pages in a Sandbox Account .................................................... Changing SMT to Use a Different Hosting Root ................................................................ Configuring Escape to Log In ........................................................................................ Internationalization of SMT Administration ....................................................................... CMS Records for SMT ................................................................................................... Custom Record for CMS Content ................................................................................ CMS Contents Record ............................................................................................... CMS Page Record .................................................................................................... CMS Page Type Record ............................................................................................. Custom Content Type ................................................................................................... Custom Record for Custom Content Type .................................................................... CMS Content Type Record ......................................................................................... Customization ..................................................................................................................... Overview ........................................................................................................................ Commerce Migration to SuiteScript 2.0 ............................................................................... Themes .......................................................................................................................... Themes Overview ........................................................................................................ Develop Your Theme .................................................................................................... Customize Pre-Existing Theme Files ............................................................................ Add a New File to a Theme ....................................................................................... Override Active Extension Files ................................................................................... Set Up Your Theme for Customization in SMT .............................................................. Customize Site Search Elements ................................................................................. Best Practices for Creating Themes ................................................................................ SuiteCommerce Base Theme ..................................................................................... General Best Practices for Themes ............................................................................. HTML Best Practices ................................................................................................. Sass Best Practices .................................................................................................. Asset Best Practices ................................................................................................. Design Architecture .................................................................................................. Theme Manifest ........................................................................................................... Extensions ...................................................................................................................... Develop Your Extension ................................................................................................ Create Page Types ....................................................................................................... Add a CMS Page Type Record .................................................................................... Create Layout Thumbnails ......................................................................................... Extension Manifest ....................................................................................................... Troubleshoot Activation Errors ....................................................................................... Commerce Custom Fields ............................................................................................. Create Custom Fields Using an Extension .................................................................... Create Custom Fields by Customizing Templates ........................................................... 158 158 159 162 164 164 166 183 185 185 187 187 191 197 198 199 200 201 201 202 203 205 206 209 210 212 215 215 217 219 219 220 221 222 224 226 234 236 236 237 238 240 242 246 253 257 258 259 261 262 262 268 269 270 274 Theme and Extension SuiteApps ........................................................................................ 282 Bundle Themes and Extensions as SuiteApps ................................................................... 282 Declare Target Versions ................................................................................................ 285 Update Themes and Extensions ..................................................................................... 286 Core SCA Source Code ..................................................................................................... 289 Core SuiteCommerce Advanced Developer Tools .............................................................. 289 Set Up Your Development Environment ....................................................................... 290 SCA on a Local Server .............................................................................................. 295 Deploy to NetSuite ................................................................................................... 297 Gulp Command Reference for SCA Developer Tools ...................................................... 298 The Build Process .................................................................................................... 301 Customize and Extend Core SuiteCommerce Advanced Modules ......................................... 305 Best Practices for Customizing SuiteCommerce Advanced .............................................. 306 Customization Examples ........................................................................................... 310 Architecture ........................................................................................................................ 349 Overview ........................................................................................................................ 349 Core Framework Technologies ........................................................................................... 350 Model View Controller (MVC) and Backbone.js .................................................................. 350 TypeScript ................................................................................................................... 352 Asynchronous Module Definitions (AMD) and RequireJS ..................................................... 352 Logic-less Templates and Handlebars.js ........................................................................... 353 Templates and the Template Context .......................................................................... 354 Commerce Modules ......................................................................................................... 357 The SuiteCommerce Advanced Source Directory ............................................................... 357 Dependencies ............................................................................................................. 360 Application Modules ..................................................................................................... 360 Module Architecture ..................................................................................................... 361 Entry Point .............................................................................................................. 362 Routers .................................................................................................................. 362 Views ..................................................................................................................... 362 Models, Collections, and Services ............................................................................... 366 Product Details Page Architecture ...................................................................................... 384 Patches .............................................................................................................................. 389 Overview ........................................................................................................................ 389 Patches .......................................................................................................................... 390 Patches Overview ......................................................................................................... 390 Patch Using Extend Mode ......................................................................................... 390 Patch Using Override Mode ...................................................................................... 392 Patch Instructions ........................................................................................................ 394 CVE-2020-14728: Vulnerability in SuiteCommerce Advanced Services ................................ 400 CVE-2020-14729: Vulnerability in SuiteCommerce Advanced Sites .................................... 403 Shopping User Environment Experiences Degraded Performance .................................... 406 beforeShowContent Event Stops Working After Initial Trigger .......................................... 408 Filter Site Option Does Not Work As Expected .............................................................. 410 Quantity Facet Displays Dollar Sign ............................................................................. 412 Bronto Cart Recovery Link Redirects to Blank Page ........................................................ 414 Custom Overrides Not Applying When Deployed ........................................................... 418 Theme Developer Tool Overrides May Cause Error On Activation ..................................... 419 Categories Do Not Display Properly ............................................................................ 420 Incorrect Value for Shipping Estimate Occurs in Shopping Cart ....................................... 422 Standard Promotion with Inline Discount and Rate as Percentage Not Updating the Amount in Checkout ................................................................................................................ 425 Page With URL Fragments Redirects Too Many Times .................................................... 428 See Complete List of Stores Link on Store Locator Page Does Not Show Store List ............... 430 Quantity Pricing Displayed in Web Store Even When “Require Login for Pricing” is Enabled .... 432 Edited Shipping Address on the Review Your Order Page is Not Showing Changes .............. 435 Custom Page Title in SMT Does Not Display Correctly .................................................... 437 Currencies Change to the Default in the Shopping Application ........................................ 440 Order Confirmation Page Not Displayed When Using Single Page Checkout and External Payment ................................................................................................................. 442 Incorrect Discounted Amounts on Checkout Summary ................................................... 444 DeployDistribution Folder Does Not Include Local Files .................................................. 447 HTML List Styles Do Not Display ................................................................................. 448 Item Search Displays Incorrect Results ........................................................................ 456 Category Product Lists Return Page Not Found ............................................................ 458 Cannot Test an Extension on a Local Server ................................................................. 462 Secure Shopping for Site Builder Implementations ........................................................ 464 Cannot Scroll Through Long Menu Lists Using iOS ........................................................ 476 Pages Not Indexed Using Google’s Mobile-First Indexing ............................................... 481 Disabling Display of SuiteCommerce Gift Wrap & Message Extension Transaction Line Fields ..................................................................................................................... 483 Users Not Redirected to External Payment System ........................................................ 488 Invoices Do Not Include the Request for a Return Button ............................................... 491 Unable to Select Item Options Within the SuiteCommerce Configuration Record in NetSuite ................................................................................................................. 494 Incorrect Redirect URL for External Payments ............................................................... 496 npm Error on Implementations .................................................................................. 499 Content Appears Incorrectly in a Merchandising Zone ................................................... 500 Reference My Account Generates Error on Load ........................................................... 503 Error Loading Shopping Page Due to Uncaught TypeError ............................................. 504 Users Redirected to Checkout Application Instead of Shopping Application ........................ 507 Add to Cart Button Does Not Work If Quality Field Selected ............................................ 509 URLs with Redundant Facets Generated ...................................................................... 511 Content Flickers or Disappears When Browsing the Product Listing Page .......................... 515 Enabling Google AdWords Causes Error on Login ......................................................... 517 URL for Commerce Categories Contains Incorrect Delimiters .......................................... 519 Order Summary for Item-Based Promotions ................................................................ 523 CSS Error Hides First div Element on Product Details Page .............................................. 525 Invoice Terms Not Included In Order Details ................................................................ 527 Users Required to Re-enter Credit Card Payment Method Details on Payment Page ............ 528 Selected Invoice Not Displayed When Making an Invoice Payment ................................... 532 Log In to See Prices Message Appears When Users are Logged In ................................... 534 Item Record HTML Meta Data Not Appearing on Page Meta Data .................................... 537 Delivery Options Not Appearing After Editing the Cart and Re-entering a Shipping Address ... 539 Order Confirmation and Thank You Page is Blank ......................................................... 542 Matrix Item Options Not Displaying With Google Tag Manager Enabled ............................ 545 Delivery Methods Not Appearing in One Page Checkout ................................................ 548 Mastercard 2-Series BIN Regex Patch ......................................................................... 552 Auto-Apply Promotions for Elbrus ............................................................................... 560 Change Email Address Patch ..................................................................................... 576 Duplicate Product Lists in Internet Explorer 11 ............................................................. 633 Save for Later Item not Moved to Cart ........................................................................ 634 Running Gulp Commands Results in a Syntax Error ....................................................... 637 Missing Promo Code on Return Request ..................................................................... 638 Enhanced Page Content Disappears when Resizing the Browser ...................................... 640 Invoices Page Displays Incorrect Date Sort (pre-Denali) .................................................. 645 PayPal Payments Cause Error at Checkout ................................................................... 646 Canonical Tags Populated With Relative Paths .............................................................. 649 Shopping Cart Not Scrolling (Mobile) .......................................................................... 651 Error When Adding Items to Categories in Site Management Tools .................................. 655 Item Search API Response Data not Cached ................................................................ Secure Shopping Domains (Elbrus, Vinson, Mont Blanc, and Denali) .................................. Secure Shopping Domain (pre-Denali) ......................................................................... PayPal Address not Retained in Customer Record ......................................................... Login Email Address Appears in the Password Reset URL ............................................... How to Apply .patch Files .......................................................................................... Upgrade SuiteCommerce to SuiteCommerce Advanced ......................................................... Update SuiteCommerce Advanced ...................................................................................... Migrate to the Latest Release of SuiteCommerce Advanced ................................................ Migrate from Aconcagua and Later ............................................................................ Migrate From Kilimanjaro and Earlier .......................................................................... 659 661 662 675 676 680 683 685 685 686 688 Overview 11 Overview Applies to: SuiteCommerce | SuiteCommerce Advanced Before customizing a Commerce web store, you must set up the developer tools. These tools let you: ■ Create your own themes and extensions. ■ Compile your themes and extensions locally for testing. ■ Deploy themes and extensions to your NetSuite account. You can also deploy directly to your production or sandbox accounts in NetSuite. ■ Create and edit code locally in your preferred text editor or IDE. ■ Retrieve pre-existing theme source code as a basis for building a custom theme. ■ Build baseline extensions to access the Extensibility API. ■ Expose theme Sass variables for the Site Management Tools Theme Customizer. Follow the instructions in these topics to set up and use the developer tools: ■ Developer Environment – This topic explains how to create your developer environment. The term developer environment refers to both the tools used to develop your code and the physical location where you store it all. ■ Theme Developer Tools – These topics explain how to use the theme developer tools to start building your own themes, test them locally, and deploy them to a NetSuite account. ■ Extension Developer Tools – These topics explain how to use the extension developer tools to start building your own extensions, test them locally, and deploy them to a NetSuite account. ■ Developer Tools Reference – These topics provide a handy reference of each Gulp.js command, what your theme and extension workspaces look like, plus important information on testing locally and deploying to NetSuite. SuiteCommerce Site Development Developer Environment Developer Environment Applies to: SuiteCommerce | SuiteCommerce Advanced | SuiteCommerce InStore Install the SuiteCommerce Advanced Developer Tools Commerce web stores provide different tools that let you create, test, and deploy code as either themes or extensions. The developer tools you need depend on your implementation. The lists below explain what tools you need by implementation. After determining the correct tools you need, use the provided checklist to ensure a complete setup. SuiteCommerce (Themes and Extensions Development) ■ Install Node.js ■ Install Gulp.js ■ Set Up Theme Developer Tools ■ Set Up Extension Developer Tools SuiteCommerce InStore (Extensions Development) ■ Install Node.js ■ Install Gulp.js ■ Set Up Extension Developer Tools SuiteCommerce Advanced ■ Install Node.js ■ Install Gulp.js ■ Set Up Theme Developer Tools ■ Set Up Extension Developer Tools ■ Core SuiteCommerce Advanced Developer Tools ■ Set Up SCA 2019.1 for Theme and Extension Developer Tools (required for SCA 2019.1 and 2019.2) Important: If you are implementing the Aconcagua Release of SCA or later, the best practice is to use themes and extensions to customize your site. SuiteCommerce Advanced (Kilimanjaro release and earlier) ■ Install Node.js ■ Install Gulp.js ■ Core SuiteCommerce Advanced Developer Tools Need help? Download the Developer Tools Checklist for a handy quick reference. SuiteCommerce Site Development 12 Install Node.js Install Node.js Applies to: SuiteCommerce | SuiteCommerce Advanced | SuiteCommerce InStore Node.js is the platform required for all Gulp.js tasks required to develop any Commerce web store or extensions for SCIS. Node.js is available at: https://nodejs.org/en/download/ Install the version of Node.js that is supported by your implementation according to the table below. Use the most current minor release (designated by x in the table below) for the version of Node.js you are using. Commerce Web Store Implementation Supported Node.js Versions SuiteCommerce 12.14.x SuiteCommerce Advanced — 2020.1 12.14.x SuiteCommerce Advanced — 2019.2 10.16.x SuiteCommerce Advanced — 2019.1 10.15.x SuiteCommerce Advanced — 2018.2 8.11.4 SuiteCommerce Advanced — Aconcagua 8.9.x LTS SuiteCommerce Advanced — Kilimanjaro 6.11.x SuiteCommerce Advanced — Elbrus 4.x.x LTS and Later SuiteCommerce Advanced — Vinson 4.x.x LTS SuiteCommerce Advanced — Mont Blanc 4.4.x and 0.12.x SuiteCommerce Advanced — Denali 0.12.x When installing Node.js, ensure that you install all Node.js components. This includes the Node Package Manager (NPM), which is used to install Gulp.js and other files required by the developer tools and the build process. After running the installer, you should see Node.js in the list of available programs on your system. The npm command should also be added to the path on your system. Note: Ensure that you use the correct installer for your platform. You may have to restart your machine for the Node.js commands to be recognized in the path variable on your system. To verify that Node.js is installed correctly: 1. Depending on your platform open a command line or terminal window. 2. Enter the following command: node -v If everything is installed correctly, this command outputs the currently installed version of Node.js. There should be no errors or warnings. After successfully installing Node.js, you are ready to Install Gulp.js. SuiteCommerce Site Development 13 Install Gulp.js 14 Install Gulp.js Applies to: SuiteCommerce | SuiteCommerce Advanced | SuiteCommerce InStore After successfully installing Node.js, the next step in setting up your developer environment is to install Gulp.js. Gulp.js is a third-party, open-source tool that automates many of the tasks related to creating web-based applications. This is required for all Commerce web store implementations. To Install Gulp.js: 1. Depending on your platform, open a command line or terminal window. 2. Enter the following command: npm install --global gulp Note: Install Gulp.js using the --global flag as shown above. On Linux and MacOS, you must run this command using sudo. This is required to ensure that Gulp.js is installed correctly. 3. Verify that Gulp.js was installed correctly by entering the following command: gulp -v If installed correctly, this command outputs the currently installed version of Gulp.js. Ensure that this version is 3.9.1 or higher. There should be no errors or warnings. Permissions To use Gulp.js to deploy source files to NetSuite, you must use a System Administrator role with the following permissions set to Full: ■ Documents and Files ■ Website (External) publisher ■ Web Services After successfully installing Gulp.js, you are ready to set up one or more of the following: ■ Set Up Theme Developer Tools ■ Set Up Extension Developer Tools ■ Core SuiteCommerce Advanced Developer Tools Set Up Theme Developer Tools Applies to: SuiteCommerce | SuiteCommerce Advanced Before you can create a theme, you must download the theme developer tools and extract them to create a top-level development workspace. This is where you maintain a theme’s HTML, Sass, and asset files. You use the developer tools to run Gulp.js commands to fetch files from the server, test your changes locally, and deploy themes to NetSuite. SuiteCommerce Site Development Set Up Theme Developer Tools 15 Important: You can only develop one theme per top-level theme workspace. To develop two or more themes simultaneously, you must set up multiple instances of the theme developer tools, one for each theme. Note: These tools are required for all SuiteCommerce sites and any SCA sites implementing the Aconcagua release or later. You cannot customize your SCA site’s Sass or HTML template files without these tools. To download and extract theme developer tools: 1. Login to your NetSuite account. 2. In NetSuite, go to Documents > Files > File Cabinet. 3. Navigate to SuiteBundles/Bundle 317001/. 4. Download the .zip file you find there: ThemeDevelopmentTools-20.1.x.zip (where x equals the latest minor release). 5. Extract the .zip file to a location in your local environment. This becomes your root development directory for custom themes. The .zip file extracts into a directory named ThemeDevelopmentTools-20.1.x by default (where x equals the latest minor release). However, you can rename this directory to suit your needs. Note: SuiteCommerce Advanced 2018.2 Developers: If you are implementing the 2018.2 release of SCA, you must use the 2018.2 developer tools when creating themes and extensions due to non-backward compatibility. The latest release of the SuiteCommerce Extension Management Bundle also includes the theme and extension developer tools for 2018.2. Important: Do not move, delete, or rename any files or folders within the top-level development directory. 6. Open a command line or terminal window. 7. Access your root development directory created previously. 8. Enter the following command to install additional Node.js packages into this directory: npm install Note: This command installs the dependencies required to manage your custom themes. These files are stored in the node_modules subdirectory of the root development directory. This command may take several minutes to complete. You are now ready to begin theme development. See Theme Developer Tools for information on fetching an active theme, testing on a local server, and deploying to a NetSuite account. For information on developing a theme, see Themes. If you also intend to build extensions, you must Set Up Extension Developer Tools. Set Up Extension Developer Tools Applies to: SuiteCommerce | SuiteCommerce Advanced | SuiteCommerce InStore Before you can create an extension, you must download the extension developer tools and extract them to create a top-level development directory. This is where you maintain all of your extension’s JavaScript, SuiteCommerce Site Development Set Up Extension Developer Tools 16 SuiteScript, Configuration, HTML, Sass, and assets. You use the tools to run Gulp.js commands to build baseline files for your extension, test your changes locally, and deploy extensions to NetSuite. Note: These tools are required for all SuiteCommerce sites and any SCA sites implementing the Aconcagua release or later. You build extensions to interact with the Extensibility API to extend the application. See the help topic Extensibility Component Classes for an explanation of what components are currently accessible using the Extensibility API. To download and extract the extension developer tools: 1. Login to your NetSuite account. 2. In NetSuite, go to Documents > Files > File Cabinet. 3. Navigate to SuiteBundles/Bundle 317001/. 4. Download the .zip file you find there: ExtensionDevelopmentTools-20.1.x.zip (where x equals the latest minor release). 5. Extract the .zip file to a location in your local environment. This becomes your root development directory for your custom extensions. The .zip file extracts into a directory named ExtensionDevelopmentTools-20.1.x by default (where x equals the latest minor release). However, you can rename this directory to suit your needs. Note: SuiteCommerce Advanced 2018.2 Developers: If you are implementing the 2018.2 release of SCA, you must use the 2018.2 developer tools when creating themes and extensions due to non-backward compatibility. The latest release of the SuiteCommerce Extension Management Bundle also includes the theme and extension developer tools for 2018.2. Important: Do not move, delete, or rename any files or folders within the top-level development directory. 6. Open a command line or terminal window. 7. Access your root development directory created previously. 8. Enter the following command to install additional Node.js packages into this directory: npm install Note: This command installs the dependencies required to manage your custom extensions. These files are stored in the node_modules subdirectory of the root development directory. This command may take several minutes to complete. You are now ready to begin extension development. See Extension Developer Tools for information on building a baseline extension, testing on a local server, and deploying to a NetSuite account. For information on developing an extension, see Extensions. If you also intend to create themes, you must Set Up Theme Developer Tools. SuiteCommerce Site Development Theme Developer Tools 17 Theme Developer Tools Applies to: SuiteCommerce | SuiteCommerce Advanced The theme developer tools are required to create themes for following implementations: ■ SuiteCommerce ■ SuiteCommerce Advanced (Aconcagua and later) After you have successfully installed the theme developer tools, you are ready to develop, test, and deploy themes. to develop a theme, explore the following topics: ■ Fetch Active Theme Files ■ Test a Theme on a Local Server ■ Deploy a Theme to NetSuite Important: These procedures assume that you have successfully set up your developer environment to use the theme developer tools. See Developer Environment for details. Before You Begin Be aware of the following important information: ■ The gulp theme:deploy command checks to see if the theme you have customized is a published theme or a previously deployed, custom theme. □ When you deploy customizations to a published theme, the theme development tools require that you create a new, custom theme. You cannot overwrite content protected by copyright. □ When you deploy customizations to a pre-existing custom theme, the theme development tools give you the option to create a new theme (using the existing theme as a baseline) or update the existing theme with a new revision. ■ When you create a new custom theme, the developer tools rename the local directory where you created your customizations. This name matches the theme name you specify when you deploy your code. Example: When you download the files for the SuiteCommerce Base Theme, the developer tools create the SuiteCommerceBaseTheme directory in your theme workspace. You make your customizations, test, and deploy to NetSuite. The developer tools prompt you to create a new theme, which you name MyTheme1. When the deployment is complete, your local theme directory is renamed to MyTheme1. ■ If you deploy a theme with extension overrides and later activate new extensions for the same domain. Your deployed customizations do not apply to the new extensions. You must update your theme to include these customizations. ■ During activation, if you decide not activate an extension for which you created an override within the active theme, that override does not take effect at runtime and has no impact on your domain. ■ After deploying a theme or extension to NetSuite, you must activate the theme using the Manage Extensions wizard to apply your changes to a domain. Even if your theme is already active for a domain, you must reactivate your theme for your changes to compile. Theme parameters, including your NetSuite email, account, role, and domain information, are stored in the .nsdeploy file when you fetch a theme. To reset your login and deployment information, delete the .nsdeploy file. This file is located here: SuiteCommerce Site Development Fetch Active Theme Files 18 <LOCAL_SOURCEFILES_ROOT>/gulp/config/.nsdeploy Likewise, theme information, including the theme name, fantasy name, version, and description, are stored in the theme’s Manifest.json file. The manifest file is located here: <LOCAL_SOURCEFILES_ROOT>/Workspace/<THEME_DIRECTORY>/manifest.json Fetch Active Theme Files Applies to: SuiteCommerce | SuiteCommerce Advanced To create a theme, you first download files for the currently active theme to use as the baseline for your own custom theme. You can download files of any published theme or any previously deployed custom theme. When you run the gulp theme:fetch command, the theme developer tools download all editable themerelated files for the active theme and place them in your theme workspace. If you have any active extensions when you run the gulp theme:fetch command, the Sass, HTML, and assets of those extension download to your local environment as well. These are provided should you need to make changes to the extensions to match your new theme. Warning: When you fetch a theme, the developer tools download the active theme’s development files to your theme directory. This action overwrites any theme files currently stored in your local workspace. This can result in loss of development files if you are not careful. To ensure that you do not lose any work under development, do not run the gulp theme:fetch command until you have deployed your work to NetSuite. To develop two or more themes simultaneously, you must extract the theme developer tools into separate workspaces, one for each theme. Important: You must at least have a theme activated for a domain before continuing with this procedure. If this is your first theme, activate the SuiteCommerce Base Theme to use as your baseline. This theme includes many best practices for creating a theme. See the help topic Install Your Commerce Web Store Applications for a list of required SuiteApps and corresponding Bundle IDs. To fetch the active theme and extension files: 1. Open a command line or terminal. 2. Access the top-level theme development directory you created when you downloaded the developer tools. 3. Enter the following command: gulp theme:fetch 4. When prompted, enter the following information: NetSuite Email Enter the email address associated with your NetSuite account. NetSuite Password Enter your account password. Note: The developer tools do not support emails or passwords containing special characters such as + and %. Choose Your Target Account and Role Select the NetSuite account where your Commerce web store application is installed. You must specify the correct role with required permissions for connecting to NetSuite. SuiteCommerce Site Development Fetch Active Theme Files 19 Important: You must log in using the SCDeployer role to access your NetSuite account. Failure to use this role may result in an error. See Developer Tools Roles and Permissions for instructions on setting up this role. Choose Your Website Select your website that includes the domain you are customizing. Choose Your Domain Select your domain with the active themes and extensions you want to download. Your next step is to develop your theme. See Themes for details. What Happens When You Fetch an Active Theme? When you run the gulp theme:fetch command, the theme developer tools: ■ Create the Workspace directory in your theme development directory. If the Workspace directory already exists, the developer tools clear its contents before downloading. This action overwrites any files currently stored in your local workspace with the files being fetched. ■ Download all theme-related HTML and Sass files for the active theme and store them in your workspace by module within a directory specific to the theme. For example, Workspace/ <THEME_DIRECTORY>/Modules. The theme directory is intuitively named to match the name of the active theme. ■ Download all theme-related assets to Workspace/<THEME_DIRECTORY>/assets. ■ Download all theme-related skin preset files to Workspace/<THEME_DIRECTORY>/Skins. ■ If you are downloading a theme that includes previously deployed overrides, the developer tools download these into ../Workspace/<THEME_DIRECTORY>/Overrides. ■ Validate that all files declared in the theme’s manifest.json have been downloaded correctly. If any problems occurred, the developer tools list all missing files and direct you to execute the gulp theme:fetch command again. If the chosen domain includes any active extensions when you fetch the active theme, the developer tools: ■ Download all extension-related HTML and Sass files for the active extensions and store them in your workspace by module within directories specific to each active extension. For example, Workspace/ Extras/Extensions/<EXTENSION_DIRECTORY>/Modules. The extension directories are intuitively named to match the name of each active extension. ■ Download all extension-related assets to ../Workspace/Extras/Extensions/<EXTENSION_DIRECTORY>/ assets. When you fetch the active theme, you are basically downloading the HTML, Sass, and assets files for the active theme to use as a baseline for your own theme development. Because a published theme is protected by copyright, you cannot overwrite any files for that theme. You can, however, use an existing theme as a baseline for your own, which you later deploy as a unique theme. The SuiteCommerce Base Theme SuiteApp provides a good starting point for building your own theme. Note: Although you cannot overwrite a published theme, you can make any development changes to your own themes. When you fetch a theme for a domain, the developer tools download the HTML, Sass, and asset files for the active theme plus any HTML, Sass, and asset files of any extensions active at the time you run the gulp theme:fetch command. The local server needs these files to compile your theme when testing locally. You also have the opportunity to override the HTML and Sass for the active extensions with custom changes or add new assets. Any overrides you declare affect the domain once activated. Be aware that this only affects your domain. You are not overwriting any published extension’s code. SuiteCommerce Site Development Fetch Active Theme Files Example: Your domain has an active theme, SuiteCommerceBaseTheme, and an active extension, PublishedExtension1. Your Vendor name is ACME. You run the gulp theme:fetch command and specify your domain. In this example, your Workspace directory structure should look similar to following: Workspace/ Extras/ Extensions/ ACME/ PublishedExtension1/ assets/ Modules/ manifest.json application_manifest.json SuiteCommerceBaseTheme/ assets/ Modules/ Overrides/ Skins/ manifest.json When the gulp processes are complete your theme developer environment should look similar to the following: File Types Workspace Subdirectory Theme-related HTML and Sass files ../SuiteCommerceBaseTheme/Modules/ Theme-related asset files ../SuiteCommerceBaseTheme/assets/ Theme-related skin presets ../SuiteCommerceBaseTheme/Skins/ Extension-related HTML and Sass source files (sorted by module) ../Extras/Extensions/ACME/PublishedExtension1/Modules/ Extension-related asset files ../Extras/Extensions/ACME/PublishedExtension1/assets/ Pre-existing extension overrides ../SuiteCommerceBaseTheme/Overrides/ Test a Theme on a Local Server Applies to: SuiteCommerce | SuiteCommerce Advanced You can test your theme customizations on a local server before deploying to NetSuite. To set up your files for a local server, access the top-level directory in a command terminal and run the following command: gulp theme:local This command compiles all source files, including your theme and any extensions customizations, into combined files within a LocalDistribution/tmp directory. This directory contains the Sass and template files used by the local version of the application, so you can test your site before deploying anything to NetSuite. When the server starts, Gulp.js initializes watch tasks that listen for changes to files in the Templates and Sass directories. When you save changes to a file, gulp automatically recompiles the source files and SuiteCommerce Site Development 20 Test a Theme on a Local Server updates the LocalDistribution directory. Gulp also outputs a message to the console when an update occurs. Important: The local server is primarily used to test frontend changes. You must deploy and activate your theme to view any changes you made to skins or to Sass variables exposed to SMT. To run your Theme customizations on a local server: 1. In your local developer environment, open a command line or terminal and access the top-level development directory. 2. Run the following command: gulp theme:local Warning: Potential data loss. Besides compiling and deploying your theme to a local server, the gulp theme:local command updates the manifest.json file for the theme. This action overwrites any manual changes you made to this file. To preserve any manual changes to your manifest.json file, run the gulp theme:local --preserve-manifest command instead. See Theme Manifest for details on this file. 3. Navigate to the local version of the application using one of the following URLs: ■ http://<DOMAIN_NAME>/c.<ACCOUNT_ID>/<SSP_APPLICATION>/shopping-local.ssp ■ http://<DOMAIN_NAME>/c.<ACCOUNT_ID>/<SSP_APPLICATION>/my_account-local.ssp ■ http://<DOMAIN_NAME>/c.<ACCOUNT_ID>/<SSP_APPLICATION>/checkout-local.ssp In the above URL patterns, you must replace the following variables with values for your specific environment: DOMAIN_NAME Replace this value with the domain name configured for your NetSuite website record. For example: http://www.mysite.com ACCOUNT_ID Replace this value with your NetSuite account ID. For example: c.123456 SSP_APPLICATION Replace this value with the URL root that you are accessing. SuiteCommerce example: scs For SuiteCommerce Advanced (SCA), this variable equals the URL root of the SCA implementation. ■ sca-dev-2019–2 SuiteCommerce Advanced examples: For SuiteCommerce implementations, this ■ sca-dev-aconcagua variable should read scs. Complete URLs for SuiteCommerce implementations would look like these examples: SuiteCommerce Site Development 21 Test a Theme on a Local Server 22 ■ http://www.mysite.com/c.123456/scs/shopping-local.ssp ■ http://www.mysite.com/c.123456/scs/my_account-local.ssp Complete URLs for SuiteCommerce Advanced implementations would look like these examples: ■ http://www.mysite.com/c.123456/sca-dev-aconcagua/shopping-local.ssp ■ http://www.mysite.com/c.123456/sca-dev-2019–2/shopping-local.ssp The local server starts automatically. With the local server running, you can make changes to your local files and see the results immediately. Gulp.js automatically recompiles the application when you save any changes to theme-related HTML, Sass, or assets. Simply refresh your browser to see the changes. You can also deploy your theme to NetSuite. This is required if you want to activate the theme on a domain. This is also required to test any Sass variables exposed to the Site Management Tools Theme Customizer. See Deploy a Theme to NetSuite. Important: If you add a new file or make changes to any overrides after launching the local server, you must run the gulp theme:local command again to include the new changes. Gulp.js does not automatically compile new files or process overrides. Deploy a Theme to NetSuite Applies to: SuiteCommerce | SuiteCommerce Advanced When you initially deploy a theme to NetSuite, you configure your environment to deploy to a specific account and SSP Application. For SuiteCommerce sites, this is straightforward (as a managed bundle, SuiteCommerce relies on the SuiteCommerce SSP Application only). If deploying to a SuiteCommerce Advanced (SCA) account, you must also configure the correct SSP Application, related to the current release you are implementing. To deploy a theme, use the following command: gulp theme:deploy This command validates your customizations, copies them into a local DeployDistribution directory, and updates the manifest files with any necessary overrides. Gulp.js then uploads these files to your NetSuite account, making them available for activation. When you deploy your theme to NetSuite, the developer tools upload your development files to a location in your NetSuite File Cabinet. The developer tools compile your theme files locally, but only for testing. Deploying a theme does not apply your theme to a domain. Deployment simply makes your theme available for activation in the Manage Extensions Wizard. See the help topic Manage Themes and Extensions for details. Note: You cannot overwrite any themes protected by copyright. This includes any themes published by Oracle or Oracle-certified partners. You can, however, use these themes as a baseline for your own customizations. For more Gulp.js commands used with themes and extensions, see Gulp Command Reference for Themes and Extensions. To deploy your theme to NetSuite: 1. In your local developer environment, open a command line or terminal and access the top-level development directory. 2. Run the following command: SuiteCommerce Site Development Deploy a Theme to NetSuite gulp theme:deploy Warning: Potential data loss. Besides compiling and deploying your theme, the gulp theme:deploy command updates the manifest.json file for the theme. This action overwrites any manual changes you made to this file. To preserve any manual changes to your manifest.json file, run the gulp theme:deploy --preserve-manifest command instead. See Theme Manifest for details on this file. 3. When prompted, enter the following information. Unless otherwise noted, create all entries using only alphanumeric characters without spaces. Note: These prompts appear the first time you deploy a new theme to NetSuite. Subsequent deployments of the same theme only prompt for your NetSuite password. To reset the login information and fill in these prompts again, use the gulp theme:deploy --to command. NetSuite Email Enter the email address associated with your NetSuite account. NetSuite Password Enter your account password. Note: The developer tools do not support emails or passwords containing special characters such as + and %. Target Account and Role Choose your account and role. Website Choose the website associated with your domain. Vendor Enter the name of the vendor building this theme. Name Enter a name for your custom theme. Fantasy Name Provide a name for your theme as you want it to appear in the NetSuite user interface. This can contain special characters and spaces. Version Enter a version for your theme. Important: To take advantage of theme update requirements, assign a version number to your extensions. Version numbers should follow this format, where d is a single digit: dd.dd.dd. Description Enter a brief description for your theme. This will appear in NetSuite when you select themes to activate. Supported Products Select the product or products (SuiteCommerce Online or SCIS) to which you are deploying. An asterisk (*) identifies a selected product. SuiteCommerce Online applies to SuiteCommerce and SuiteCommerce Advanced. ■ Use the spacebar key to select or deselect an option. ■ Use the UP and DOWN arrow keys to scroll through the options. ■ Toggle the A key to select or deselect all options. Target Version Using Commerce versioning schema, enter a string to declare the target versions to which this theme applies. The developer tools prompt you for a target version for each product specified earlier. Leaving these prompts blank results in compatibility with all versions of the associated Commerce products. See Declare Target Versions and SuiteScript 2.0 Bundle Installation Script Type for more information. SuiteCommerce Site Development 23 Deploy a Theme to NetSuite 24 Your customizations do not apply to your site until you activate the theme for a specific domain using the Manage Extensions wizard in NetSuite. The deploy process includes a notation reminding you of the domain and theme name to set during this process. See the help topic Activate Themes and Extensions for instructions on activating your new theme for the domain or domains of your choice. What Happens When You Deploy a Theme? The deployment process is specific to uploading theme files and extension overrides (if applicable) to a location in your NetSuite File Cabinet. This process only compiles your source files for testing before deployment. The deployment process does not deploy compiled files or associate any files with a site or domain. To do that, you must activate your theme using the Manage Extensions Wizard. When you download a theme or extension’s source files using the gulp theme:fetch command, you receive all HTML, Sass, overrides, and assets (images, fonts, etc.) of the active theme. This command places these files in your Workspace/<THEME_DIRECTORY> folder. This is where you build your custom themes and extension overrides. During the deployment process: ■ The developer tools copy all of your custom theme development files (modules, assets, and overrides) into the DeployDistribution folder in your top-level development directory. If this directory does not exist, the developer tools create it. ■ The developer tools validate your customizations. ■ The developer tools update the manifest.json file to include any overrides. ■ The developer tools upload development files to your NetSuite file cabinet as bundled files (maintaining the same organizational structure). Note: The gulp theme:deploy command uploads your theme development files in groups of files called chunks. The default number of files in a single chunk is 80 files. If needed, you can configure the number of files in each chunk. See Troubleshooting the Developer Tools for more information. ■ NetSuite creates an Extension record for the custom theme. Like a published theme or extension, these files have not compiled into usable files, but they are available for activation. Note: Your extension overrides always deploy as part of a custom theme. If you activate a custom theme but fail to activate any extension for which the theme includes overrides, the application will ignore the overrides and your site will function normally. Example You download the source files for the active theme (SuiteCommerce Base Theme) and the active extension (PublishedExtension1). You follow best practices and procedures to customize your theme files and override your extension files. After testing on a local server, you decide to deploy your customizations. You run the gulp theme:deploy command, and the theme development tools update the manifest file with any overrides, validate your customizations, and copy the contents of your theme directory to your DeployDistribution directory. The development tools then upload your development files to a location in your NetSuite File Cabinet. These files are not compiled into any usable runtime files, but they are now available for activation an a site and domain. When you run the gulp theme:deploy command, the development tools prompt you for a new theme name, which you call MyCustomTheme1. Finally, the development tools rename your Workspace/ SuiteCommerce Site Development Deploy a Theme to NetSuite 25 SuiteCommerceBaseTheme directory to Workspace/MyCustomTheme1 and update the manifest and configuration file with the new theme name. This prepares the local environment to function with the new name. SuiteCommerce Site Development Extension Developer Tools Extension Developer Tools Applies to: SuiteCommerce | SuiteCommerce Advanced | SuiteCommerce InStore The extension developer tools are required to create extensions for following implementations: ■ SuiteCommerce ■ SuiteCommerce Advanced (Aconcagua and later) ■ SuiteCommerce InStore After you have successfully installed the extension developer tools, you are ready to develop, test, and deploy extensions. Extension development requires using the Extensibility API. to develop an extension, explore the following topics: ■ Create Extension Files ■ Fetch Active Theme and Extension Files ■ Test an Extension on a Local Server ■ Deploy an Extension to NetSuite Important: These procedures assume that you have successfully set up your developer environment to use the extension developer tools. See Developer Environment for details. Before You Begin Be aware of the following important information: ■ The gulp extension:fetch command only fetches the following: □ HTML and Sass files associated with the currently active theme for the specified domain. □ Extensions development files for custom extensions currently active for the specified domain. You cannot download files for published extensions. ■ Login parameters, including your NetSuite email, account, role, and domain information, are stored in the .nsdeploy file when you create an extension. To reset your login and deployment information, delete the .nsdeploy file. This file is located here: <LOCAL_SOURCEFILES_ROOT>/gulp/config/.nsdeploy ■ Extension information, including the extension name, fantasy name, version, and description, are stored in the extension’s Manifest.json file. The manifest file is located here: <LOCAL_SOURCEFILES_ROOT>/Workspace/<EXTENSION_DIRECTORY>/manifest.json Create Extension Files Applies to: SuiteCommerce | SuiteCommerce Advanced | SuiteCommerce InStore The following section explains how to use the extension developer tools to create initial files to use as a baseline for extension development. This is a critical first step when building a new extension, as it provides you with a starting point in your extension workspace. SuiteCommerce Site Development 26 Create Extension Files 27 Create a Baseline Extension Applies to: SuiteCommerce | SuiteCommerce Advanced | SuiteCommerce InStore A Baseline Extension is a set of files, installed locally in your extension development directory. You use these files as a basis to build any extension for your Commerce web store or SCIS implementation. When you run the gulp extension:create command, the developer tools create this baseline extension in a Workspace directory within your top-level extension development directory. The baseline extension starts out with one module that you design, based on your needs. It can include any combination of the following file types within one new module: ■ Templates ■ Sass ■ Configuration ■ JavaScript ■ SuiteScript 1.0 ■ SuiteScript 2.0 Note: Only 2020.1 Extension Developer Tools and later include the SuiteScript 2.0 file type as an option. To create a baseline extension: 1. Open a command line or terminal. 2. Access the top-level extension development directory you created when you installed the extension developer tools. 3. Enter the following command: gulp extension:create 4. When prompted, enter the information for your baseline extension. ■ Unless otherwise directed, create all entries using only alphanumeric characters without spaces. ■ Pressing enter results in the default value. Set Your Extension Fantasy Name Provide a name for your extension as you want it to appear in the NetSuite user interface. This can contain special characters and spaces. For example: My Cool Extension! Set Your Extension Name Provide a name for your extension’s files and folders within your development environment. Set the Vendor Name Enter your business, vendor, or partner name. Assign a Version Number Add a version number for your extension. Important: To take advantage of extension update requirements, assign a version number to your extensions. Version numbers should follow this format, where d is a single digit: dd.dd.dd. Set the Initial Module Name Name the module to be created as part of the baseline extension. Each extension needs at least one module to contain your extension files. SuiteCommerce Site Development Create Extension Files Set a Description for Your Extension Provide some text to describe your extension. This string can contain spaces and special characters. This Extension Supports Select one of the following options: 28 ■ SuiteCommerce Online – To create an extension for SuiteCommerce or SuiteCommerce Advanced. ■ SuiteCommerce InStore – To create an extension for SuiteCommerce InStore. An asterisk (*) identifies the selected option. Use arrow keys to scroll. Press the spacebar to select an option, press <a> key to select all, or <i> key to invert your selections. This Extension Will Be Applied To Select one or more applications that your extension requires. Options include: ■ Shopping ■ My Account ■ Checkout Target Version Using Commerce versioning schema, enter a string to declare the target versions to which this extension applies. The developer tools prompt you for a target version for each product specified earlier. Leaving these prompts blank results in compatibility with all versions of the associated Commerce products. See Declare Target Versions and SuiteScript 2.0 Bundle Installation Script Type for more information. For This Extension You Will Be Using Select one or more file types that your extension should include. Your file options are: ■ JavaScript ■ SuiteScript ■ Templates ■ Sass ■ Configuration ■ SuiteScript2 The developer tools create a baseline example of these files to get you started. Note: Only 2020.1 Extension Developer Tools and later include the SuiteScript 2.0 file type as an option. After following these prompts, you can optionally build on this baseline by adding additional modules. Consider the following topics: ■ Create Additional Modules for an Extension ■ Create Custom Content Types for an Extension When you have completed building baseline extension files in your developer environment, you are ready to develop your extension. See Extensions for details. What Happens When You Create Extension files? When you run the gulp extension:create command, the extension developer tools: ■ Create the Workspace directory in your top-level development directory, unless it already exists. ■ Create a subdirectory to house all of your extension’s code. This is where you develop your extension. ■ Create a manifest.json file. This file includes all the information required to compile resources for your extension. SuiteCommerce Site Development Create Extension Files 29 Example You run the gulp extension:create command and build a baseline extension, MyCoolExtension with a module called MyCoolModule. You set this extension to include all available files. In this example, your Workspace directory structure should look similar to: Workspace/ MyCoolExtension/ assets/ fonts/ img/ services/ Modules/ MyCoolModule/ Configuration/ JavaScript/ Sass/ SuiteScript/ SuiteScript2/ Templates/ manifest.json When you run the gulp extension:create command, the extension developer tools also create a frontend model in the JavaScript directory for your extension’s initial module. For this example, the model name would be: [Vendor_Name].MyCoolExension.MyCoolModule.Model.js. This model includes logic to issue requests via entry points to a backend service. During extension development, the location of extension files after activation is unknown. So, to successfully issue service requests, the model uses the getAbsoluteUrl method to generate the absolute URL to the service. This is the service URL that will exist when the extension is deployed to NetSuite and activated. The getAbsoluteUrl method includes two parameters: ■ The relative path to the service, which is returned by the getExtensionAssetsPath helper. ■ A boolean that it set to True to generate an absolute URL for a SuiteScript 2.0 service; or set to False to generate the URL to a SuiteScript 1.0 backend service. Note that leaving the boolean empty is the same as a False setting. Important: The extension developer tools create one initial frontend model for each module in your extension. You need to create additional models if your extension module includes multiple services. Create a separate model for each service. To create additional models, you can copy and rename the initial model created by the extension developer tools. Then make sure each model includes the correct values for the getAbsoluteUrl method parameters as shown in the following examples: SuiteScript 1.0 service //@property {String} urlRoot urlRoot: Utils.getAbsoluteUrl( getExtensionAssetsPath("services/MyCoolModule.Service.ss") ); SuiteScript 2.0 service //@property {String} urlRoot urlRoot: Utils.getAbsoluteUrl( getExtensionAssetsPath( "Modules/MyCoolModule/SuiteScript2/MyCoolModule.Service.ss" ), true ); SuiteCommerce Site Development Create Extension Files 30 Create Additional Modules for an Extension Applies to: SuiteCommerce | SuiteCommerce Advanced | SuiteCommerce InStore The gulp extension:create command builds an extension with one baseline module. However, if your extension requires more than one module, the developer tools let you create more using the —module attribute. To add an additional module to your baseline extension: 1. Create a baseline extension, if you have not done so already. See Create a Baseline Extension for details. 2. Open a command line or terminal. 3. Access the top-level extension development directory you created when you installed the extension developer tools. 4. Enter the following command: gulp extension:create-module 5. When prompted, enter the following information: Important: Unless otherwise directed, create all entries using only alphanumeric characters without spaces. Set the Module Name Name the module to be created as part of the baseline extension. Use only alphanumeric characters without spaces. For This Module You Will Select one or more file types your extension requires. Your file options are: Be Using ■ JavaScript ■ SuiteScript ■ Templates ■ Sass ■ Configuration ■ SuiteScript2 The developer tools create a baseline of these files to get you started. Note: Only 2020.1 Extension Developer Tools and later include the SuiteScript 2.0 file type as an option. Select extension to add module Select the name of the extension to contain this module. This option only appears if your Workspace directory contains more than one extension. 6. Repeat these steps to add any additional modules as needed. Important: NetSuite imposes certain record limits to control the consumption of web services. To avoid errors related to record limits when deploying themes and extensions, limit the number of files and folders at the same level to 100 when developing themes and extensions. Some options include introducing images across multiple folders and placing custom modules in a different top-level directory. For more information on record limiting, see the help topic SOAP Web Services Governance Overview. When you have completed building baseline extension files in your developer environment, you are ready to develop your extension. See Extensions for details. SuiteCommerce Site Development Create Extension Files 31 Create Custom Content Types for an Extension Applies to: SuiteCommerce | SuiteCommerce Advanced When you create your baseline extension files, the developer tools provide a method to build your extension as a CCT. The developer tools provide on-screen instructions to assist you with developing your CCT. This requires: ■ Creating a baseline extension ■ Adding one or more baseline CCTs ■ Customizing your CCT and preparing it for use with Site Management Tools Note: To implement a CCT using Site Management Tools, you must configure the CMS Adapter Version to 3 in the SuiteCommerce Configuration record. This property is located in the Integrations tab and Site Management Tools subtab. To add a CCT to your baseline extension: 1. Open a command line or terminal. 2. Access the top-level extension development directory you created when you installed the extension developer tools. 3. Create a baseline extension, if you have not done so already. See Create a Baseline Extension for details. 4. Enter the following command: gulp extension:create-cct 5. When prompted, enter the following information: Important: Unless otherwise directed, create all entries using only alphanumeric characters without spaces. Set the Label of the CCT Name the CCT to be added to your baseline extension. This can contain alphanumeric and special characters. Set the Name of the CCT Provide a name for your CCT as it appears in your development files and folders. Use only alphanumeric characters without spaces. Set a Description for your CCT Provide some text to describe your CCT. For This CCT You Will Be Using Select one or more file types your CCT requires (Templates, Sass, Configuration, JavaScript, SuiteScript). An asterisk (*) identifies a selected application. Select Extension to Add CCT Select the name of the extension to contain this module. This option only appears if your Workspace directory contains more than one extension. 6. Repeat these steps to add any additional CCTs as needed. To Build a CCT: After you have successfully created your baseline CCT, you must set it up for use with Site Management Tools and customize your code to meet your needs. SuiteCommerce Site Development Create Extension Files 32 1. Open the extension’s manifest.json file. This can be found in Workspace/ <EXTENSION_DIRECTORY>/. This file lists the following as part of the manifest metadata. You need this information when setting up your records in NetSuite. icon Equals a default icon that is visible in SMT Admin. As a default, the developer tools provide one to help you get started. settings_record Equals the ID of the custom record you associate with this CCT. registercct_id Equals the Name field of the CMS Content Type Record for your CCT. This is also the value of the id property within the registerCustomContentType() method of your CCT module’s entry point JavaScript file. 2. Prepare your CCT for use with SMT. Follow the instructions listed in the help topic Custom Content Type. Build your custom record and your CMS Content Type Record using the parameters explained in Step 1. 3. Develop your CCT module. Follow the instructions listed in the help topic Create a Custom Content Type. Ensure that your entry point JavaScript file incorporates your CMS Content Type record name, as described in Step 1. 4. Deploy and activate your extension. Then log into SMT to test confirm that your CCT was added correctly. See the help topic Site Management Tools for details on using SMT. ■ See Deploy an Extension to NetSuite for instructions on deploying your extension. ■ See the help topic Manage Themes and Extensions for instructions on activating your extension. ■ Extensions API Fetch Active Theme and Extension Files Applies to: SuiteCommerce | SuiteCommerce Advanced | SuiteCommerce InStore If creating an extension for SuiteCommerce or SCA, you must first download files for the currently active theme before you can deploy an extension or test it on a local server. You do this by running the following command: gulp extension:fetch Note: SCIS extension developers can disregard this section. This command: ■ Downloads HTML and Sass files for the currently active theme. Do not modify these files. The Sass and HTML files downloaded using this command are for reference only. ■ Downloads files for any custom extensions that are currently activated. The developer tools require theme files (HTML and Sass) to compile a local distribution for testing an extension on a local server. The developer tools also use these files to run a test compilation before deploying. When you fetch the active theme, you provide the necessary files in your local extension workspace. Later, when you test locally or deploy your extension, the developer tools can compile the code without error. SuiteCommerce Site Development Fetch Active Theme and Extension Files 33 If you want to skip this step, you can run the gulp extension:deploy --skip-compilation command to deploy your extension files without running the compilation. For more Gulp.js commands used with extensions, see Extension Developer Gulp Commands. The gulp extension:fetch command also fetches files for any custom extensions. When you fetch files for an active extension, you download these development files to your local extension workspace. You can now customize these files further development and testing. Warning: When you fetch custom extension files, the developer tools download extension files that are activated for the specified domain. This action overwrites any extension files currently stored in your local workspace. This can result in loss of development files if you are not careful. To ensure that you do not lose any work under development, do not run the gulp extension:fetch command until you have deployed your extension work to NetSuite. Note: This command does not download files for published extensions. A published extension is an extension installed into your account as part of a published SuiteApp. You cannot edit published content due to copyright restrictions. Fetch the active files: 1. In your local developer environment, open a command line or terminal and access the top-level extension development directory. 2. Run the following command: gulp extension:fetch 3. When prompted, enter the following information: ■ NetSuite Email – Enter the email address associated with your NetSuite account. ■ NetSuite Password – Enter your account password. ■ Choose Your Target Account and Role – Select the NetSuite account where the Commerce web store application is installed. You must specify the correct role with required permissions for connecting to NetSuite. Important: You must log in using the SCDeployer role to access your NetSuite account. Failure to use this role may result in an error. See Developer Tools Roles and Permissions for instructions on setting up this role. ■ Choose Your Website – Select your website with the domain you want to access. ■ Choose Your Domain – Select your domain with the active theme or extensions you want to download. ■ Extensions to Fetch – If you have any active extensions for the domain selected, you can download the working files of any selected extensions. This is optional. Content downloads to your extension’s Extras folder. The gulp extension:fetch command creates a theme subdirectory in your Workspace/Extras directory. These files are for use by the developer tools only. Do not add, edit, delete, or move any files in this location. You are now ready to perform either of the following tasks: ■ Test an Extension on a Local Server ■ Deploy an Extension to NetSuite SuiteCommerce Site Development Test an Extension on a Local Server 34 Test an Extension on a Local Server Applies to: SuiteCommerce | SuiteCommerce Advanced | SuiteCommerce InStore You can test your extension customizations on a local server before deploying to NetSuite. The local server is installed as part of the Node.js installation and uses the Express web framework. gulp extension:local This command compiles all source files into combined files within a LocalDistribution/tmp directory. When the server starts, Gulp.js initializes watch tasks that listen for changes to files in the JavaScript, Templates, or Sass directories. When you save changes to a file, gulp automatically recompiles the source files and updates the LocalDistribution directory. Gulp also outputs a message to the console when an update occurs. Important: Typically, you test your code locally before deploying to a live site in a NetSuite account. However, if you are developing an extension that includes SuiteScript or configuration (JSON) files, you must deploy your files to your account and activate the extension for these changes to accessible by the local server. SuiteScript includes services, which do not exist in your account’s backend until you deploy them. Likewise, changes to configuration JSON files do not apply to a domain until deployed. See the help topic Manage Themes and Extensions. Note: If you modify any manifest files, you must restart your local server to see changes. To test your extension on a local server: 1. If you have not already done so, fetch the active theme. This is required before you can test an extension locally. See Fetch Active Theme and Extension Files for details. 2. Open a command line or terminal and access the top-level development directory. This is the same directory created when you extracted the Extension Developer Tools. 3. Run the following command: gulp extension:local If this is the first time you are running gulp extension:local in this directory, this command creates a subdirectory called LocalDistribution. It then compiles the source files and outputs them to this directory. Warning: Potential data loss. Besides compiling and deploying your extension to a local server, the gulp extension:local command updates the manifest.json file for the extension. This action overwrites any manual changes you made to this file. To preserve any manual changes to your manifest.json file, run the gulp extension:local --preserve-manifest command instead. See Extension Manifest for details on this file. 4. Navigate to the local version of the application using one of the following URLs: ■ Shopping: http://<DOMAIN_NAME>/c.<ACCOUNT_ID>/<SSP_APPLICATION>/shopping-local.ssp ■ My Account: http://<DOMAIN_NAME>/c.<ACCOUNT_ID>/SSP_APPLICATION/my_account-local.ssp ■ Checkout: http://<DOMAIN_NAME>/c.<ACCOUNT_ID>/SSP_APPLICATION/checkout-local.ssp In the above URL patterns, you must replace the following variables with values for your specific environment: SuiteCommerce Site Development Test an Extension on a Local Server DOMAIN_NAME Replace this value with the domain name configured for your NetSuite website record. For example: http://www.mysite.com ACCOUNT_ID Replace this value with your NetSuite account ID. For example: c.123456 SSP_APPLICATION Replace this value with the URL root that you are accessing. SuiteCommerce example: scs For SuiteCommerce Advanced (SCA), this variable equals the URL root of the SCA implementation. ■ sca-dev-2019–2 SuiteCommerce Advanced examples: For SuiteCommerce implementations, this ■ sca-dev-aconcagua variable should read scs. Complete URLs for SuiteCommerce implementations would look like these examples: ■ http://www.mysite.com/c.123456/scs/shopping-local.ssp ■ http://www.mysite.com/c.123456/scs/my_account-local.ssp Complete URLs for SuiteCommerce Advanced implementations would look like these examples: ■ http://www.mysite.com/c.123456/sca-dev-aconcagua/shopping-local.ssp ■ http://www.mysite.com/c.123456/sca-dev-2019–2/shopping-local.ssp Note: When accessing the secure checkout domain using HTTPS on the local server, you must use a different URL. See Secure HTTP (HTTPS) with the Local Server for more information. Deploy an Extension to NetSuite Applies to: SuiteCommerce | SuiteCommerce Advanced | SuiteCommerce InStore The term deploy refers to what happens when you use Gulp.js to upload source files and any custom changes to a hosted site. To do this, you use the following command: gulp extension:deploy This command validates your code, copies them into a local DeployDistribution directory, and updates the manifest.json. The developer tools then upload these files to your NetSuite account, making them available for activation. Note: For more Gulp.js commands used with extensions, see Extension Developer Gulp Commands. To deploy your extension to NetSuite: 1. If you have not already done so, fetch the active theme. This is required before you can deploy an extension. See Fetch Active Theme and Extension Files for details. 2. In your local developer environment, open a command line or terminal and access the top-level development directory. 3. Run the following command: SuiteCommerce Site Development 35 Deploy an Extension to NetSuite gulp extension:deploy Warning: Potential data loss. Besides compiling and deploying your extension to NetSuite, the gulp extension:deploy command updates the manifest.json file for the extension. This action overwrites any manual changes you made to this file. To preserve any manual changes to your manifest.json file, run the gulp extension:deploy --preservemanifest command instead. See Extension Manifest for details on this file. 4. When prompted, enter the following information. ■ Unless otherwise directed, create all entries using only alphanumeric characters without spaces. ■ These prompts appear the first time you deploy a new extension to NetSuite. Subsequent deployments of the same extension only prompt for your NetSuite password. To reset the login information and enter information again, use the gulp extension:deploy --to command to deploy your changes. Select Extension If you have more than one extension in your developer environment, choose the extension you are deploying. NetSuite Email Enter the email address associated with your NetSuite account. NetSuite Password Enter your account password. Choose Your Target Select the NetSuite account where the Commerce web store application is installed. Account and Role You must specify the correct role with required permissions for connecting to NetSuite. Important: You must log in using the SCDeployer role to access your NetSuite account. Failure to use this role may result in an error. See Developer Tools Roles and Permissions for instructions on setting up this role. Choose Your Website Choose your site from the list. Vendor Enter your partner or business vendor name. Name Provide a name for your extension within your development environment. Fantasy Name Provide a name for your extension as you want it to appear in the NetSuite user interface. This can contain special characters and spaces. Version Add a version number for your extension. Important: To take advantage of extension update requirements, assign a version number to your extensions. Version numbers should follow this format, where d is a single digit: dd.dd.dd. Description Provide some text to describe your extension. This string can contain special characters and spaces. Select Supported Products Select one of the following options: ■ SuiteCommerce Online – To create an extension for SuiteCommerce or SuiteCommerce Advanced. ■ SuiteCommerce InStore – To create an extension for SuiteCommerce InStore. SuiteCommerce Site Development 36 Deploy an Extension to NetSuite 37 An asterisk (*) identifies a selected option. Press the spacebar to select. Use arrow keys to scroll. Press the A key to select all. Press the I key to invert your selections. Target Version Using Commerce versioning schema, enter a string to declare the target versions to which this extension applies. The developer tools prompt you for a target version for each product specified earlier. Leaving these prompts blank results in compatibility with all versions of the associated Commerce products. See Declare Target Versions and SuiteScript 2.0 Bundle Installation Script Type for more information. 5. Activate your new extension for the domain or domains of your choice. See the help topic Manage Themes and Extensions for instructions. Important: Any changes to your extension source code do not apply to your site until you activate the extension for a specific domain using the Manage Extensions wizard in NetSuite. The deploy process includes a notation reminding you of the domain and theme name to set during this process. What Happens When You Deploy an Extension? The deployment process is specific to uploading custom extensions to a location in your NetSuite file cabinet. This process does not compile any files or associate any files with a site or domain. To do that, you must activate a theme and include your extensions as necessary. During the deployment process: ■ The development tools copy all of your custom extension development files (modules and assets) into the DeployDistribution folder in your top-level development directory. If this directory does not exist, the development tools create it. ■ The extension development tools validate your code. ■ The extension development tools upload these files to your NetSuite file cabinet (maintaining the same organizational structure). These are simply your development files. Nothing is compiled or activated at this time. Note: The gulp extension:deploy command uploads your extension development files in groups of files called chunks. A single chunk, by default, contains 80 files. If needed, you can change the number of files in each chunk. See Troubleshooting the Developer Tools for more information. SuiteCommerce Site Development Developer Tools Reference 38 Developer Tools Reference Applies to: SuiteCommerce | SuiteCommerce Advanced | SuiteCommerce InStore This topic includes the reference materials for using the developer tools. The Gulp Command Reference provides details on each command using the theme and extension developer tools. Some of these topics provide important details for testing locally or deploying to NetSuite. Developer Tools Roles and Permissions Applies to: SuiteCommerce | SuiteCommerce Advanced | SuiteCommerce InStore Two-factor authentication (2FA) is mandatory on all NetSuite accounts using NetSuite 2018.2 and later. However, Commerce developer tools do not currently support 2FA. When using the Commerce developer tools to access a NetSuite account provisioned with 2FA, you must sign in with the SCDeployer role. This role includes all permissions required to deploy customizations but does not require two-factor authentication. This section includes the following topics: ■ Confirm That You Have the SCDeployer Role – Explains how to determine if you already have the SCDeployer role. ■ Prepare the SCDeployer Role – Explains how to prepare the SCDeployer role for use. ■ Set Up the SCDeployer Role Manually – This topic explains how to set up the SCDeployer role manually. This applies to implementations of SuiteCommerce Advanced (Aconcagua and earlier) only. Important: Because the developer tools do not accommodate 2FA, any attempt to deploy or fetch themes and extensions or deploy core SCA modules without properly setting up and using the SCDeployer role results in errors. See Error Messages When Running the Developer Tools for troubleshooting these errors. Confirm That You Have the SCDeployer Role Applies to: SuiteCommerce | SuiteCommerce Advanced | SuiteCommerce InStore If you have the SuiteCommerce Extension Management SuiteApp installed in your NetSuite account, you should have the SCDeployer role. However, you can check your NetSuite account for confirmation. To determine if you have the SCDeployer role in your account: 1. In NetSuite, go to Setup > Users/Roles > Manage Roles. 2. Scroll to see if the SCDeployer role exists in the list. 3. If the role exists, see Assign the SCDeployer Role to an Employee Record. If the role does not exist, see Set Up the SCDeployer Role Manually to create it. Prepare the SCDeployer Role Applies to: SuiteCommerce | SuiteCommerce Advanced | SuiteCommerce InStore After you have confirmed that the SCDeployer role exists in your account, perform the following steps to prepare it for use in the developer tools: SuiteCommerce Site Development Developer Tools Roles and Permissions 39 ■ Assign the SCDeployer Role to an Employee Record ■ Prepare Developer Tools Assign the SCDeployer Role to an Employee Record Before a developer can use the Commerce developer tools, you must assign the SCDeployer role to the Employee record for each employee that requires developer access to NetSuite. Assign the SCDeployer role in Role field of the Employee record (Access tab, Role subtab). See the help topic Assigning Roles to an Employee more information. Prepare Developer Tools The developer tools prompt you for login credentials when you initially use the following commands to access NetSuite: ■ gulp theme:fetch ■ gulp theme:deploy ■ gulp extension:fetch ■ gulp extension:deploy ■ gulp deploy The developer tools store the login credentials (including the role) in the .nsdeploy file. If you used the Commerce developer tools prior to setting up the SCDeployer role, you might need to reset the login credentials. To reset the developer tools login credentials, add the ––to parameter to the applicable gulp command within the developer tools. This prompts the developer to recreate the login credentials, overwriting the .nsdeploy file. When prompted to choose a role using any of the aforementioned commands, select the SCDeployer role to gain access to NetSuite accounts without requiring two-factor authentication. Set Up the SCDeployer Role Manually Applies to: SuiteCommerce Advanced If you are implementing the Aconcagua release of SuiteCommerce Advanced and earlier, you must create the SCDeployer role manually. If you do not have the SCDeployer role in your NetSuite account, perform the following steps: ■ Create the SCDeployer Role ■ Edit Script Deployment Records Create the SCDeployer Role To create a SCDeployer role: 1. In NetSuite, go to Setup > Users/Roles > Manage Roles > New. 2. Fill in the Role record as described in the Customizing or Creating NetSuite Roles topic. Include the following changes: ■ In the Name field, title the role SCDeployer. ■ In the ID field, enter _sc_deployer. SuiteCommerce Site Development Developer Tools Roles and Permissions ■ In the Two-Factor Authentication Required field, select Not required. ■ On the Permission tab, add the following permissions: Subtab Role Level Lists Documents and Files Full Custom Record Entries Full Website (External) Publisher Full Allow JS/HTML Uploads Full Custom Lists Full Set Up Web Site Full SuiteScript View Web Services Full Setup 3. Save the Role record. 4. Assign the SCDeployer role to the Employee record for each person requiring developer access to NetSuite. See Assign the SCDeployer Role to an Employee Record for more information. 5. If necessary, prepare the developer tools to allow NetSuite access using the SCDeployer Role. See Prepare Developer Tools for more information. Edit Script Deployment Records As part of the manual role set up, you must also manually edit your account’s Script Deployment records. To edit Script Deployment records: 1. In NetSuite, go to Customization > Scripting > Script Deployments. 2. Set the following filters: ■ Type: RESTlet ■ API Version: 1.0 3. Add the SCDeployer role to Roles list on the Audience tab for each of the following Script Deployment records, depending on your implementation: SuiteCommerce, SuiteCommerce Advanced (Aconcagua and Later), SCIS (2018.2 and later): Edit each of the following Script Deployment records. ■ customdeploy_ext_mech_extension_service ■ customdeploy_ext_mech_file_service ■ customdeploy_ext_mech_skin_service ■ customdeploy_ext_mech_web_service_rest SuiteCommerce Advanced and Site Builder Extensions (Kilimanjaro release and Earlier): Edit the script associated with your implementation. ■ customdeploy_ns_sca_deployer_kilimanjaro ■ customdeploy_ns_sca_deployer_elbrus SuiteCommerce Site Development 40 Developer Tools Roles and Permissions 41 ■ customdeploy_ns_sca_deployer_mont_blanc ■ customdeploy_ns_sca_deployer_vinson ■ customdeploy_ns_sca_deployer_denali ■ customdeploy_ns_sbe_deployer_elbrus ■ customdeploy_ns_sbe_deployer_kilimanjaro ■ customdeploy_ns_sbe_deployer_mont_blanc ■ customdeploy_ns_sbe_deployer_vinson ■ customdeploy_ns_sbep_deployer_denali ■ customdeploy_ns_sbep_deployer_mont_blanc ■ customdeploy_ns_sbep_deployer_vinson ■ customdeploy_ns_sbep_deployer_elbrus ■ customdeploy_ns_sbep_deployer_kilimanjaro 4. Save the Script Deployment record. Gulp Command Reference for Themes and Extensions Applies to: SuiteCommerce | SuiteCommerce Advanced | SuiteCommerce InStore The following tables lists Gulp.js commands required when using the theme or extension developer tools with your Commerce web store: ■ Theme Developer Gulp Commands ■ Extension Developer Gulp Commands Note: For a list of commands used with the SuiteCommerce Advanced (SCA) developer tools, see Theme Developer Gulp Commands. Theme Developer Gulp Commands Command Description gulp theme:fetch This command downloads the active theme and extension files (Sass, HTML, and other assets) for the specified domain. You must have already activated a theme using the Manage Extensions wizard in NetSuite for this command to run. This command places these files in the top-level directory’s Theme directory. If this is the first time running this command, the development tools create subdirectories for these files. gulp theme:fetch --to This command fetches a theme and extensions from NetSuite as usual, but it prompts for login credentials, ignoring the .nsdeploy file. gulp theme:local This command compiles all Sass and HTML template files for a theme into a functional application. This command also updates the theme manifest.json. After compilation, this command starts a local server. This server watches for changes to Sass and HTML template files. After the server starts, any changes you make to your theme files or extension overrides are automatically recompiled and visible in the browser. SuiteCommerce Site Development Gulp Command Reference for Themes and Extensions Command Description gulp theme:local --preservemanifest This performs the same action as gulp theme:local, but it does not update the manifest. Use this command to test your theme locally if you have made any manual changes to the manifest.json file for the theme. gulp theme:deploy This command compiles Sass, HTML, and asset files into a DeployDistribution folder. This command also updates the theme manifest.json. 42 If you are deploying changes to a published theme, the development tools prompt you for a Vendor Name, Theme Name, Theme Version, Description, and Application when you initially run this command. This command forces you to name a new theme. If you are deploying customizations to a custom theme, this command does not prompt you for this information and gives you the option to create a new theme or update the existing theme. The development tools then create a folder for the theme in the NetSuite file cabinet and deploy the customized theme's code. In addition to compiling the application, this command creates the .nsdeploy file, if it does not already exist. gulp theme:deploy --preservemanifest This performs the same action as gulp theme:deploy, but it does not update the manifest. Use this command to deploy your theme if you have made any manual changes to the manifest.json file for the theme. gulp theme:deploy --advanced This command deploys as an update of the current custom theme, but resets the prompts regarding the Vendor Name, Theme Name, Theme Version, Description, and Application. This command also rewrites this information in the theme’s manifest.json file. This command only takes effect on custom themes. gulp theme:deploy --create This command creates a new theme instead of updating the existing theme. gulp theme:deploy --skipcompilation This command deploys the current contents of the DeployDistribution folder without compiling the application. Although the developer tools do not deploy a compiled set of files, the default action is to compile files as a final test of your code. Using this command skips this check. gulp theme:deploy --source templates This command only deploys the HTML template files. gulp theme:deploy --source sass This command only deploys Sass files. gulp theme:deploy --source assets This command only deploys theme asset files. gulp theme:deploy --source skins This command only deploys theme skin preset files. gulp extension:deploy --source <multiple> Separate multiple source deployments by commas to deploy more than one type of source code. For example, gulp extension:deploy --source templates,sass gulp theme:deploy --to This command deploys to NetSuite as usual, but resets the login credentials, rewriting the .nsdeploy file. gulp theme:update-manifest This command updates the theme’s manifest.json file without requiring a deployment. gulp validate This command validates the theme’s manifest.json file and confirms that the file does not list any files that do not exist in the theme folder. SuiteCommerce Site Development Gulp Command Reference for Themes and Extensions Command Description gulp clear This command removes the DeployDistribution and LocalDistribution directories and the .nsdeploy file. gulp This command displays a list of all gulp commands. 43 Extension Developer Gulp Commands Command Description gulp extension:create This command creates an example extension (with one example module) to use as a baseline for development. This command creates all necessary folders to store and maintain your customizations within your top-level extension development directory. gulp extension:create-module This command creates an additional module within your extension. This command prompts you for information about the module you want to create and the extension within which you want to create it. gulp extension:fetch This command downloads the active theme and compiles all theme resources (Sass, HTML, and other assets). This command places theme files in the toplevel extension development directory’s Extras folder. If this is the first time running this command, the development tools create subdirectories for these files. Note: Any downloaded theme files are only provided for testing your extensions locally. You do not customize any theme files in your toplevel extension development directory. If you also choose to continue development on a previously deployed, custom extension, this command also downloads these files, placing them in your Workspace/<EXTENSION_FOLDER>. The extensions must be active using the Manage Extensions wizard in NetSuite. Note: This command does not download published extensions. You cannot customize published content. gulp extension:fetch <arg> This command downloads the files of a specific extension, where <arg> is the name of the extension. This can be helpful if you want to use a previously deployed extension as a baseline for a new one. You can fetch multiple extensions, separated by a comma. For example: gulp extension:fetch --fetch Badges,CartExtension. Note: Extensions must be active to download code or to view them on a local server. gulp extension:local This command compiles your custom extension files into a functional application and places them in a LocalDistibution folder. After compilation, this command starts a local server. This server watches for changes to any extension files. After the server starts, any changes you make to your extension files are automatically recompiled and visible in the browser. gulp extension:local --preservemanifest This performs the same action as gulp extension:local, but it does not update the manifest. Use this command to test your extension locally if you have made any manual changes to the manifest.json file for the extension. SuiteCommerce Site Development Gulp Command Reference for Themes and Extensions Command Description gulp extension:deploy This command compiles your custom extension files into a functional application and places them into a DeployDistribution folder. 44 If you have more than one extension in your top-level development directory, this command prompts you to declare which extension to deploy. If you have never deployed the extension, this command prompts you for information about the extension. The development tools then create a folder for the extension in the NetSuite file cabinet and deploy the customized extension code. In addition to compiling the application, this command creates the .nsdeploy file, if it does not already exist. gulp extension:deploy --preservemanifest This performs the same action as gulp extension:deploy, but it does not update the manifest. Use this command to deploy your extension if you have made any manual changes to the manifest.json file for the extension. gulp extension:deploy --advanced This command deploys an update of the extension, but resets the prompts regarding the Vendor Name, Extension Name, Version, Description, Application, etc. This command also rewrites this information in the extension manifest.json file. gulp extension:deploy --skipcompilation This command deploys the current contents of the DeployDistribution folder without compiling the application. Although the developer tools do not deploy a compiled set of files, the default action is to compile files as a final test of your code. Using this command skips this check. gulp extension:deploy --source configuration This command only compiles and deploys configuration JSON files. gulp extension:deploy --source javascript This command only compiles and deploys JavaScript files. gulp extension:deploy --source ssp- This command only compiles and deploys ssp-libraries. libraries gulp extension:deploy --source services This command only compiles and deploys services. gulp extension:deploy --source sass This command only compiles and deploys Sass files. gulp extension:deploy --source templates This command only compiles and deploys HTML files. gulp extension:deploy --source assets This command only compiles and deploys assets. gulp extension:deploy --source <multiple> Separate multiple source deployments by commas to deploy more than one type of source code. For example, gulp extension:deploy --source templates,sass gulp extension:update-manifest This command updates the extension’s manifest.json file without requiring a deployment. gulp validate This command validates the theme’s manifest.json file and confirms that the file does not list any files that do not exist in the theme folder. gulp clear This command removes the DeployDistribution and LocalDistribution directories and the .nsdeploy file. gulp This command displays a list of all gulp commands. SuiteCommerce Site Development Theme Development Files and Folders 45 Theme Development Files and Folders Applies to: SuiteCommerce | SuiteCommerce Advanced | SuiteCommerce InStore This section describes the various files and folders included in your top-level theme development directory. You create this when you extract the zip file containing the theme developer tools. Note: Some of the files and folders listed herein do not appear until you run one or more Gulp.js commands. The following sections point this out where applicable. The Theme Development Directory The top-level theme development directory contains the following files/folders. Some of the files/folders listed below do not appear until after you run your customizations to a local server or deploy them to NetSuite. You name this top-level directory when you extract the theme development tools. File/Folder Description DeployDistribution/ Created when you run the gulp theme:deploy command, this directory contains all of the files associated with the compiled application. After compilation, Gulp.js deploys the contents of this directory to your NetSuite file cabinet. Do not manually edit the files in this directory. gulp/ This directory contains all of the files required by Gulp.js. Do not manually edit the files in this directory. LocalDistribution/ Created when you run the gulp theme:local command, this directory contains all of the files associated with the compiled application used by the local server. When you run gulp theme:local, Gulp.js deploys the contents of this directory to the local Node.js server. Do not manually edit the files in this directory. node_modules Created when you run the npm install command, this directory stores the dependencies and other files required by the development tools. Do not manually edit this file. ns_npm_repository Do not manually edit this file. Workspace/ Created when you initially run the gulp theme:fetch command, this directory maintains all downloaded and customized theme and extension HTML, Sass, and asset files. This is the directory where you maintain all of your theme and extension customizations. See The Theme Workspace for detailed information on the contents of this directory. .jshintrc Do not manually edit this file. distro.json Do not manually edit this file. gulpfile.js This file contains all the JavaScript code necessary to run Gulp.js. Do not manually edit this file. javascript-libs.js Do not manually edit this file. package.json This file maintains dependencies required to operate the theme development tools. Do not manually edit this file. version.txt This file maintains versioning information for SuiteCommerce or SCA. SuiteCommerce Site Development Theme Development Files and Folders 46 Do not manually edit this file. The Theme Workspace The Workspace directory is the location within your top-level theme development directory where you create themes. This directory contains a subdirectory for the downloaded theme and an Extras directory to maintain all extension-related source files. When you run the gulp theme:fetch command, the development tools delete all Workspace directory subfolders and download the active theme and extension source files, building a new Workspace environment each time. <TopLevelDevelopmentDirectory>/ Workspace/ Extras/ <THEME_DIRECTORY>/ The Theme Directory When you access your theme development directory and run the gulp theme:fetch command, the development tools create a subdirectory to store the source files for the active theme. The name of this directory matches the name of the theme that is active when you run the gulp theme:fetch command. Perform all theme customizations and template overrides here. The theme directory contains the following files or folders: File/Folder Description assets/ This directory maintains any images or fonts associated with the theme. These assets include fonts, logos, icons, and other images related to your site that are not managed by NetSuite. This is also the location where you save any new assets you introduce as part of your theme customizations or extension overrides. Modules/ This directory contains individual modules as subdirectories associated with the theme. Each module defines a specific area of functionality (feature or utility) for your site and contains Template and Sass files in respective subdirectories. You customize these Sass and HTML files directly. Overrides/ This directory contains any HTML and Sass associated with all extensions that were active when you ran the gulp theme:fetch command. This directory is initially empty, but its structure matches that of the files in the Extras directory. If you are customizing HTML and Sass files associated with an extension, you place copies of those files here to maintain your overrides. See Override Active Extension Files for more details. Skins/ This directory contains any skin preset files for your theme. For more information on skins, see Create Skins for more details. manifest.json This file maintains all extensible resources for the theme and declares any overrides for extension customizations. The development tools automatically edit this file to include any necessary overrides when you run the gulp theme:deploy command. For more information on this file, see Theme Manifest. Example: Your domain has an active theme, SuiteCommerceBaseTheme. You run the gulp theme:fetch command and specify your domain. The development tools clear any existing Workspace directory contents and download all theme-related HTML, Sass, and asset files into the SuiteCommerceBaseTheme directory. This is your workspace for creating and editing your theme. If the SuiteCommerce Site Development Theme Development Files and Folders 47 theme you download includes any previously deployed overrides, the development tools place them in the Overrides directory. In this example, your theme workspace structure should look similar to: <TopLevelDevelopmentDirectory>/ Workspace/ SuiteCommerceBaseTheme/ assets/ img/ fonts/ Modules/ AddressModule@1.0.0/ Sass/ Templates/ Overrides/ manifest.json The Extras Directory (Theme Development) When you access your theme development directory, you The ../Workspace/Extras/Extensions directory contains subdirectories for each extension active when downloaded using the gulp theme:fetch command. Each extension subdirectory contains the following files or folders: Important: At this time, you can only create your own themes. Therefore, do not manually edit or remove files found in the Extras/Extensions directory. You can only customize extension-related HTML and Sass files using the Override method. See Override Active Extension Files. File/Folder Description assets/ This directory maintains any images or fonts associated with the associated extension. These assets include fonts, logos, icons, and other images related to your site that are not managed by NetSuite. Modules/ This directory contains a module folder that maintains all HTML templates and Sass associated with the extension. These files are provided here for your reference only. manifest.json This file lists all extension-related JavaScript, SSP libraries, configuration, HTML templates, Sass, and assets related to the active extensions downloaded when you ran the gulp theme:fetch command. For more information on this file, see Theme Manifest. Do not manually edit this file. If your domain does not have any active extensions when you run the gulp theme:fetch command, or an active extension does not contain any Sass, HTML, or assets, the development tools do not create a folder for that extension. Note: The Extras subdirectory also contains an application_manifest.json file. This file confirms that you have a valid SSP Application version that supports the Themes and Extensions. Do not move, delete, or edit this file. Extension Development Files and Folders Applies to: SuiteCommerce | SuiteCommerce Advanced | SuiteCommerce InStore This section describes the various files and folders included in your top-level extensions development directory. You create this when you extract the zip file containing the extension developer tools. SuiteCommerce Site Development Extension Development Files and Folders 48 Note: Some of the files and folders listed herein do not appear until you run one or more Gulp.js commands. The following sections point this out where applicable. However, for a full list of Gulp.js commands, see Gulp Command Reference for Themes and Extensions. The Top-Level Extension Development Directory Your top-level extensions development directory contains the files/folders listed in the following table. Some of the files/folders listed do not appear until after you run your customizations to a local server or deploy them to NetSuite. You name this top-level directory when you extract the extension development tools. Important: Do not manually edit any of the individual files in the top-level extensions development directory. File/Folder Description DeployDistribution/ Created the first time you run the gulp extension:deploy command, this directory contains all of the files associated with the compiled application. After compilation, Gulp.js deploys the contents of this directory to your NetSuite file cabinet. Do not manually edit the files in this directory. gulp/ Created when you extract the extension developer tools, this directory contains all of the files required by Gulp.js. Do not manually edit the files in this directory. LocalDistribution/ Created the first time you run the gulp extension:local command, this directory contains all of the files associated with the compiled application used by the local server. When you run gulp extension:local, Gulp.js deploys the contents of this directory to the local Node.js server. Do not manually edit the files in this directory. node_modules Created when you run the npm install command, this directory stores the dependencies and other files required by the development tools. ns_npm_repository Created when you install the extension developer tools, this folder contains important files for the NPM package manager. Workspace/ Created the first time you run the gulp extension:fetch or gulp extension:create command, this directory maintains all of your extension files under development. This directory also includes an Extras/ folder to maintain theme files for local testing. See The Extensions Workspace Directory for detailed information on the contents of this directory. gulpfile.js This file contains all the JavaScript code necessary to run Gulp.js. package.json This file maintains dependencies required to operate the theme development tools. The Extensions Workspace Directory The Workspace directory resides in your top-level extensions development directory. This directory contains a subdirectory for each extension you are creating plus an Extras directory to store the active theme source files. <Top-LevelDevelopmentDirectory>/ Workspace/ Extras/ <EXTENSION_DIRECTORY>/ SuiteCommerce Site Development Extension Development Files and Folders 49 The Extension Directory When you run the gulp extension:create command, the developer tools create the Workspace directory (unless it already exists) and places a basic extension with source files for you to begin creating your own extension. Each extension directory contains the following files or folders: File/Folder Description assets/ This directory maintains any images or fonts associated with the extension. These assets include fonts, logos, icons, and other images related to your site that are not managed by NetSuite. Modules/ This directory contains individual modules as subdirectories associated with the extension. Each module defines a specific area of functionality (feature or utility) for your site and contains the JavaScript, SuiteScript, Configuration, Templates, and Sass files for your extension. manifest.json This file maintains all extensible resources for the extension. The development tools automatically edit this file to include any necessary overrides when you run the gulp extension:deploy command. For more information on this file, see Extension Manifest. Example You run the gulp extension:create command from your top-level extension development directory. During this task, you name your extension MyCoolExtension and choose to create all options for extension files (templates, sass, configuration, etc.). You also choose not to create a Custom Content Type (CCT). After this command is complete, your Workspace directory contains the following: <TopLevelDevelopmentDirectory>/ Workspace/ MyCoolExtension/ assets/ fonts/ img/ services/ MyCoolModule.Service.ss Modules/ MyCoolModule/ Configuration/ JavaScript/ Sass/ SuiteScript/ SuiteScript2/ Templates/ manifest.json The MyCoolModule directory contains an example file for each files type. You use these files as an example to build your new extension. For example, the JavaScript folder contains JavaScript collection, model, router, view, and entry point files. The Extras Directory When you run the gulp extension:fetch command, the developer tools create the Workspace directory (unless it already exists) and downloads the source files for the active theme. These files are provided for reference during local testing only. Do not move, delete, add, or edit the files in the Extras subdirectory. The Extras subdirectory contains the following files or folders: SuiteCommerce Site Development Extension Development Files and Folders File/Folder Description assets/ This directory maintains any images or fonts associated with the active theme. These assets include fonts, logos, icons, and other images related to your site that are not managed by NetSuite. Modules/ This directory contains a module folder that maintains all HTML templates and Sass associated with the theme. These files are provided here for your reference only. Overrides/ This directory contains files associated with overrides for the theme. See Override Active Extension Files to learn how to use the Override method to customize HTML and Sass files related to extensions. manifest.json This file lists all extension-related HTML templates, Sass, and assets related to the active theme downloaded when you ran the gulp extension:fetch command. Do not manually edit this file. Note: The Extras subdirectory also contains an application_manifest.json file. This file confirms that you have a valid SSP Application version that supports the Themes and Extensions. Do not move, delete, or edit this file. Example You run the gulp extension:fetch command. Your domain has an active theme, ActiveTheme1, and an active extension, MyCoolExtension. You run the gulp theme:fetch command and specify your domain. The extension developer tools download all theme-related HTML, Sass, and asset files into the Exrtras/ActiveTheme1/ directory. In this example, your Workspace directory structure should look similar to: <TopLevelDevelopmentDirectory>/ Workspace/ Extras/ ActiveTheme1/ assets/ Modules/ Overrides/ manifest.json MyCoolExtension/ Mixed Domains in a Local Server Applies to: SuiteCommerce | SuiteCommerce Advanced When redirecting between domains while testing on your local server, the default behavior is for the application to load the production version of the initial page in the new domain. For example, suppose you start in the local version of the Shopping domain using the shoppinglocal.ssp URL. On login, you are redirected to the production version of the Checkout domain at the myaccount.ssp URL. To return to the local version of that domain you must manually edit the URL. Change: https://checkout.netsuite.com/c.xxxxxxx/sca-dev-denali/my_account.ssp?n=3 To: https://checkout.netsuite.com/c.xxxxxxx/sca-dev-denali/my_account-local.ssp?n=3 Also, in some browsers, when you manually update this URL you may encounter blank page loads with console errors similar to the following: SuiteCommerce Site Development 50 Mixed Domains in a Local Server 51 Mixed Content: The page at 'https://checkout.netsuite.com/c.xxxxxx/sca-dev-denali/my_account-local.ssp?n=3' was loaded over HTTPS, but requested an insecure stylesheet 'http://localhost:7777/css/myaccount.css'. This request has been blocked; the content must be served over HTTPS. For example, Chrome returns this error to protect you from a site that is not secure. If this happens in Chrome, in the address bar you will see a shield. Click on the shield and select Load unsafe scripts. The page then loads normally. Note: You can also launch the Chrome browser with the flag --allow-running-insecure-content or you can install the certificates in your local web server. Secure HTTP (HTTPS) with the Local Server Applies to: SuiteCommerce | SuiteCommerce Advanced The gulp local command starts two instances of the local server at the following URLs: ■ http://localhost:7777 ■ https://localhost:7778 The instance running at port 7778 provides a secure domain using HTTPS. This enables you to test the application using secure domains. However, before using secure domains on the local server, you must perform the following: ■ Modify the distro.json. ■ Modify the root URL of the shopping-local.ssp file. ■ Generate the required SSL certificates and private keys. ■ Configure the KEYPEM and CERTPEM environment variables. ■ Install the certificates on your system. Generate SSL Certificates and Private Keys To access a secure domain via HTTPS when running the local server, you must use an SSL certificate and a private key. Since the local server is intended for testing and not a production environment, you can create a self-signed certificate locally and do not need to use a third-party certificate provider. To generate an SSL Certificate and a Private Key 1. Download and Install OpenSSL. 2. Generate an RSA private key. a. Run the following command: openssl genrsa -des3 -out ca.key 1024 b. Enter and confirm a password for the certificate. You will use this password in the remaining procedures for creating a certificate and private key. This command outputs the RSA private key in a file called ca.key. 3. Create a new SSL certificate. a. Run the following command: openssl req -new -sha256 -key ca.key -out ca.csr SuiteCommerce Site Development Secure HTTP (HTTPS) with the Local Server 52 This command uses the RSA private key created in the previous step. b. Accept the default value for the localhost field. The other fields are not required to create the certificate used by the local server when running HTTPS. This command outputs the SSL certificate in a file called ca.csr. 4. Create a self-signed certificate: openssl x509 -req -days 3600 -in ca.csr -out ca.crt -signkey ca.key If you are prompted to enter a password, use the password you entered when generating the RSA key. 5. Create a server key: openssl genrsa -des3 -out server.key 1024 This command outputs the server private key to a file called server.key. 6. Create a certificate signing request (CSR): openssl req -new -sha256 -key server.key -out server.csr This command outputs the CSR to a file called server.csr. 7. Remove the password from the server certificate. This step is optional. If you encounter problems with the password, you can remove it from the certificate. a. Copy the server.key file to server.key.org. b. Run the following command to generate a new server.key file that has no password: openssl rsa -in server.key.org -out server.key This command creates a new private key called server.key. The local server uses this file when creating a secure domain. Therefore, you should move it to a permanent location. 8. Create a self-signed server certificate: openssl x509 -req -sha256 -days 3600 -in server.csr -signkey server.key -out server.crt This command creates a new server certificate called server.crt. The local server uses this file when creating a secure domain. Therefore, you should move it to a permanent location. Configure the KEYPEM and CERTPEM Environment Variables After generating a server certificate and private key, you must define environment variables that point to these files. Using the method for setting environment variables for your operating system, create the following: Note: You must set these environment variables before running the local server. KEYPEM <path_to_file>/server.key CERTPEM <path_to_file>/server.crt On Windows, for example, you can set these environment variables as in the following example: set KEYPEM=c:\OpenSSL-Win64\server.key set CERTPEM=c:\OpenSSL-Win64\server.crt SuiteCommerce Site Development Secure HTTP (HTTPS) with the Local Server Install the Generated Certificates After generating the SSL and server certificates, you must enable them to work with your web browser. On Windows, you can use the Certificate Import Wizard. To install generated certificates: 1. Run the server.crt file you generated using OpenSSL. 2. Click Install Certificate. 3. Click Next. 4. Choose Place all certificates in the following store, then click Browse. 5. Choose Trusted Root Certification Authorities, then click OK. 6. Click Next. 7. Verify that your settings are correct, then click Finish. 8. Click Yes to verify that you want to install the certificate on your system. After installing the server certificate, you should repeat these procedures to install the ca.crt file generated in a previous step. Modify the distro.json File To access a secure domain on the local sever, you must ensure that the https object exists in the local object of taskConfig. After adding the https object, add an entry for the HTTPS port, certificate and key. Your distro.json file should look similar to the following: "tasksConfig": { "local": { "http": { "port": 7777 }, "lessSourcemap": false, "jsRequire": true, "https": { "port": 7778, "key": "KEYPEM", "cert": "CERTPEM" } }, ... Note: You must set the key and cert properties as shown above. The local server uses these values to determine the environment variables used to local the certificate and key required to use HTTPS. Modify the Root URL of the Shopping SSP Application To use HTTPS with the local server, you must change the value of the ROOT variable in the shopping SSP application. To modify the root URL of the shopping SSP application: 1. Open the index-local.ssp file. SuiteCommerce Site Development 53 Secure HTTP (HTTPS) with the Local Server This file is located in <SCA_Source_Root>/Modules/suitecommerce/ShoppingApplication@x.y.z/ Internals. 2. Change the value of the ROOT variable: var ROOT = 'https://localhost:7778/' 3. Compile and deploy the application using the following command: gulp deploy Since the above procedure changes a backend file, you must deploy the files to NetSuite. In the process of compiling the application, this command creates the shopping-local.ssp file based on the index-local.ssp file modified above. Access the Local Server Using a Secure URL To access the local server using the local server, you must use the URL of your secure domain. To access the local server using a secure domain: 1. Run the following command: gulp local 2. Access the secure domain of the local server using a URL of the following form: https://checkout.netsuite.com/c.<account_id>/<SSP_application>/shopping-local.ssp For example, your URL should look similar to the following: https://checkout.netsuite.com/c.123456/sca-dev-montblanc/shopping-local.ssp Deploy to a NetSuite Sandbox Applies to: SuiteCommerce | SuiteCommerce Advanced Commerce web stores also enable you to deploy to a sandbox account. See the help topics NetSuite Sandbox and FAQ: NetSuite Sandbox for more information about sandbox accounts. Note: Before deploying to your sandbox account, you should verify that the Commerce bundles are installed. You may also need to delete the .nsdeploy file if you previously deployed to an account other than the sandbox account. Deleting this file enables you to enter the login credentials for the sandbox account. To deploy to a sandbox account: 1. Go to your command line or terminal window. 2. Enter the appropriate command for your environment from the top-level directory of the source files (the same directory used during the tools installation). ■ Theme developer tools: gulp theme:deploy ■ Extension developer tools: gulp extension:deploy ■ Core SuiteCommerce Advanced developer tools: gulp deploy If this is the first time you are deploying, the tools create a sub directory called DeployDistribution. The tools then compile the source files and output them to this directory. SuiteCommerce Site Development 54 Deploy to a NetSuite Sandbox 55 Note: Subsequent deployments only prompt for your NetSuite password. To reset the login information and enter information again, use the gulp deploy --to command to deploy your changes. 3. When prompted, enter the email and password of your sandbox account. Note: The developer tools do not support emails or passwords containing special characters such as + and %. 4. When prompted, select the sandbox account where SuiteCommerce or SuiteCommerce Advanced is installed. 5. When prompted, navigate to Web Site Hosting Files for your Commerce installation: ■ SuiteCommerce: Web Site Hosting Files > Live Hosting Files > SSP Applications > NetSuite Inc. SCS ■ SuiteCommerce Advanced: Web Site Hosting Files > Live Hosting Files > SSP Applications > NetSuite Inc. - SCA <version> Development After you enter your connection setting, the contents of the DeployDistribution folder on your local system are uploaded to the NetSuite file cabinet of your sandbox account. This process may take a few minutes. Wait for the process to complete before proceeding. Deploy to a Custom SSP Application Applies to: SuiteCommerce Advanced During installation of SuiteCommerce Advanced (SCA), the SSP applications included in the SCA bundle are automatically configured in your NetSuite account. Generally, you deploy customizations to the Development SSP application associated with your SCA release, as described in the Deploy to NetSuite topic. SSP Application Support for SuiteScript 2.0 As of the 2019.1 release, SCA supports SuiteScript 2.0. The SSP applications for SCA 2019.1 and later releases include resources to run services implemented using SuiteScript 2.0. These resources can be found in the Development2 and Source2 directories. You can also deploy local files to a custom SSP application. Custom SSP applications enable you to test local cutomizations of SCA on the domain and site you specify. When you create custom SSP applications, NetSuite generates the directory structure in its file cabinet to which you can deploy your local files. Important: If you are implementing the 2019.1 release of SCA or later and want to use custom SSPs for testing, you must create two custom SSP applications. You need one custom application to support the creation and deployment of SuiteScript 1.0 resources and one to support SuiteScript 2.0. In the following procedure, the custom application you create for SuiteScript 2.0 is referred to as SSPv2. To deploy to custom SSP application, complete the following steps: ■ Step 1: Create a Custom SSP Application □ Create a custom SSP application for SuiteScript 1.0 (all implementations of SCA) SuiteCommerce Site Development Deploy to a Custom SSP Application □ Create a custom SSP application for SuiteScript 2.0 (2019.1 and later implementations of SCA) ■ Step 2: Deploy Local Files (all implementations of SCA) ■ Step 3: Configure SSP Applications (all implementations of SCA) Note: Before deploying to a Custom SSP Application, the SCA bundle must be installed in your account. You cannot deploy local files into an account without the bundle installed. Step 1: Create a Custom SSP Application If you are implementing the 2019.1 release of SCA or later and want to use custom SSPs for testing, you must create two custom SSP applications. You need one custom application to support the creation and deployment of SuiteScript 1.0 resources and one to support SuiteScript 2.0. The NetSuite SSP application record defines the folder in the NetSuite file cabinet where website customization assets are stored. If you are unfamiliar with SSP applications in NetSuite, review SSP Application Overview in the NetSuite Help Center before proceeding. Important: If you are updating a site that has been previously deployed to a custom SSP application, you do not need to create a new SSP application. To deploy to the existing SSP application, you need to know the Application Folder and the Application Name. You can find this information on the SSP Application Record for the site you are working on. Create a custom SSP application for SuiteScript 1.0 This procedure applies to all implementations of SCA. 1. Go to Setup > SuiteCommerce Advanced > SSP Applications > New. 2. To create the record for your SuiteScript 1.0 assets, follow the steps outlined in the NetSuite Help topic Create a SuiteScript 1.0 SSP Application Record to provide the following information: ■ If you are implementing SCA 2019.1 or later, when naming your SSP application be sure to append v1 to the end. For example: MyCustomSSPv1 ■ Specify a version of 1.x. ■ Create a new application folder and provide the HTML Hosting Root, Application Publisher, and Application Name for your application. Creating an SSP application results in a directory structure in the NetSuite File Cabinet with the following path: <HTML Hosting Root>: /SSP Applications/<Application Publisher>/<Application Name>. For example, if you specify the following information for the application folder when creating an SSP application: ■ HTML Hosting Root: Live Hosting Files ■ Application Publisher: ProDev ■ Application Name: ProDevSite The resulting directory structure in the NetSuite File Cabinet is: Web Site Hosting Files/Live Hosting Files/SSP Applications/ProDev/ProDevSite SuiteCommerce Site Development 56 Deploy to a Custom SSP Application 57 Create a custom SSP application for SuiteScript 2.0 This procedure applies only to 2019.1 implementations of SCA and later. The NetSuite SSPv2 application record defines the folder in the NetSuite file cabinet where website customization assets that support SuiteScript 2.0 are stored. If you are implementing the 2019.1 release of SCA or later, you must create this additional SSP application for SuiteScript 2.0 assets. 1. In the NetSuite File Cabinet, go to Setup > SuiteCommerce Advanced > SSP Applications > New. 2. To create the record for your SuiteScript 2.0 assets, follow the steps outlined in the NetSuite Help topic Create a SuiteScript 2.0 SSP Application Record to provide the following information: ■ Be sure that the name you assign to the SSP application is the same as the name used for the SuiteScript 1.0 application, but append v2 to the end. For example: MyCustomSSPv2 ■ Specify a version of 2.x. ■ Create a new application folder and provide the same HTML Hosting Root and Application Publisher that you used in Create a custom SSP application for SuiteScript 1.0. Also use the same Application Name, but add the number 2 to the end. For example: ProDevSite2 ■ Be sure the URL root is the same as the root used for the SuiteScript 1.0 application, but append _ss2 to the end. For example, if the URL root for your SuiteScript 1.0 application is ProDev, the root for your SuiteScript 2.0 application should be ProDev_ss2. Creating an SSP application with a version of 2.x results in a directory structure in the NetSuite File Cabinet with the following path: <HTML Hosting Root>: /SSP Applications/<Application Publisher>/ <Application Name>. For example, if you specify the following information for the application folder when creating an SSP application with a version of 2.x: ■ HTML Hosting Root: Live Hosting Files ■ Application Publisher: ProDev ■ Application Name: ProDevSite2 The resulting directory structure in the NetSuite File Cabinet is: Web Site Hosting Files/Live Hosting Files/SSP Applications/ProDev/ProDevSite2 Step 2: Deploy Local Files After creating your SSP application, use the core SCA developer tools to deploy local files to your NetSuite file cabinet. You need the following information to complete these steps: ■ Your NetSuite username and password Note: The developer tools do not support emails or passwords containing special characters such as + and %. ■ Details from the SSP application record created in Create a custom SSP application for SuiteScript 1.0: HTML Hosting Root, Application Publisher, Application Name To deploy local files using Gulp: 1. Return to your command line or terminal window. 2. From the SCA source directory (the directory that contains the package.json file), enter the following command. gulp deploy SuiteCommerce Site Development Deploy to a Custom SSP Application Note: If this is the first time you are running gulp deploy in this directory, this command creates one or more deploy distribution directories depending on your implementation. 3. When prompted, enter your NetSuite email and password. Note: The developer tools do not support emails or passwords containing special characters such as + and %. 4. When prompted, select the NetSuite account where SuiteCommerce Advanced is installed. Important: You must log in using the SCDeployer role to access your NetSuite account. Failure to use this role may result in an error. See Developer Tools Roles and Permissions for instructions on setting up this role. 5. When prompted, provide the following details from your SSP application record: Tip: These values correspond to the path to your SSP application in the NetSuite File Cabinet: <HTML Hosting Root>: /SSP Applications/<Application Publisher>/<Application Name> ■ Hosting Files folder: This is the HTML Hosting Root of your SSP application. ■ Application Publisher: This is the Publisher of your SSP application. ■ SSP Application: This is the Name of your SSP application. After all of the connection settings are entered, files from your local system are pushed to the NetSuite file cabinet. This process may take a few minutes. Wait for the process to complete before proceeding. Note: The first time you run the gulp deploy command, the connection settings are stored in the .nsdeploy file in the root directory of your source SCA files. During subsequent deployments, only the login credentials are required. If you need to change the SSP application you are deploying to, you can manually edit the .nsdeploy file with the updated information. For details, see Changing Your Connection Information. Also, during the initial deployment to NetSuite, the Gulp.js commands create a manifest file within the NetSuite file cabinet. This file contains the list of files uploaded and a hash of its content. On subsequent deployments, the Gulp.js commands use the manifest file to determine new or changed files. Only those files are updated during deployment to the NetSuite file cabinet. Step 3: Configure SSP Applications After completing the preceding steps, all necessary files should be available to the SSP applications within NetSuite. In this final step, complete some configuration tasks to enable your website to use the customized SCA application you uploaded. 1. Go to Setup > SuiteCommerce Advanced > SSP Applications and then click Edit next to the SSP application created in Create a custom SSP application for SuiteScript 1.0. 2. In the Libraries subtab under Scripts, click Add. 3. Find and add the ssp_libraries.js and ssp_libraries_ext.js files to the libraries for the SSP application. These files were pushed to the NetSuite file cabinet with the gulp deploy command. When you add these files to the SSP library, they are stored in the root directory of your SSP application at <HTML Hosting Root>:/SSP Applications/<Application Publisher>/<Application Name>. SuiteCommerce Site Development 58 Deploy to a Custom SSP Application 59 Note: Depending on the number of files in your file cabinet you may need to scroll through a long list. However, do not rely on the search. The files available may not be refreshed, resulting in a no matches found error even though the files do exist. 4. In the Touch Points tab, define the touch points for this SSP application. Touch points are the entry points for your web store. For each touch point defined here, your website links to an SSP application page. a. In the Name field, select the desired touch point. b. In the Entry Page field, select the .ssp file that should be the starting point for this touch point. c. Click Add. For example, if you want your web store to use the Shopping application when a user goes to your Home page, select the View Homepage Touch Point and set the Entry page as the shopping.ssp file. 5. Click Save on the record. You are returned to the list of available SSP applications. 6. Link the SSP application created in Create a custom SSP application for SuiteScript 1.0 to your domain. a. Click View next to your SSPv1 application. b. Click Link to Domain. c. In the Domain dropdown field, select the domain you want to link this application to. d. Click Save. 7. If you are implementing SCA 2019.1 or later and are using a single domain for shopping and checkout, follow these steps to deploy the SSP application created in Create a custom SSP application for SuiteScript 2.0: a. Click View next to your SSPv2 application. b. Click Deploy to Domain. c. In the Domain dropdown field, select the domain for your site. d. Click Save. 8. If you are implementing SCA 2019.1 or later and are not using a single domain for shopping and checkout, follow these steps to deploy the SSP application created in Create a custom SSP application for SuiteScript 2.0: a. Click View next to your SSPv2 application. b. Click Deploy to Site. c. In the Deploy to All Shopping Domains on Site dropdown field, select the site associated with your shopping domains. d. In the Deploy to Checkout Domain on Site field, select the site associated with your checkout domain. Note: If you want to deploy the SSP application to the checkout domain of one site and the shopping domains of another, you can select different site names from the lists. Alternatively, if you want to deploy to just the checkout domain or just shopping domains, select - Do Not Deploy - for the domain type to which you do not want to deploy. e. Click Save. SuiteCommerce Site Development Deploy to a Custom SSP Application 60 After completing the steps in this procedure, you can view the site by navigating to the domain defined for that site. Troubleshooting the Developer Tools Applies to: SuiteCommerce | SuiteCommerce Advanced | SuiteCommerce InStore The following are known problems or errors that you may encounter when installing or running the developer tools: startDeploy Errored: Cannot Read Property 'files' of Undefined at deployData.forEach.deploy The gulp theme:deploy and gulp extension:deploy commands use SuiteScript Restlet service requests to upload your theme and extension development files to the NetSuite file cabinet. And, SuiteScript’s governance model limits the number of units each Restlet request can use. For more information, see the help topic SuiteScript Governance. The chunk_size property in the <Top-LevelDevelopmentDirectory/gulp/config/config.json file controls how many files are uploaded per Restlet request. Each Restlet request has a fixed number of units that it can consume per the SuiteScript governance model. The number of units required to upload each file to the NetSuite file cabinet varies based on the number of nested folders within your theme or extension development files. More complex directory structures consume more units. If you receive this error for a theme or extension that has a complex directory structure, reducing the value of the chunk_size property from the default setting of 80 may resolve the issue. Note: You can also adjust the chunk_size property if you need to speed up deployment. Increasing the number of files uploaded per request should speed up the process because the deployment will require fewer requests to the Restlet. Error Messages When Running the Developer Tools You may encounter the following errors when you deploy themes, extensions, and other customizations to NetSuite. They may occur when NetSuite runs with two-factor authentication and you do not properly sign in with the SCDeployer role: Error INVALID_LOGIN_ATTEMPT Invalid login attempt. This error occurs when deploying or fetching using a role that requires 2FA. To fix this error, log into NetSuite using the developer tools and choose the SCDeployer role. Include the ––to parameter to any fetch or deploy command to trigger the developer tols to prompt you for new login information. Error INSUFFICIENT_PERMISSION You do not have privileges to view this page This error occurs if the SCDeployer role is added to the Employee Record, but the Audience in the Restlet Script Deployment is not added correctly for the role. SuiteCommerce Site Development Troubleshooting the Developer Tools 61 See Edit Script Deployment Records for more information on setting this up correctly. Error When Running Gulp.js Commands When running gulp with an unsupported version of Node.js you may encounter a Sass-related error similar to the following: gyp ERR! build error gyp ERR! stack Error: `make` failed with exit code: 2 gyp ERR! stack at ChildProcess.onExit (/home/sg/netsuite/ml/node_modules/gulp-sass/node_modules/node-sass/node_modules/pangyp/lib/build.js:272:23) gyp ERR! stack at emitTwo (events.js:87:13) gyp ERR! stack at ChildProcess.emit (events.js:172:7) gyp ERR! stack at Process.ChildProcess._handle.onexit (internal/child_process.js:200:12) gyp ERR! System Linux 3.13.0-37-generic gyp ERR! command "/usr/local/bin/node" "/home/sg/netsuite/ml/node_modules/gulp-sass/node_modules/node-sass/node_modules/pangyp/bin/node-gyp" "rebuild" gyp ERR! cwd /home/sg/netsuite/ml/node_modules/gulp-sass/node_modules/node-sass gyp ERR! node -v v4.0.0 gyp ERR! pangyp -v v2.3.2 gyp ERR! not ok Build failed Resolution: Ensure that you are using Node.js version 0.12.x or older. Gulp.js Version Mismatch When running gulp, you may see a warning message related to a version mismatch. This is due to a mismatch between the version installed globally on your system and the version used by the developer tools. Resolution: This warning is expected and does not cause problems with the developer tools. Warning Messages Related to GIT This error is caused by the Sass compiler which expects a GIT server to be installed. Resolution: This warning is expected and does not cause problems with the developer tools. ENOSPC Error When Running Local Server On UNIX systems, the gulp watch command (used when running a local server) may return this exception. This is caused when the gulp process exceeds the limit of files that can be watched by the system. Resolution: Enter the following command to resolve this issue: echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p EMFILE Error When Running a Local Server On UNIX systems, the gulp local command may return this exception if the gulp process exceeds the limit of files that can simultaneously be opened. SuiteCommerce Site Development Troubleshooting the Developer Tools 62 Resolution: Enter the following command to increase the system limit on the number of files that can simultaneously be opened. ulimit -n 2048 Sass Compilation Errors when Running Gulp Applies to: SuiteCommerce Advanced This information refers to the Mont Blanc release of SuiteCommerce Advanced and later. Changes to the developer tools source code may be required to mitigate errors in Sass compilation when deploying. SCA uses gulp-sass for compiling .scss files. Node-sass (v3.5), which is a dependency of gulp-sass, has caused some Sass code that previously compiled fine to throw fatal errors, particularly in Bootstrap. These errors are returned when running the gulp local command to start your local server or when deploying with gulp deploy. The errors returned begin as follows: formatted Error: You may not @extend an outer selector form within @media you may only @extend selectors within the same directive. … [etc] To correct the compilation errors: 1. Open the command line in the project <Source Code> directory. 2. Execute the following commands to remove the 3.5 dependency and install the expected version. npm cache clear npm uninstall gulp-sass node-sass npm config set save-exact true npm install --save node-sass@3.4.1 gulp-sass@2.1.0 Note: This will modify your package.json. Preserve these changes. 3. Run gulp local to validate that the error is resolved. If you have also installed gulp-sass globally, you might need to uninstall the globals. To uninstall gulp-sass globals: 1. Open the command line in the top-level directory of your Mont Blanc source code. 2. If you are a Windows user, execute the following command as either Administrator or as a User: npm uninstall -g node-sass gulp-sass 3. If you are a Linux / Mac user, execute the following command as Administrator: npm uninstall -g node-sass gulp-sass sudo npm uninstall -g node-sass gulp-sass Source Code Error When Running Gulp This information refers to the Mont Blanc release of SuiteCommerce Advanced or later. SuiteCommerce Site Development Troubleshooting the Developer Tools 63 When deploying source files, you might encounter the following error: SOURCE CODE ERROR. Error: You may not @extend an outer selector from within @media. You may only @extend selectors within the same directive. If this occurs, a mismatch of node-sass versions exists between the package.json files located in the toplevel directory and the node_modules/gulp-sass directory. To fix this error, perform the following. To correct the Source Code Error: 1. Open the command line in the top-level directory of your source code. 2. Execute the following commands: Windows Users npm npm npm npm npm npm npm install -g npm cache clear uninstall gulp-sass uninstall node-sass config set save-exact true install node-sass@3.4.1 --save install --save gulp-sass@2.1.0 Linux/Mac Users sudo npm install -g npm npm cache clear npm uninstall gulp-sass npm uninstall node-sass npm config set save-exact true npm install node-sass@3.4.1 --save npm install --save gulp-sass@2.1.0 Note: This modifies the package.json file. Preserve these changes. 3. Run gulp local to validate that the error is resolved. If you have also installed gulp-sass globally, you might need to uninstall the globals. To uninstall gulp-sass globals: 1. Open the command line in the top-level directory of your source code. 2. If you are a Windows user, execute the following command as either Administrator or as a User: npm uninstall -g node-sass gulp-sass 3. If you are a Linux / Mac user, execute the following command as Administrator: npm uninstall -g node-sass gulp-sass sudo npm uninstall -g node-sass gulp-sass SuiteCommerce Site Development Overview 64 Overview Applies to: SuiteCommerce | SuiteCommerce Advanced Commerce websites let you configure common properties and modify application behavior for a specified domain using the NetSuite user interface rather than by customizing source code. The SuiteCommerce Configuration record feature provides this capability and is installed with the SuiteCommerce Configuration bundle. You can: ■ Configure properties for a domain ■ Read configuration file types information ■ Browse the site configuration properties reference section ■ Configure and maintain Site Management Tools See the following topics for more information: ■ Configure Properties – This section explains how to configure properties for a domain and how to copy a SuiteCommerce configuration record. ■ Configuration Properties Reference – This section contains a list of all the configuration properties supported by SuiteCommerce. Properties are grouped by functionality based on how they appear in the Configuration record, listed alphabetically by tab and subtab. ■ Configuration File Types – This section explains the different configuration files you may encounter when implementing SuiteCommerce. The types of files and their purpose differ depending on the version of SuiteCommerce you are implementing. ■ Site Management Tools Configuration – This section contains information about how to configure and maintain Site Management Tools. SuiteCommerce Site Development Configure Properties 65 Configure Properties Applies to: SuiteCommerce | SuiteCommerce Advanced These topics explain how to configure your Commerce web store using the SuiteCommerce Configuration record, which is available for SuiteCommerce web stores and the Vinson release of SCA and later. For these implementations, configuration requires the SuiteCommerce Configuration bundle. See the help topic Install Your Commerce Web Store Applications for more information. After installation, your NetSuite account has access to the SuiteCommerce Configuration record. Note: To configure properties for SuiteCommerce Advanced sites implementing the Mont Blanc release or Denali, you must extend source JavaScript files. For details, see Customize and Extend Core SuiteCommerce Advanced Modules. This topic explains how to: ■ Configure Properties for a Domain ■ Copy a SuiteCommerce Configuration Record Important: If you are using SuiteCommerce Advanced (SCA) and migrating to a later release from Denali or Mont Blanc, you can copy previous configuration files and include them in the Vinson JavaScript files directly. If doing so, you do not need to install the SuiteCommerce Configuration bundle. These existing configuration files take priority over the SuiteCommerce Configuration record. However, if installing Vinson release or later as your initial SCA installation, you must install the SuiteCommerce Configuration bundle to configure your site. Note: Before configuring a Commerce web store, ensure that you have created a website and domain for your NetSuite account. See and Set Up Domains for Web Stores for more information. Configure Properties for a Domain Use the SuiteCommerce Configuration record when you want to change properties related to your domain. To configure properties for a domain: 1. Go to Setup > SuiteCommerce Advanced > Configuration. 2. Select the site that you want to configure from the Select Website list. 3. Select the specific domain that you want to configure from the Select Domain list. 4. Click Continue. 5. Configure properties for the associated domain by clicking the tab and subtab of the feature you want to configure. See Configuration Properties Reference for details. 6. Save the record. SuiteCommerce Site Development Copy a SuiteCommerce Configuration Record 66 Important: Saving changes to the SuiteCommerce Configuration record creates a custom record for the selected domain. To configure multiple domains, you must save a SuiteCommerce Configuration record for each domain individually. You can also copy the configuration of one domain (the origin domain) to another (the destination domain) by using the Copy Configuration feature. See Copy a SuiteCommerce Configuration Record. Important: The SuiteCommerce Configuration record supports valid JSON data (data that is either a string, a number, a boolean, an object, an array, or null). The Configuration Properties Reference explains the type of data expected for each property. Note: If your domain is mapped to a CDN, any changes made to the Shopping Application using the SuiteCommerce Configuration record take approximately five minutes to take effect. This delay occurs because the configuration information from the record is published to the sc.shopping.environment.ssp file, which has a five-minute CDN cache by default. Copy a SuiteCommerce Configuration Record Use the Copy Configuration function to copy a SuiteCommerce Configuration record from one domain to another. Common scenarios where this function is useful include: ■ When you move a site from staging to production ■ When you move from one SCA release to another Note: The two domains do not have to be on the same release of SCA. For example, you can copy a Kilimanjaro Configuration record from one domain to another Kilimanjaro domain or to an Aconcagua domain. Since it is common for later versions of SCA to have fields that do not exist in previous releases, the tool copies the values of all fields that are common between the two releases and uses default values for the additional fields. Using the Copy Configuration function, you select the origin domain, select the destination domain, then click Copy Configuration. In the procedure below: ■ Origin Website/Domain refers to the selection of the source configuration record. The tool copies the configuration record values from this selected website/domain. The values in this record are not changed. ■ Destination Website/Domain refers to the selection of the configuration record you are overwriting. The tool populates the field values from the origin configuration record into this destination configuration record. To copy a SuiteCommerce Configuration record: Important: This procedure overwrites the destination domain configuration record with the content of the origin domain configuration record. Copy to a test domain (especially if you are copying from a Sandbox domain) prior to copying to a production domain and ensure that the configuration values being copied align with your configuration objectives for the destination domain. 1. Go to Setup > SuiteCommerce Advanced > Configuration. SuiteCommerce Site Development Copy a SuiteCommerce Configuration Record 67 2. Click Copy Configuration. 3. Select the origin website from the Origin Website list. 4. Select the origin domain from the Origin Domain list. 5. Select the destination site from the Destination Website list. 6. Select the destination domain from the Destination Domain list 7. Click Copy Configuration. 8. Optional: To change any of the values in the destination SuiteCommerce Configuration record, see: Configure Properties for a Domain. Note: The Copy Configuration function is a part of the SuiteCommerce Configuration bundle. SuiteCommerce Site Development Configuration Properties Reference 68 Configuration Properties Reference Applies to: SuiteCommerce | SuiteCommerce Advanced This section contains a list of all the configuration properties supported by Commerce web stores. In this section, properties are grouped by functionality based on how they appear in the Configuration record, listed alphabetically by tab and subtab. ■ Advanced Tab ■ Checkout Tab ■ Integrations Tab ■ Layout Tab ■ Legacy Tab ■ Multi-Domain Tab ■ My Account Tab ■ Search Tab ■ Shopping Tab ■ Shopping Catalog Tab ■ Store Locator Tab Note: SuiteCommerce Configuration is available as a separate bundle and requires SuiteCommerce or SuiteCommerce Advanced (Vinson release or later). If you do not have the SuiteCommerce Configuration bundle installed, this reference still applies to configuration properties available in your implementation. Each property in this reference includes a brief description of the property plus the following information. In many cases, this reference provides links to topics with detailed information. ■ ID – the name of the property in the JavaScript and JSON configuration files. This value must only contain alphanumeric characters and periods. No special characters. In some cases, the ID differs in pre-Vinson implementations. ■ UI Location – the tab and subtab location in the Configuration record's user interface. This is where you configure the property in Vinson implementations and later of SuiteCommerce Advanced and in SuiteCommerce. ■ Configuration file (pre-Vinson) – the JavaScript file where you configure the property in pre-Vinson implementations of SuiteCommerce Advanced. This only applies to pre-Vinson implementations of SuiteCommerce Advanced. Advanced Tab Applies to: SuiteCommerce | SuiteCommerce Advanced The settings on this tab let you configure advanced properties for your Commerce web store. This tab includes configurable properties grouped in the following subtabs: ■ Backend Subtab ■ Cache Subtab ■ Custom Fields Subtab ■ Filter Site Subtab SuiteCommerce Site Development Advanced Tab 69 ■ Favicon Path Subtab ■ Image Resize Subtab ■ Pagination Subtab ■ Search Results Subtab ■ Security Subtab Backend Subtab Applies to: SuiteCommerce | SuiteCommerce Advanced These settings configure SuiteScript properties. You can configure a variety of objects server-side. Among other things, modifying these objects can often improve performance of your website by restricting search results. nlapiSearchRecord Results Per Page This integer specifies the default number of search results displayed per page. Any Commerce feature that displays search results uses this value by default. ID suitescriptResultsPerPage UI Location Advanced > Backend JSON file SuiteScript.json Configuration file (pre-Vinson) Configuration.js Items Fields Advanced Name This string sets the Field Set to be used when using the Item Search API to return item details. By default, this is set to order. If you are using a different Field Set name, you must define that Field Set name here. Using a different Field Set name for each application can improve site performance. For each application, only those details required are returned for the pages specific to that implementation. For example, in the Shopping item details page, you may want to display a different set of fields than when your customer is in the My Account pages. In this case you can define two Field Sets: details to be used in ShopFlow and myDetails to be used in the My Account pages. More Information: Prepare the Web Site Setup Record ID fieldKeys.itemsFieldsAdvancedName UI Location Advanced > Backend JSON file SuiteScript.json Configuration file (pre-Vinson) Configuration.js Shopping’s Order This array defines the keys of the Shopping application’s order record. For example: shipaddress, summary, promocodes etc. To maximize performance, limit the set to only those fields required for your implementation. SuiteCommerce Site Development Advanced Tab ID orderShoppingFieldKeys.keys UI Location Advanced > Backend ID (pre-Vinson) order_shopping_field_keys Configuration file (pre-Vinson) Configuration.js 70 Shopping’s Order Items This array defines the item fields returned by the Commerce API within the Shopping application. ID orderShoppingFieldKeys.items UI Location Advanced > Backend ID (pre-Vinson) order_shopping_field_keys.items Configuration file (pre-Vinson) Configuration.js Checkout’s Order This array defines the keys of the Checkout application’s order record. For example: shipaddress, summary, promocodes etc. ID orderCheckoutFieldKeys.keys UI Location Advanced > Backend ID (pre-Vinson) order_checkout_field_keys Configuration file (pre-Vinson) Configuration.js Checkout’s Order Items This array defines the item fields returned by the Commerce API within the Checkout application. ID orderCheckoutFieldKeys.items UI Location Advanced > Backend ID (pre-Vinson) order_checkout_field_keys.items Configuration file (pre-Vinson) Configuration.js Item Fields Standard This array defines the set of fields to be returned by the Commerce API. To optimize performance, limit the set included here to only those fields required for your website. Also, use this object to ensure that custom item fields in your account are included in the Item Search API results. Add the custom field name to the list. ID SuiteCommerce Site Development fieldKeys.itemsFieldsStandardKeys Advanced Tab UI Location Advanced > Backend Configuration file (pre-Vinson) Configuration.js 71 Cache Subtab Applies to: SuiteCommerce | SuiteCommerce Advanced These settings configure caching behavior in your Commerce web store. Content Page CDN This string specifies the CDN cache duration for content pages. Possible values are Short, Medium, and Long. More Information: CDN Caching ID cache.contentPageCdn UI Location Advanced > Cache JSON file ShoppingApplication.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js Content Page TTL This integer specifies the duration of the application Time To Live (TTL) cache for content pages. This value is specified in seconds. The total value must be between 300 (5 minutes) and 7200 (2 hours). ID cache.contentPageTtl UI Location Advanced > Cache JSON file ShoppingApplication.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js Site Cache Setting (Pre-Mont Blanc Only) Specifies the duration of the site settings cache. This caches all properties (except touch points) using the application cache. By default this is set to 7200. This value is defined in seconds and must be between 300 (5 minutes) and 7200 (2 hours). Note: This property does not exist with Mont Blanc release of SuiteCommerce Advanced and later or with SuiteCommerce. To configure your site cache settings in a pre-Mont Blanc implementation, edit the siteSettings property in the backend Configuration.js file. For detailed information, see Customize and Extend Core SuiteCommerce Advanced Modules. ID SuiteCommerce Site Development cache.siteSettings Advanced Tab UI Location none Configuration file (pre-Vinson) Configuration.js Custom Fields Subtab Applies to: SuiteCommerce | SuiteCommerce Advanced Sales Order These settings specify which custom transaction body fields (by Field ID) you want exposed to your web store. More Information: Commerce Custom Fields ID customFields.salesorder UI Location Advanced > Custom Fields Favicon Path Subtab Applies to: SuiteCommerce | SuiteCommerce Advanced Favicon of the Website This string specifies the path to the favicon for the website. This property is blank by default. ID faviconPath UI Location Advanced > Favicon Path JSON file Favicon.json Filter Site Subtab Applies to: SuiteCommerce | SuiteCommerce Advanced These settings filter record lists by website. Filter Site Option This string specifies how record lists are filtered. The default value is current. Possible values are (as string): ■ all – filters records for all websites in the current NetSuite account. ■ current– filters records only in the current account. ■ siteIds – filters records for a specific website by Site ID. SuiteCommerce Site Development 72 Advanced Tab ID filterSite.option UI Location Advanced > Filter Site ID (pre-Vinson) filter_site JSON file FilterSite.json Configuration file (pre-Vinson) Configuration.js 73 Filter Site IDs This array filters records for web sites specified by site ID (see Filter Site Option). This value contains an array of comma-separated numeric IDs. ID filterSite.ids UI Location Advanced > Filter Site ID (pre-Vinson) None JSON file FilterSite.json Configuration file (pre-Vinson) Configuration.js Image Resize Subtab Applies to: SuiteCommerce | SuiteCommerce Advanced These settings map image-resize values to names as used in the application (Setup > Website > Advanced > Image Resizing). The current sizes used in Commerce web stores are: ■ thumbnail: 175 x 175 (used in the search results) ■ main: 600 x 600 (used as main image in the PDP) ■ tinythumb: 50 x 50 (used as the tiny thumbs in the PDP's image gallery) ■ zoom: 1200 x 1200 (used in the PDP's zoomed image) ■ fullscreen: 1600 x 1600 ■ homeslider: 200 x 200 ■ homecell: 125 x 125 Each Image Resize property contains the following properties: ■ Size (string) – defines the image size name used in the application. ■ Value (string) – specifies the corresponding value given in the website record (Image Size ID). More Information: Setting Up Image Resizing IDs imageSizeMapping imageSizeMapping.id imageSizeMapping.value UI Location Advanced> Image Resize SuiteCommerce Site Development Advanced Tab JSON file ApplicationSkeleton.Layout.Images.json Configuration file (pre-Vinson) SC.Configuration.js 74 Pagination Subtab Applies to: SuiteCommerce | SuiteCommerce Advanced These settings configure the pagination settings when multiple pages are returned. If enabled, the Page List displays links for multiple-page browsing. Desktop > Show Page List This boolean displays or hides the Page List on desktop browsers. ID defaultPaginationSettings.showPageList UI Location Advanced > Pagination JSON file Pagination.json Configuration file (pre-Vinson) SC.MyAccount.Configuration.js, SC.Shopping.Configuration.js Desktop > Pages To Show This number specifies the maximum number of pages displayed in the page list on desktop browsers. The default value is 4. ID defaultPaginationSettings.pagesToShow UI Location Advanced > Pagination JSON file Pagination.json Configuration file (pre-Vinson) SC.MyAccount.Configuration.js, SC.Shopping.Configuration.js Desktop > Show Page Indicator This boolean displays or hides a current page indicator in the page list on desktop browsers. ID defaultPaginationSettings.showPageIndicator UI Location Advanced > Pagination JSON file Pagination.json Configuration file (pre-Vinson) SC.MyAccount.Configuration.js, SC.Shopping.Configuration.js Phone > Show Page List This boolean displays or hides the Page List on mobile browsers. SuiteCommerce Site Development Advanced Tab ID defaultPaginationSettingsPhone.showPageList UI Location Advanced > Pagination JSON file Pagination.json Configuration file (pre-Vinson) SC.MyAccount.Configuration.js, SC.Shopping.Configuration.js Phone > Pages To Show This number specifies the maximum number of pages displayed in the page list on mobile browsers. The default value is 4. ID defaultPaginationSettingsPhone.pagesToShow UI Location Advanced > Pagination JSON file Pagination.json Configuration file (pre-Vinson) SC.MyAccount.Configuration.js, SC.Shopping.Configuration.js Phone > Show Page Indicator This boolean displays or hides a current page indicator in the page list on mobile browsers. ID defaultPaginationSettingsPhone.showPageIndicator UI Location Advanced > Pagination JSON file Pagination.json Configuration file (pre-Vinson) SC.MyAccount.Configuration.js, SC.Shopping.Configuration.js Tablet > Show Page List This boolean displays or hides the Page List on tablet browsers. ID defaultPaginationSettingsTablet.showPageList UI Location Advanced > Pagination JSON file Pagination.json Configuration file (pre-Vinson) SC.MyAccount.Configuration.js, SC.Shopping.Configuration.js Tablet > Pages To Show This number specifies the maximum number of pages displayed in the page list on tablet browsers. The default value is 4. ID defaultPaginationSettingsTablet.pagesToShow UI Location Advanced > Pagination SuiteCommerce Site Development 75 Advanced Tab JSON file Pagination.json Configuration file (pre-Vinson) SC.MyAccount.Configuration.js, SC.Shopping.Configuration.js Tablet > Show Page Indicator This boolean displays or hides a current page indicator in the page list on tablet browsers. ID defaultPaginationSettingsTablet.showPageIndicator UI Location Advanced > Pagination JSON file Pagination.json Configuration file (pre-Vinson) SC.MyAccount.Configuration.js, SC.Shopping.Configuration.js Search Results Subtab Applies to: SuiteCommerce | SuiteCommerce Advanced These settings configure options to be passed when querying the Search API. Search API Fieldsets This array contains the following properties: ■ ID (string) – specifies the search type of the resource. Options include: □ Facets □ itemDetails □ relatedItems □ correlatedItems □ merchandizingZone □ typeAhead □ itemsSearcher □ CmsAdapterSearch ■ Fieldset (string) – specifies the fieldset parameter value. ■ Include (string) – specifies the include parameter value. More Information: Define Field Sets IDs searchApiMasterOptions searchApiMasterOptions.id searchApiMasterOptions.fieldset searchApiMasterOptions.include UI Location (Vinson) Advanced > Search Results JSON file ItemsSearchAPI.json Configuration file (pre-Vinson) SC.Configuration.js SuiteCommerce Site Development 76 Advanced Tab 77 Security Subtab Applies to: SuiteCommerce | SuiteCommerce Advanced These settings configure security headers to control whether your site’s pages can be rendered in a frame and, if so, by what domains. Allow Site To Be Framed This field specifies whether pages can be rendered in a frame. The possible settings include: DISALLOW FRAMING This setting allows pages to be rendered in a frame by only your own domain, which is the same origin. This is the default setting. ALLOW FRAMING This setting allows pages to be rendered in a frame by any domain/origin. ALLOW FRAMING CUSTOM This setting allows you to specify the domains/origins that are allowed to render pages in a frame. Specify the origins to allow in the ORIGIN list. By default, the ORIGIN list includes SAMEORIGIN to include your own domain. Checkout Tab Applies to: SuiteCommerce | SuiteCommerce Advanced The settings on this tab let you configure properties related to the Checkout application. This tab includes overall checkout properties plus the following subtabs: ■ Credit Card Subtab ■ Forms Subtab ■ Payment Methods Subtab Enable Pickup In Store This property applies to: ■ SuiteCommerce Advanced - Elbrus and later ■ SuiteCommerce This boolean enables the Pickup In Store feature for Commerce web stores. More Information: Pickup In Store ID isPickupInStoreEnabled UI Location Checkout JSON file PickupInStore.json Pickup In Store Sales Order Custom Form ID This property applies to: SuiteCommerce Site Development Checkout Tab ■ SuiteCommerce Advanced - Elbrus and later ■ SuiteCommerce This string specifies the ID for the sales order form customized for the Pickup In Store feature. More Information: Pickup In Store ID pickupInStoreSalesOrderCustomFormId UI Location Checkout JSON file PickupInStore.json Skip Checkout Login This boolean enables anonymous users to skip the login/register page when they navigate to Checkout. The user is redirected to the first checkout step. This is disabled by default. With this property enabled, the checkout application does not establish a guest session until data is sent to the backend for validation (any Ajax call to the server). Simply entering a full name does not create a session because the order has not been submitted to the backend. Without validation, some necessary session information is not yet known. For example, whether the user has permissions to pay with terms (invoices). After the guest session is created, the Checkout application refers to the user as Guest. If the user wants to log in as a registered user after this time, they must log out and either log in as a registered user or create an account. The application also gives a guest user the option to create an account after the checkout process is completed. Important: Invoices can not be set as a payment option for a One Page Checkout flow with this property enabled. This property is not supported on Site Builder sites or when Multiple Ship To is enabled and configured for your web store. More Information: Checkout ID checkoutApp.SkipLogin ID (pre-Vinson) checkout_skip_login UI Location Checkout JSON file CheckoutApplication.json Configuration file (pre-Vinson) Configuration.js Enable Multiple Shipping This boolean lets users specify multiple shipping addresses for an order. More Information: Multiple Ship To ID isMultiShippingEnabled UI Location Checkout SuiteCommerce Site Development 78 Checkout Tab JSON file CheckoutApplication.json Configuration file (pre-Vinson) Configuration.js 79 Remove PayPal Addresses This property applies to: ■ SuiteCommerce Advanced - Elbrus and later ■ SuiteCommerce This boolean lets users remove addresses from PayPal after placing the order, as the addresses are not valid for NetSuite. More Information: PayPal Address not Retained in Customer Record ID removePaypalAddress UI Location Checkout JSON file CheckoutApplication.json Use Standard Header and Footer This property applies to: ■ SuiteCommerce Advanced - Aconcagua and later ■ SuiteCommerce There are two types of headers and footers: ■ Standard: Used on non-checkout site pages. These headers and footers include navigation and other links. ■ Checkout: Used on checkout pages. These headers and footers are the default headers and footers for checkout pages and do not include navigation or other links. These headers and footers are designed to minimize the chances of a site user navigating away from the site prior to completing a purchase. The Use Standard Header and Footer boolean, when enabled (checked), causes the standard site header and footer to display on checkout pages. This option is disabled by default. When disabled (cleared), the checkout pages use the default (simplified) headers and footers. ID useStandardHeaderFooter UI Location Checkout JSON file CheckoutApplication.json Enable 3D Secure Payments This property applies to: SuiteCommerce Site Development Checkout Tab 80 ■ SuiteCommerce Advanced - Kilimanjaro and later ■ SuiteCommerce This boolean enables 3D Secure payments for a site. More Information: 3D Secure Payment Authentication ID isThreeDSecureEnabled UI Location Checkout JSON file CheckoutApplication.json Checkout Steps This string specifies a checkout flow configuration from the drop down list. Each checkout flow guides the user through the same tasks, but uses a different sequence of pages as defined below. More Information: Checkout Flows ID checkoutApp.checkoutSteps UI Location Checkout JSON file CheckoutApplication.json Configuration file (pre-Vinson) SC.Checkout.Configuration.js PayPal Logo URL This string specifies the URL of the PayPal logo. Commerce web stores display this logo in the check out process. ID checkoutApp.paypalLogo UI Location Checkout ID (pre-Vinson) paypal_logo JSON file CheckoutApplication.json Configuration file (pre-Vinson) SC.Checkout.Configuration.js Invoice Terms and Conditions This string specifies the text of the invoice terms and conditions in HTML format. ID checkoutApp.invoiceTermsAndConditions UI Location Checkout JSON file CheckoutApplication.json SuiteCommerce Site Development Checkout Tab Configuration file (pre-Vinson) 81 SC.Checkout.Configuration.js Credit Card Subtab Applies to: SuiteCommerce | SuiteCommerce Advanced These settings configure how credit card information is displayed. Show Credit Card Help This boolean displays or hides help text for finding a credit card security code. ID creditCard.showCreditCardHelp UI Location Checkout > Credit Cards JSON file CreditCard.json Configuration file (pre-Vinson) SC.Checkout.Configuration.js Credit Card Help Title This string specifies the title of the credit card help link. This title is displayed only if the Show Credit Card Help property is enabled. ID creditCard.creditCardHelpTitle UI Location Checkout > Credit Cards JSON file CreditCard.json Configuration file (pre-Vinson) SC.Checkout.Configuration.js CVV All Cards Image This string specifies the URL of the image showing the card verification value (CVV) number on credit cards. This image displays a number located on the back of the credit card. ID creditCard.imageCvvAllCards UI Location Checkout > Credit Cards JSON file CreditCard.json Configuration file (pre-Vinson) SC.Checkout.Configuration.js CVV American Card Image This string specifies the URL for the image showing the card verification value (CVV) number on American credit cards. This image shows a number located on the front of the credit card. SuiteCommerce Site Development Checkout Tab ID creditCard.imageCvvAmericanCard UI Location Checkout > Credit Cards JSON file CreditCard.json Configuration file (pre-Vinson) SC.Checkout.Configuration.js 82 Credit Card Secure Info This string specifies the security-related text displayed in the user interface. ID creditCard.creditCardShowSecureInfo UI Location Checkout > Credit Cards JSON file CreditCard.json Configuration file (pre-Vinson) SC.Checkout.Configuration.js Forms Subtab Applies to: SuiteCommerce | SuiteCommerce Advanced These settings configure the behavior of checkout forms. Applies to: ■ SuiteCommerce Advanced - Vinson and later ■ SuiteCommerce More Information: Checkout Auto Populate Name and Email This boolean enables or disables auto-population of a guest shopper’s name and email in any forms during checkout. If this field is disabled, no fields will populate automatically. If this field is enabled, Login as Guest, Show Name and Login as Guest, Show Email options must be enabled (as applicable) to populate automatically. ID autoPopulateNameAndEmail UI Location Checkout > Forms JSON file CheckoutApplication.json Login as Guest, Show Name This boolean displays or hides first and last name input fields when a user registers as a guest. If enabled, and the Auto Populate Name and Email property is also enabled, these names will be required and automatically populate throughout the checkout process where applicable. If disabled, no fields populate automatically. SuiteCommerce Site Development Checkout Tab ID forms.loginAsGuest.showName UI Location Checkout > Forms JSON file CheckoutApplication.json 83 Login as Guest, Show Email This boolean displays or hides an email address input field when a user registers as a guest. If enabled, and the Auto Populate Name and Email property is also enabled, this address will be required and automatically populate throughout the checkout process where applicable. If disabled, no fields populate automatically. ID forms.loginAsGuest.showEmail UI Location Checkout > Forms JSON file CheckoutApplication.json Show Address Line 2 This boolean displays or hides a secondary address line during Checkout. ID forms.address.showAddressLineTwo UI Location Checkout > Forms JSON file CheckoutApplication.json Payment Methods Subtab Applies to: SuiteCommerce | SuiteCommerce Advanced This array specifies the Payment Method record in NetSuite using the Payment Method ID. ■ Key (string) – This number must match the property key of the objects returned by the JavaScript call (run in the Browser Console): SC.ENVIRONMENT.siteSettings.paymentmethods. Enter the key value returned to configure each method. To edit or add new payment methods, in NetSuite go to Setup > Accounting > Accounting Lists, then filter by Payment Method. ■ Regex (string) – defines the regular expression that matches the payment method. ■ Description (string) – defines a text description of the payment method. More Information: Creating a Payment Method IDs paymentmethods paymentmethods.key paymentmethods.regex paymentmethods.description UI Location Checkout > Payment Methods JSON file PaymentMethods.json SuiteCommerce Site Development Checkout Tab Configuration file (pre-Vinson) SC.Configuration.js Integrations Tab Applies to: SuiteCommerce | SuiteCommerce Advanced The settings on this tab let you configure properties related to different integration options available for your site, such as Google, Twitter, and Facebook. This tab includes the following subtabs: ■ AddThis Subtab ■ Bronto Subtab ■ Categories Subtab ■ Facebook Subtab ■ Google AdWords Subtab ■ GooglePlus Subtab ■ Google Tag Manager Subtab ■ Google Universal Analytics Subtab ■ Pinterest Subtab ■ Site Management Tools Subtab ■ Twitter Subtab AddThis Subtab Applies to: SuiteCommerce | SuiteCommerce Advanced These settings configure the AddThis sharing service. This service defines which SEO services are active on your Commerce site. ID addThis UI Location Integrations > addThis JSON file addThis.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js Enable This boolean enables or disables the AddThis sharing service. ID addThis.enable UI Location Integrations > addThis JSON file addThis.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js SuiteCommerce Site Development 84 Integrations Tab Public ID This string specifies your AddThis Profile ID. ID addThis.pubId UI Location Integrations > addThis JSON file addThis.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js Toolbox Class This string specifies the class to be added to the AddThis Toolbox. ID addThis.toolboxClass UI Location Integrations > addThis JSON file addThis.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js Services to Show This array lists the social services to be displayed in the AddThis buttons. Each Service contains the following properties: ■ Key (string) – defines the sharing service. For example: facebook, pinterest, twitter. ■ Value (string) – defines a text description to display for the associated service. IDs addThis.servicesToShow addThis.servicesToShow.key addThis.servicesToShow.value UI Location Integrations > addThis JSON file addThis.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js Options This array defines the configuration options of the AddThis sharing service. ■ Key (string) – defines the AddThis configuration variable. ■ Value (string)– defines each configuration variable according to the AddThis service. IDs addThis.options addThis.options.key addThis.options.value UI Location Integrations > addThis SuiteCommerce Site Development 85 Integrations Tab JSON file addThis.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js 86 Bronto Subtab Applies to: SuiteCommerce | SuiteCommerce Advanced These settings configure Bronto integration with Commerce web stores. Bronto is a NetSuite company that provides an advanced marketing automation engine and solutions for shopping cart abandonment, post-purchase campaigns and so forth. Bronto can be easily integrated with your Commerce web store. The following Bronto Applications are supported: ■ Cart Recovery ■ Conversion Tracking ■ Coupon Manager ■ Pop-up Manager More Information: Bronto Integration Account ID This string specifies your Bronto account ID. ID bronto.accountId UI Location Integrations > Bronto JSON file BrontoIntegration.json Configuration file (pre-Vinson) SC.Configuration.js Adapter URL This string specifies the URL of the Bronto adapter. ID bronto.adapterUrl UI Location Integrations > Bronto JSON file BrontoIntegration.json Categories Subtab Applies to: SuiteCommerce | SuiteCommerce Advanced These settings configure properties related to Commerce Categories. SuiteCommerce Site Development Integrations Tab More Information: Commerce Categories Category Navigation Menu Level Deepness This integer specifies how many levels of the category hierarchy to show in the Categories navigation menu. ID categories.menuLevel UI Location Integrations > Categories JSON file Categories.json Show Categories Navigation Menu This boolean enables or disables the Categories navigation menu. ID categories.addToNavigationTabs UI Location Integrations > Categories JSON file Categories.json Exclude Empty Categories This boolean enables or disables the Exclude Empty Categories feature. ID categories.excludeEmptyCategories UI Location Integrations > Categories JSON file Categories.json Side Menu > Sort By This string specifies the Category record field to act as the primary sort field in the Categories sidebar. This is set to sequencenumber by default. In this case, the sidebar categories sort by the sequence number set in NetSuite. ID categories.sideMenu.sortBy UI Location Integrations > Categories JSON file Categories.json Side Menu > Additional Fields This string specifies any additional fields added to the default list returned by the ItemSearch API for use in the application. The default list returned is: ■ internalid SuiteCommerce Site Development 87 Integrations Tab 88 ■ name ■ sequencenumber ■ urlfragment ■ displayinsite ID categories.sideMenu.additionalFields UI Location Integrations > Categories JSON file Categories.json Side Menu > Collapsible This boolean specifies if the Categories side menu is collapsible and expandable. ID categories.sideMenu.uncollapsible UI Location Integrations > Categories JSON file Categories.json Side Menu > Show Max This integer specifies maximum number of categories to show in the list before displaying a Show More link. The default is 5. ID categories.sideMenu.showMax UI Location Integrations > Categories JSON file Categories.json Side Menu > Collapsed This boolean specifies if the Categories sidebar is collapsed when the page loads. The default is to appear expanded. ID categories.sideMenu.collapsed UI Location Integrations > Categories JSON file Categories.json Sub Categories > Sort By This string specifies the Category record field to act as the primary sort field for sub categories. This is set to sequencenumber by default. In this case, the sidebar categories will sort by the sequence number set in NetSuite. ID categories.subCategories.sortBy SuiteCommerce Site Development Integrations Tab UI Location Integrations > Categories JSON file Categories.json 89 Sub Categories > Additional Fields This string specifies any additional fields added to the default list returned by the ItemSearch API for use in the application for sub categories. The default list returned is: ■ internalid ■ name ■ description ■ sequencenumber ■ urlfragment ■ thumbnailurl ■ displayinsite ID categories.subCategories.fields UI Location Integrations > Categories JSON file Categories.json Category Fields This string specifies any optional fields added to the default list for category fields. Category Fields are the fields that appear in the Category page. ID categories.category.fields UI Location Integrations > Categories JSON file Categories.json Breadcrumb Fields This string specifies any additional fields added to the default list returned by the ItemSearch API for use in the breadcrumb navigation. The default list returned is: ■ internalid ■ name ■ displayinsite ID categories.breadcrumb.fields UI Location Integrations > Categories JSON file Categories.json SuiteCommerce Site Development Integrations Tab Menu > Sort By This string specifies the Category record field as the primary sort field in the Navigation menu. This is set to sequencenumber by default. In this case, the navigation menu categories will sort by the sequence number set in NetSuite. ID categories.menu.sortBy UI Location Integrations > Categories JSON file Categories.json Menu Fields This property specifies any additional fields added to the default list returned by the ItemSearch API for use in the Navigation menu. The default list returned is: ■ internalid ■ name ■ sequencenumber ■ displayinsite ID categories.menu.fields UI Location Integrations > Categories JSON file Categories.json Facebook Subtab Applies to: SuiteCommerce | SuiteCommerce Advanced These settings configure Facebook popup integration with Commerce web stores. The popupOptions configured here get passed as the third parameter into the window.Open method of SocialSharing.Plugins.Facebook.js. More Information: Facebook Share Enable This boolean enables or disables the Facebook addThis sharing service. ID facebook.enable UI Location Integrations > Facebook JSON file facebook.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js SuiteCommerce Site Development 90 Integrations Tab Application ID This string sets the custom application ID to associate the domain to your application ID. ID facebook.appId UI Location Integrations > Facebook JSON file facebook.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js Facebook Popup Status This string specifies if the Facebook popup is enabled. ID facebook.popupOptions.status UI Location Integrations > Facebook JSON file facebook.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js Facebook Popup Resizable This string specifies if the Facebook popup is resizable. ID facebook.popupOptions.resizable UI Location Integrations > Facebook JSON file facebook.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js Facebook Popup Scrollbars This string specifies if the Facebook popup displays scrollbars. ID facebook.popupOptions.scrollbars UI Location Integrations > Facebook JSON file facebook.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js Facebook Popup Personalbar This string specifies if the Facebook popup displays a personal bar. ID SuiteCommerce Site Development facebook.popupOptions.personalbar 91 Integrations Tab UI Location Integrations > Facebook JSON file facebook.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js Facebook Popup Directories This string specifies if the Facebook popup displays a directories bar. ID facebook.popupOptions.directories UI Location Integrations > Facebook JSON file facebook.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js Facebook Popup Location This string specifies if the Facebook popup displays a location bar. ID facebook.popupOptions.location UI Location Integrations > Facebook JSON file facebook.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js Facebook Popup Toolbar This string specifies if the Facebook popup displays a tool bar. ID facebook.popupOptions.toolbar UI Location Integrations > Facebook JSON file facebook.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js Facebook Popup Menubar This string specifies if the Facebook popup displays a menu bar. ID facebook.popupOptions.menubar UI Location Integrations > Facebook JSON file facebook.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js SuiteCommerce Site Development 92 Integrations Tab Facebook Popup Width This integer specifies the width (in pixels) of the Facebook popup. ID facebook.popupOptions.width UI Location Integrations > Facebook JSON file facebook.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js Facebook Popup Height This integer specifies the height (in pixels) of the Facebook popup. ID facebook.popupOptions.height UI Location Integrations > Facebook JSON file facebook.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js Facebook Popup Left This integer specifies the left offset (in pixels). ID facebook.popupOptions.left UI Location Integrations > Facebook JSON file facebook.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js Facebook Popup Top This integer specifies the top offset (in pixels). ID facebook.popupOptions.top UI Location Integrations > Facebook JSON file facebook.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js Google AdWords Subtab Applies to: SuiteCommerce | SuiteCommerce Advanced These settings configure Google AdWords. SuiteCommerce Site Development 93 Integrations Tab 94 More Information: Google Ads Google AdWords ID This string specifies your Google AdWords ID. This value corresponds to the conversion tag you created in your Google AdWords account. ID 2019.2 and later: tracking.googleAdWordsConversion.id 2019.1 and earlier: googleAdWordsConversion.id UI Location 2019.2 and later: Integrations > Adwords 2019.1 and earlier: Integrations > Google Adwords JSON file GoogleAdWords.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js SC.MyAccount.Configuration.js SC.Checkout.Configuration.js AdWords Value This string specifies the value property you defined in the conversion tag you created in your Google AdWords account. ID 2019.2 and later: tracking.googleAdWordsConversion.value 2019.1 and earlier: googleAdWordsConversion.value UI Location 2019.2 and earlier: Integrations > Adwords 2019.1 and later: Integrations > Google Adwords JSON file GoogleAdWords.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js SC.MyAccount.Configuration.js SC.Checkout.Configuration.js Google AdWords Label This string specifies your Google AdWords label. This value corresponds to the conversion tag you created in your Google AdWords account. SuiteCommerce Site Development Integrations Tab ID 2019.2 and later: tracking.googleAdWordsConversion.label 2019.1 and earlier: googleAdWordsConversion.label UI Location 2019.2 and later: Integrations > Adwords 2019.1 and earlier: Integrations > Google Adwords JSON file GoogleAdWords.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js SC.MyAccount.Configuration.js SC.Checkout.Configuration.js GooglePlus Subtab Applies to: SuiteCommerce | SuiteCommerce Advanced These settings configure GooglePlus integration with Commerce web stores. Enable This boolean enables or disables the GooglePlus addThis property. ID googlePlus.enable UI Location Integrations > GooglePlus JSON file googlePlus.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js GooglePlus Popup Status This string specifies if the GooglePlus popup is enabled. ID googlePlus.popupOptions.status UI Location Integrations > GooglePlus JSON file googlePlus.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js GooglePlus Popup Resizable This string specifies if the GooglePlus popup is resizable. SuiteCommerce Site Development 95 Integrations Tab ID googlePlus.popupOptions.resiszable UI Location Integrations > GooglePlus JSON file googlePlus.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js GooglePlus Popup Scrollbars This string specifies if the GooglePlus popup displays scrollbars. ID googlePlus.popupOptions.scrollbars UI Location Integrations > GooglePlus JSON file googlePlus.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js GooglePlus Popup Personalbar This string specifies if the GooglePlus popup displays a personal bar. ID googlePlus.popupOptions.personalbar UI Location Integrations > GooglePlus JSON file googlePlus.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js GooglePlus Popup Directories This string specifies if the GooglePlus popup displays a directories bar. ID googlePlus.popupOptions.directories UI Location Integrations > GooglePlus JSON file googlePlus.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js GooglePlus Popup Location This string specifies if the GooglePlus popup displays a location bar. ID googlePlus.popupOptions.location UI Location Integrations > GooglePlus JSON file googlePlus.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js SuiteCommerce Site Development 96 Integrations Tab GooglePlus Popup Toolbar This string specifies if the GooglePlus popup displays a tool bar. ID googlePlus.popupOptions.toolbar UI Location Integrations > GooglePlus JSON file googlePlus.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js GooglePlus Popup Menubar This string specifies if the GooglePlus popup displays a menu bar. ID googlePlus.popupOptions.menubar UI Location Integrations > GooglePlus JSON file googlePlus.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js GooglePlus Popup Width This integer specifies the width (in pixels) of the GooglePlus popup. ID googlePlus.popupOptions.width UI Location Integrations > GooglePlus JSON file googlePlus.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js GooglePlus Popup Height This integer specifies the height (in pixels) of the GooglePlus popup. ID googlePlus.popupOptions.height UI Location Integrations > GooglePlus JSON file googlePlus.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js GooglePlus Popup Left This integer specifies the left offset (in pixels) of the GooglePlus popup. ID SuiteCommerce Site Development googlePlus.popupOptions.left 97 Integrations Tab UI Location Integrations > GooglePlus JSON file googlePlus.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js 98 GooglePlus Popup Top This integer specifies the top (in pixels) of the GooglePlus popup. ID googlePlus.popupOptions.top UI Location Integrations > GooglePlus JSON file googlePlus.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js Google Tag Manager Subtab Applies to: SuiteCommerce | SuiteCommerce Advanced These settings configure properties related to the Google Tag Manager. More: Google Tag Manager Google Tag Manager ID This string specifies the value of the Google Tag Manager ID. Setting this property enables this feature on your Commerce site. More Information: Step 2: Sign Up for Google Tag Manager ID tracking.googleTagManager.id UI Location Integrations > Google Tag Manager JSON file GoogleTagManager.json Configuration file (pre-Vinson) SC.Configuration.js Google Tag Manager Data Name This string specifies the data layer object that contains all of the information that you want to pass to Google Tag Manager. ID tracking.googleTagManager.dataLayerName UI Location Integrations > Google Tag Manager JSON file GoogleTagManager.json Configuration file (pre-Vinson) SC.Configuration.js SuiteCommerce Site Development Integrations Tab 99 Is A Multi-Domain Site? This property applies to: ■ SuiteCommerce Advanced - 2018.2 and later ■ SuiteCommerce This boolean specifies if shopping and checkout use separate domains. Enable this option to preserve data between sessions when using separate domains for shopping and checkout. ID tracking.googleTagManager.isMultiDomain UI Location Integrations > Google Tag Manager JSON file GoogleTagManager.json Google Universal Analytics Subtab Applies to: SuiteCommerce | SuiteCommerce Advanced These settings configure properties for Google Universal Analytics. Google Universal Analytics is a third party analytics solution that can help you evaluate traffic on your website using data based on visitor tracking information. More Information: Configuring GUA Google Universal Analytics ID This string specifies the Google Universal Analytics Tracking ID. The application inserts this property into each page of the application. To locate the tracking ID, login to your Google Analytics account and go to Admin > Property > Property Settings. More Information: Set Up GUA Account and Website Property ID tracking.googleUniversalAnalytics.propertyID UI Location Integrations > Google Universal Analytics JSON file GoogleUniversalAnalytics.json Configuration file (pre-Vinson) SC.Checkout.Configuration.js Google Universal Analytics Domain This string specifies the unencrypted (insecure) domain hostname used for Google Universal Analytics. If you use separate domains for shopping and checkout, enter the hostname of the insecure shopping domain in this field. Example: shopping.example.com If you use a single secure domain for shopping and checkout, leave this field blank. See the help topic Set Up Domains for Web Stores for additional information. More Information: Configuring GUA SuiteCommerce Site Development Integrations Tab Note: If you are implementing SuiteCommerce Advanced MontBlanc or later, use Google Tag Manager to configure tracking codes. See Google Tag Manager. ID tracking.googleUniversalAnalytics.domainName UI Location Integrations > Google Universal Analytics JSON file GoogleUniversalAnalytics.json Configuration file (pre-Vinson) SC.Checkout.Configuration.js Google Universal Analytics Secure Domain This string specifies the encrypted (secure) domain hostname used for Google Universal Analytics. If you use a single secure domain for shopping and checkout, leave this field empty. If you use a custom checkout domain, enter the hostname of the checkout domain in this field. Example: checkout.example.com If you use NetSuite for your checkout domain, enter netsuite.com in this field. ID tracking.googleUniversalAnalytics.domainNameSecure UI Location Integrations > Google Universal Analytics JSON file GoogleUniversalAnalytics.json Configuration file (pre-Vinson) SC.Checkout.Configuration.js Pinterest Subtab Applies to: SuiteCommerce | SuiteCommerce Advanced These settings configure Pinterest integration with Commerce web stores. More Information: Pinterest Enable Hover This boolean enables or disables the Pinterest Pin It to hover over the image. ID pinterest.enableHover UI Location Integrations > Pinterest JSON file pinterest.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js Enable Button This boolean enables or disables the Pinterest PinIt button. SuiteCommerce Site Development 100 Integrations Tab ID pinterest.enableButton UI Location Integrations > Pinterest JSON file pinterest.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js Image Size This string specifies the Pinterest image size ID to show on Pinterest. ID pinterest.imageSize UI Location Integrations > Pinterest JSON file pinterest.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js Pinterest Popup Status This string specifies if the Pinterest popup is enabled. ID pinterest.popupOptions.status UI Location Integrations > Pinterest JSON file pinterest.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js Pinterest Popup Resizable This string specifies if the Pinterest popup is resizable. ID pinterest.popupOptions.resizable UI Location Integrations > Pinterest JSON file pinterest.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js Pinterest Popup Scrollbars This string specifies if the Pinterest popup displays scroll bars. ID pinterest.popupOptions.scrollbars UI Location Integrations > Pinterest JSON file pinterest.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js SuiteCommerce Site Development 101 Integrations Tab Pinterest Popup Personalbar This string specifies if the Pinterest popup displays a personal bar. ID pinterest.popupOptions.personalbar UI Location Integrations > Pinterest JSON file pinterest.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js Pinterest Popup Directories This string specifies if the Pinterest popup displays a directories bar. ID pinterest.popupOptions.directories UI Location Integrations > Pinterest JSON file pinterest.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js Pinterest Popup Location This string specifies if the Pinterest popup displays a location bar. ID pinterest.popupOptions.location UI Location Integrations > Pinterest JSON file pinterest.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js Pinterest Popup Toolbar This string specifies if the Pinterest popup displays a tool bar. ID pinterest.popupOptions.toolbar UI Location Integrations > Pinterest JSON file pinterest.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js Pinterest Popup Menubar This string specifies if the Pinterest popup displays a menu bar. ID SuiteCommerce Site Development pinterest.popupOptions.menubar 102 Integrations Tab UI Location Integrations > Pinterest JSON file pinterest.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js Pinterest Popup Width This number specifies the width (in pixels) of the Pinterest popup. ID pinterest.popupOptions.width UI Location Integrations > Pinterest JSON file pinterest.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js Pinterest Popup Height This number specifies the height (in pixels) of the Pinterest popup. ID pinterest.popupOptions.height UI Location Integrations > Pinterest JSON file pinterest.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js Pinterest Popup Left This number specifies the left offset (in pixels) of the Pinterest popup. ID pinterest.popupOptions.left UI Location Integrations > Pinterest JSON file pinterest.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js Pinterest Popup Top This number specifies the top offset (in pixels) of the Pinterest popup. ID pinterest.popupOptions.top UI Location Integrations > Pinterest JSON file pinterest.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js SuiteCommerce Site Development 103 Integrations Tab 104 Site Management Tools Subtab Applies to: SuiteCommerce | SuiteCommerce Advanced These settings configure properties for the Site Management Tools (SMT). More Information: Site Management Tools Use Site Management Tools This boolean enables or disables SMT integration with Commerce web stores. Content Delivery and SMT are mutually exclusive features. If you want to use Content Delivery, this property must be unchecked. ID cms.useCMS UI Location Integrations > Site Management Tools JSON file CMS.json Configuration file (pre-Vinson) Configuration.js Disable ESC Key to Login This property applies to: ■ SuiteCommerce Advanced - Elbrus and later ■ SuiteCommerce This boolean enables or disables SMT’s escape-to-login feature. This property is unchecked by default, allowing users to press the ESC key to login to SMT. To disable your site’s escape-to-login feature, check this property. More Information: Disable Esc Key to Log In ID cms.escToLoginDisabled UI Location Integrations > Site Management Tools JSON file CMS.json Landing Pages URL This property applies to: ■ SuiteCommerce Advanced - Elbrus and later ■ SuiteCommerce This string enables you to configure the base URL for Site Management Tools landing pages. By default this property is blank, and landing pages use the URL of the web store. When working in a sandbox account, set the property to the URL for sandbox, for example, https://system.sandbox.netsuite.com. ID cms.baseUrl UI Location Integrations > Site Management Tools SuiteCommerce Site Development Integrations Tab JSON file 105 CMS.json CMS Adapter Version This string specifies the CMS Adapter version (2 or 3) to be used by Site Management Tools. The default value for this field is 3. If you are implementing custom content types (CCTs) on your site, you must set this property to 3. More information: Site Management Tools ID cms.adapterVersion UI Location Integrations > Site Management Tools JSON file CMS.json Time to Wait for CMS Content (ms) This string specifies the maximum time in milliseconds to wait for CMS content to render. If this maximum time is exceeded, the app renders then CMS content renders later. You might also have a flickering problem. The default value for this field is 200. More information: Site Management Tools ID cms.contentWait UI Location Integrations > Site Management Tools JSON file CMS.json Twitter Subtab Applies to: SuiteCommerce | SuiteCommerce Advanced These settings configure Twitter popup settings. More Information: Twitter Product Cards Enable This boolean specifies if the Twitter addThis property is enabled. ID twitter.enable UI Location Integrations > Twitter JSON file twitter.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js Twitter Popup Status This string specifies if the Twitter popup is enabled. SuiteCommerce Site Development Integrations Tab ID twitter.popupOptions.status UI Location Integrations > Twitter JSON file twitter.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js Twitter Popup Resizeable This string specifies if the Twitter popup is resizable. ID twitter.popupOptions.resizable UI Location Integrations > Twitter JSON file twitter.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js Twitter Popup Scrollbars This string specifies if the Twitter popup displays scroll bars. ID twitter.popupOptions.scrollbars UI Location Integrations > Twitter JSON file twitter.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js Twitter Popup Personalbar This string specifies if the Twitter popup displays a personal bar. ID twitter.popupOptions.personalbar UI Location Integrations > Twitter JSON file twitter.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js Twitter Popup Directories This string specifies if the Twitter popup displays a directories bar. ID twitter.popupOptions.directories UI Location Integrations > Twitter JSON file twitter.json SuiteCommerce Site Development 106 Integrations Tab Configuration file (pre-Vinson) SC.Shopping.Configuration.js Twitter Popup Location This string specifies if the Twitter popup displays a location bar. ID twitter.popupOptions.location UI Location Integrations > Twitter JSON file twitter.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js Twitter Popup Toolbar This string specifies if the Twitter popup displays a tool bar. ID twitter.popupOptions.toolbar UI Location Integrations > Twitter JSON file twitter.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js Twitter Popup Menubar This string specifies if the Twitter popup displays a menu bar. ID twitter.popupOptions.menubar UI Location Integrations > Twitter JSON file twitter.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js Twitter Popup Width This number specifies the width (in pixels) of the Twitter popup. ID twitter.popupOptions.width UI Location Integrations > Twitter JSON file twitter.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js Twitter Popup Height This number specifies the height (in pixels) of the Twitter popup. SuiteCommerce Site Development 107 Integrations Tab ID twitter.popupOptions.height UI Location Integrations > Twitter JSON file twitter.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js Twitter Popup Left This number specifies the left offset (in pixels) of the Twitter popup. ID twitter.popupOptions.left UI Location Integrations > Twitter JSON file twitter.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js Twitter Popup Top This number specifies the top offset (in pixels) of the Twitter popup. ID twitter.popupOptions.top UI Location Integrations > Twitter JSON file twitter.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js Twitter VIA This string specifies the Twitter account of the original tweeter. For example: @MerchantName. ID twitter.popupOptions.via UI Location Integrations > Twitter JSON file twitter.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js Layout Tab Applies to: SuiteCommerce | SuiteCommerce Advanced The settings on this tab let you configure proper ties related to your site layout. This tab includes the following subtabs: ■ Bottom Banner Images Subtab SuiteCommerce Site Development 108 Layout Tab 109 ■ Carousel Images Subtab ■ Color Palettes Subtab ■ Cookies Warning Banner Subtab ■ Footer Subtab ■ Header Subtab ■ Images Subtab ■ Light Colors Subtab ■ Navigation Subtab Bottom Banner Images Subtab Applies to: SuiteCommerce | SuiteCommerce Advanced This array specifies the banner images that appear at the bottom of the application. Each banner image requires the URL property. This string defines the URL of the bottom banner image. The order in the array specifies the order in the banner. Note: SuiteCommerce Advanced developers on the Kilimanjaro release or earlier: Three default images are distributed with the SCA bundle. These images are located in the ShoppingApplication module. You can ovevrride these default images, but the images must be in the file cabinet. ID home.bottomBannerImages UI Location Layout > Bottom Banner Images JSON file Home.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js Carousel Images Subtab Applies to: SuiteCommerce | SuiteCommerce Advanced This array specifies the carousel images that appear at the top of the home page. Each carousel image requires the URL property. This string defines the URL of the carousel image. The order in the array specifies the order in the carousel. Note: The three default images are distributed with the SCA bundle, located in the ShoppingApplication module. You can override these, but the images must be in the file cabinet at Web Site Hosting Files > Live Hosting Files > SSP Applications > [SSP Application] > Development > img. Note: Carousel styles are dictated by Sass files in the source code. If implementing SuiteCommerce or the Aconcagua release of SCA or later, you can alter the carosel Sass as part of a theme. Sass files for the carousel are located in the twitter-bootstrap-sass module of the SuiteCommerce Base Theme. See: File Types Recognized in the File Cabinet for a list of supported image file types. SuiteCommerce Site Development Layout Tab ID home.carouselImages UI Location Layout > Carousel Images JSON file Home.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js 110 Color Palettes Subtab Applies to: SuiteCommerce | SuiteCommerce Advanced These settings define the default color palette or let you create a new one. A color palette maps a color defined in NetSuite to a CSS color value. A color palette maps a color label to its hexadecimal value. More Information: Select and Configure Facet Fields Each color palette contains the following: ■ Palette ID (string) – specifies the internal id for the color. The default color palette is called default. When creating a custom color palette, use only number values from 1 to 20. ■ Color Name (string) – specifies the name of the color. ■ Color Value (string) – specifies the hexadecimal value of the color. If you want to use an image as a color source, leave this field blank. ■ In some cases, you may want a color option that cannot be generated from a hexadecimal value, such as an image of fabric. In these cases, use the following fields to specify the image that you want: □ Image Source – specifies the source image for the color as a URL. For example: /siteImgFolder/ colorImage.jpg □ Image Height – specifies the height of the image in pixels. For example: 20px □ Image Width – specifies the width of the image in pixels. For example: 20px Note: The preceding Image fields are available in the Elbrus and later releases of Commerce web stores. These Image fields are not available for earlier releases, but you can define the image as an object in the Color Value field. To define an object in the Color Value field instead of a specifying a hexadecimal value, define the object type (image), src (URL), width and height (in pixels). For example: {type: 'image', src: '/siteImgFolder/colorImage.png', width: 20, height: 20} IDs layout.ColorPalette layout.ColorPalette.paletteId layout.ColorPalette.colorName layout.ColorPalette.colorValue layout.ColorPalette.imgsrc layout.ColorPalette.imgheight layout.ColorPalette.imgwidth IDs (pre-Elbrus) facetsColorPalette facetsColorPalette.paletteId facetsColorPalette.colorName facetsColorPalette.colorValue Note: These properties appear in the Shopping Catalog tab and Facet Color Palettes subtab in Vinson implementations of SCA. UI Location SuiteCommerce Site Development Layout > Color Palettes Layout Tab Configuration file (pre-Vinson) 111 SC.Shopping.Configuration.js Cookies Warning Banner Subtab Applies to: SuiteCommerce | SuiteCommerce Advanced These settings configure the cookie warning banner. To display this banner, you must enable the Show Cookie Consent Banner property in NetSuite. ID cookieWarningBanner UI Location Layout > Cookie Warning Banner JSON file Cookies.json Configuration file (pre-Vinson) SC.Configuration.js User May Dismiss Banner This boolean specifies if the user can close the cookie warning banner. ID cookieWarningBanner.closable UI Location Layout > Cookie Warning Banner JSON file Cookies.json Configuration file (pre-Vinson) SC.Configuration.js Save in Cookie This boolean specifies if the value of the User May Dismiss Banner property is stored in a browser cookie. ID cookieWarningBanner.saveInCookie UI Location Layout > Cookie Warning Banner JSON file Cookies.json Configuration file (pre-Vinson) SC.Configuration.js Anchor Text This string specifies the text used in the link to a modal dialog whose content is defined in the Message property. The default value of this property is Learn More. ID cookieWarningBanner.anchorText UI Location Layout > Cookie Warning Banner SuiteCommerce Site Development Layout Tab JSON file Cookies.json Configuration file (pre-Vinson) SC.Configuration.js Message This string specifies the text of the modal dialog. This text is displayed when the user clicks the link defined in the Anchor Text property. ID cookieWarningBanner.message UI Location Layout > Cookie Warning Banner JSON file Cookies.json Configuration file (pre-Vinson) SC.Configuration.js Footer Subtab Applies to: SuiteCommerce | SuiteCommerce Advanced This subtab moved to the Legacy tab in the 2018.2 release of SuiteCommerce Advanced. See Footer Subtab for more information on the properties related to Footer. Header Subtab Applies to: SuiteCommerce | SuiteCommerce Advanced These settings specify properties of the application header. Hide Currency Selector This boolean hides or displays the currency selector in the application. Enable this property to hide the selector. ID header.notShowCurrencySelector UI Location Layout > Header JSON file Header.json Configuration file (pre-Vinson) SC.Checkout.Configuration.js Logo URL This string specifies the location of the logo image file that is displayed at the top of the application. ID SuiteCommerce Site Development header.logoUrl 112 Layout Tab UI Location Layout > Header JSON file Header.json Configuration file (pre-Vinson) SC.Checkout.Configuration.js Show Recognized Shopper This boolean enables or disables the show recognized shopper feature when the session times out. ID header.showRecognizedShopper UI Location Layout > Header JSON file Header.json Images Subtab Applies to: SuiteCommerce | SuiteCommerce Advanced These settings configure general properties for site images. Image Not Available URL This string specifies the URL to the default image displayed when an item image is not configured. ID imageNotAvailable UI Location Layout > Images JSON file ApplicationSkeleton.Layout.Images.json Configuration file (pre-Vinson) SC.Configuration.js Light Colors Subtab Applies to: SuiteCommerce | SuiteCommerce Advanced This array specifies color labels in the color pallet that have a similar hue to the background color. The color picker for each of these colors is displayed with an outer border. ID layout.lightColors ID (Pre-Elbrus) lightColors Note: In the Vinson release of SCA, this property is located on the Shopping Catalog tab and Light Colors subtab. UI Location SuiteCommerce Site Development Layout > Light Colors 113 Layout Tab JSON file ApplicationSkeleton.Layout.Colors.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js Navigation Subtab Applies to: SuiteCommerce | SuiteCommerce Advanced These settings configure defaults for the main navigational links of the application (Home, Shop, etc.) used to construct site navigation. This array specifies the following for each link: ■ Text (string) – specifies the link text displayed in the user interface. ■ HREF (string) – specifies the href attribute of the navigation link. For example: /search results in navigation to the search results page. This is ignored for parent entries. ■ Level (string) – specifies the hierarchical level of this navigation link. ■ data-touchpoint (string) – specifies the touch point of the navigational link, if applicable. ■ data-hashtag (string) – specifies the data hashtag of the link. ■ Class names (string)– specifies any additional HTML class names added to the link. ■ ID (string) – specifies the internal identifier of the link. Parent entries must have an ID for children to reference. ■ Parent ID (string) – specifies the parent ID of the entry if it is a child view. IDs navigationData navigationData.text navigationData.href navigationData.level navigationData.dataTouchpoint navigationData.dataHashtag navigationData.classnames navigationData.id navigationData.parentId UI Location Layout > Navigation Configuration file (pre-Vinson) SC.Configuration.js Legacy Tab Applies to: SuiteCommerce | SuiteCommerce Advanced ■ Newsletter Subtab ■ Footer Subtab This tab provides access to properties that may transition to Site Management Tools or Extensions. The 2018.1 release of SuiteCommerce and SCA includes the templates necessary to access the configuration properties located on the Legacy tab subtabs. If your implementation began with the SuiteCommerce Site Development 114 Legacy Tab 2018.2 release or later, you do not have the templates necessary to access these properties and you should not use this tab. Newsletter Subtab Applies to: SuiteCommerce | SuiteCommerce Advanced In SuiteCommerce Advanced Aconcagua and earlier, this subtab is located under the Shopping tab. In SuiteCommerce Advanced 2018.2 and later, this subtab is not available. This feature and its settings require: ■ SuiteCommerce Advanced – Vinson, Elbrus, Kilimanjaro, or Aconcagua. ■ SuiteCommerce 2018.1 release. The following settings specify properties for the Newsletter opt-in feature. When a user submits an email address for a newsletter and the SuiteScript API fails to return any matching Customer or Lead records, the application creates a new Lead record in NetSuite. SCA then sets this new record’s Global Subscription Status field to Soft Opt-In. However, in these situations, NetSuite requires populating the new Lead record’s Name or Company Name fields with information. You configure the value of these entries. The default value for each field is unknown. When a user submits an email address for a newsletter and the SuiteScript API fails to return any matching Customer or Lead records, the application creates a new Lead record in NetSuite. SCA then sets this new record’s Global Subscription Status field to Full Subscription (Not opted in; send all messages). However, in these situations, NetSuite requires populating the new Lead record’s Name or Company Name fields with information. You configure the value of these entries. The default value for each field is unknown. More Information: Newsletter Generic First Name This string specifies the generic first name to populate in a new Lead record when a user opts in for the newsletter. This satisfies the record’s requirement to populate this field. ID newsletter.genericFirstName UI Location Legacy > Newsletter UI Location (Aconcagua and Earlier) Shopping > Newsletter JSON file NewsLetter.json Generic Last Name This string specifies the generic last name to populate in a new Lead record when a user opts in for the newsletter. This satisfies the record’s requirement to populate this field. ID newsletter.genericLastName UI Location Legacy > Newsletter UI Location (Aconcagua and Earlier) Shopping > Newsletter SuiteCommerce Site Development 115 Legacy Tab JSON file 116 NewsLetter.json Company Name This string specifies the generic company name to populate in a new Lead record when a user opts in for the newsletter. This satisfies the record’s requirement to populate this field. ID newsletter.company UI Location Legacy > Newsletter UI Location (Aconcagua and Earlier) Shopping > Newsletter JSON file NewsLetter.json Footer Subtab Applies to: SuiteCommerce | SuiteCommerce Advanced These settings configure the footer navigation links. Footer Navigation This array specifies the navigation links that appear in the footer. You can edit the default links or create new ones. Each link requires the following properties: ■ Text (string) – defines the text of the link that appears in the footer. ■ URL (string) – defines the target URL of the link. IDs footer.navigationLinks footer.navigationLinks.text footer.navigationLinks.href UI Location Legacy > Footer UI Location (Aconcagua and Earlier) Layout > Footer JSON file footer.json Configuration file (pre-Vinson) SC.Configuration.js Multi-Domain Tab Applies to: SuiteCommerce | SuiteCommerce Advanced The settings on this tab let you configure properties related to multiple domains. This tab includes the following subtabs: ■ Hosts Subtab ■ Translations Subtab SuiteCommerce Site Development Multi-Domain Tab 117 Hosts Subtab Applies to: SuiteCommerce | SuiteCommerce Advanced These settings configure information about each host for websites with multiple languages or regions. You must define a host for each language. More Information: Localization List of Hosts Specifies the host for each translated site. Use the following list to add your hosts by ID. For example, you can configure two different hosts. You set one for English and U.S. Dollars only. You set the remaining site for English and French with two currencies, U.S. Dollar and Euros. Important: Each language must have its own domain. Each host requires the following: ■ Host ID – specifies the host address for the translated content. ■ Language – specifies the languages available for the associated host location. ■ Language Title – specifies the display label of the currency within the Location dropdown selector on the website. ■ Language Domain – specifies the domain name for this language. This must exactly match the hosted domain for the associated language. ■ Currency – specifies the display label of the currency within the Location dropdown selector on the website. ■ Subsidiary – specifies the subsidiary for the host. ■ Location – specifies the location for the host. IDs multiDomain.hosts multiDomain.hosts.host multiDomain.hosts.language multiDomain.hosts.languageTitle multiDomain.hosts.languageDomain multiDomain.hosts.currency multiDomain.hosts.subsidiary multiDomain.hosts.location UI Location Multi-Domain > Hosts ID (pre-Vinson) hosts JSON file Languages.json Configuration file (pre-Vinson) Configuration.js Hosts Array Parameters (pre-Vinson) In pre-Vinson implementations, the hosts array, located in the backend Configuration.js file, maps languages and currencies to specific host locations. This array requires a title property and both the currencies and languages arrays, as defined below. SuiteCommerce Site Development Multi-Domain Tab 118 Note: The hosts array contains sample code that is hidden within a multi-line comment block. Removing the comment tags reveals this code, but the properties require customization unique to your site as defined below. ■ title (string) – specifies the display label of the location within the Location drop-down selector on the website. ■ currencies (array) – specifies the currencies available for the associated host location. □ title (string) – specifies the display label of the currency within the Location drop-down selector on the website. □ code (string) – specifies the code for the location. This maps the currency code with the specific host location and must exactly match the three-letter International Standards Organization (ISO) currency code symbol defined in the backend, or the currency will not appear in the list. See the help topic Currency Management for more information. ■ languages (array) – specifies the languages available for the associated host location □ title (string) – specifies the display label of the currency within the Location drop-down selector on the website. □ host (string) – specifies the host address for the translated content. This must exactly match the hosted domain for the associated language. For more information on setting up domains, see the help topic Domains □ locale (string) – specifies the country code and culture code for the associated language per ISO standards (ISO 639 and ISO 3166 respectively). This must match the locale property defined in the backend, or the language will not appear in the list. Example: en_US. Your website must have a unique locale for each hosted domain and a unique domain for each language. IDs (pre-Vinson) hosts hosts.title hosts.currencies hosts.currencies.title hosts.currencies.code hosts.languages hosts.languages.title hosts.languages.host hosts.languages.locale UI Location None Configuration file (pre-Vinson) Configuration.js Translations Subtab Applies to: SuiteCommerce | SuiteCommerce Advanced These settings configure multiple domains for a website to enable multiple languages or regions. List of Translations This array specifies new string translations or updates for existing strings. NetSuite recommends using this method to make small changes to the translated content on your site. If making significant changes to translated content on your site, see the help topic The Translation Process for details. Each translation array contains the following properties: SuiteCommerce Site Development Multi-Domain Tab ■ Key (string) – specifies the string being translated. ■ Language (string) – defines the localized string for each locale. More Information: Localization IDs extraTranslations extraTranslations.key extraTranslations.cs_CZ (Czech Republic) extraTranslations.da_DK (Danish) extraTranslations.de_DE (German) extraTranslations.en_US (English – US) extraTranslations.es_AR (Spanish – Argentina) extraTranslations.es_ES (Spanish – Spain) extraTranslations.fr_CA (French – Canada) extraTranslations.fr_FR (French – France) extraTranslations.it_IT (Italian) extraTranslations.ja_JP ()Japanese extraTranslations.ko_KR (Korean) extraTranslations.nl_NL (Dutch – Netherlands) extraTranslations.pt_BR (Portuguese – Brazil) extraTranslations.ru_RU (Russian) extraTranslations.sv_SE (Swedish) extraTranslations.th_TH (Thai) extraTranslations.tr_TR (Turkish) extraTranslations.zh_CN (Chinese) extraTranslations.zh_TW (Chinese – Taiwan) UI Location Multi-Domain > Translations JSON file Translations.json My Account Tab Applies to: SuiteCommerce | SuiteCommerce Advanced The settings on this tab let you configure properties related to the My Account application. This tab includes the following subtabs: ■ Addresses Subtab ■ Cases Subtab ■ List Header Subtab ■ Overview Subtab ■ Quotes Subtab ■ Return Authorization Subtab ■ SCIS Integration Subtab ■ Subscriptions Subtab ■ Transaction List Columns Subtab Addresses Subtab Applies to: SuiteCommerce | SuiteCommerce Advanced These settings configure properties related to addresses entered in My Account pages. SuiteCommerce Site Development 119 My Account Tab 120 Require a Phone Number With Addresses This boolean determines if users are required to include a phone number when saving an address to their account. If this property is checked, users must include a phone number when entering an address. If this property is unchecked, no phone number is required. This property is unchecked by default. ID addresses.isPhoneMandatory UI Location My Account > Addresses JSON file Address.json Cases Subtab Applies to: SuiteCommerce | SuiteCommerce Advanced These settings configure the initial required default case status values. Status Start ID This string specifies the NetSuite status Commerce web stores use to indicate that a case has been started. Options include: ■ 1 – Not Started ■ 2 – In Progress ■ 3 – Escalated ■ 4 – Re-opened ■ 5 – Closed ID cases.defaultValues.statusStart.id UI Location My Account > Cases JSON file Case.json Configuration file (pre-Vinson) Configuration.js Status Close ID This string specifies the NetSuite status Commerce web stores use to indicate the case has been closed. Options include: ■ 1 – Not Started ■ 2 – In Progress ■ 3 – Escalated ■ 4 – Re-opened ■ 5 – Closed ID cases.defaultValues.statusClose.id UI Location My Account > Cases SuiteCommerce Site Development My Account Tab JSON file Case.json Configuration file (pre-Vinson) Configuration.js Origin ID This string specifies the internal identifier of the case origin. ID cases.defaultValues.origin.id UI Location My Account > Cases JSON file Case.json Configuration file (pre-Vinson) Configuration.js List Header Subtab Applies to: SuiteCommerce | SuiteCommerce Advanced These settings specify properties that determine how lists of data and collections are displayed. The ListHeader module uses these properties. Filter Range Quantity Days This integer specifies the number of days within the date range used when displaying data. ID listHeader.filterRangeQuantityDays UI Location My Account > List Header JSON file ListHeader.json Configuration file (pre-Vinson) SC.MyAccount.Configuration.js Overview Subtab Applies to: SuiteCommerce | SuiteCommerce Advanced These settings configure the My Account page settings. Customer Support URL This string specifies the URL for your customer support page. ID overview.customerSupportURL UI Location My Account > Overview JSON file Overview.json Configuration file (pre-Vinson) SC.MyAccount.Configuration.js SuiteCommerce Site Development 121 My Account Tab 122 Recent Orders Quantity to Show This number specifies the quantity of recent orders displayed in the My Account Overview page. By default, the last three orders are displayed. ID overview.homeRecentOrdersQuantity UI Location My Account > Overview JSON file Overview.json Configuration file (pre-Vinson) SC.MyAccount.Configuration.js Home Banners This array specifies the banner to display in the index of My Account. You can configure this to customize promotions for clients. Each banner requires the following properties: ■ Image URL (string) – specifies the source image and URL. ■ Link URL (string) – specifies the URL link when a user clicks the image. ■ Link Target (string) – specifies the link target. IDs overview.homeBanners overview.homeBanners.imageSource overview.homeBanners.linkURL overview.homeBanners.linkTarget UI Location My Account > Overview JSON file Overview.json Configuration file (pre-Vinson) SC.MyAccount.Configuration.js Quotes Subtab Applies to: SuiteCommerce | SuiteCommerce Advanced These settings configure the behavior of the Quotes feature in Commerce web stores. More Information: Quotes Show Request A Quote Hyperlink This property applies to: ■ SuiteCommerce Advanced - 2018.2 and later ■ SuiteCommerce This boolean specifies whether the Request a Quote hyperlink displays. Select to display the Request a Quote hyperlink. The default value is: true. ID quote.showHyperlink UI Location My Account > Quotes SuiteCommerce Site Development My Account Tab JSON file 123 RequestQuoteAccessPoint.json Hyperlink Text This property applies to: ■ SuiteCommerce Advanced - 2018.2 and later ■ SuiteCommerce This string specifies the text of the Request a Quote hyperlink. The default value is: Request a Quote. ID quote.textHyperlink UI Location My Account > Quotes JSON file RequestQuoteAccessPoint.json Purchase Ready Status ID This string specifies the Customer Status that enables a quote to be purchased. This field must match the Internal ID of the Customer Status required for that customer to be able to make a purchase from the quote. In NetSuite, the Estimate record’s Status field lists all available Customer Statuses for the quote. When the merchant manually changes this field to the Customer Status whose Internal ID matches the Purchase Ready Status ID, all website links to Review or Purchasing pages are enabled. The user can then make a purchase. More Information: Set the Customer Internal ID ID quote.purchaseReadyStatusId UI Location My Account > Quotes ID (pre-Vinson) purchase_ready_status_id JSON file Quote.json Configuration file (pre-Vinson) Configuration.js Invoice Form ID This string specifies Internal ID of the invoice form that SCA uses to generate a sales order using terms. More Information: Define an Invoice Form ID quoteToSalesorderWizard.invoiceFormId UI Location My Account > Quotes ID (pre-Vinson) invoice_form_id JSON file QuoteSalesorderWizard.json Configuration file (pre-Vinson) Configuration.js SuiteCommerce Site Development My Account Tab 124 Days Before Expiration Notification This value specifies the number of days before a quote expires that the expiration notification displays on your web site. The default value is 7. All quotes use the same expiration notification configuration. More Information: Set Quote Expiration ID quote.daysToExpirationNotification UI Location My Account > Quotes JSON file Quote.json Days to Expiration This value specifies the number of days you want all quotes to remain valid after initial submittal. If this value is 0, the number of days to expiration is determined by the value in the Default Quote Expiration (In Days) field on the Sales Preferences record. See the help topic Sales Force Automation Preferences. All quotes use the same expiration configuration. After this time expires, the quote can no longer become a purchase. More Information: Set Quote Expiration ID quote.daysToExpire UI Location My Account > Quotes ID (pre-Vinson) days_to_expire JSON file Quote.json Configuration file (pre-Vinson) Configuration.js Disclaimer Summary This string specifies the sales representative disclaimer summary that appears under the Order Summary area of the Quote Details page. This message appears if no sales representative is assigned to the quote. What appears on your site depends on how your sales representative information is set up in your account. More Information: Customize Sales Representative Information ID quote.disclaimerSummary UI Location My Account > Quotes JSON file Quote.json Configuration file (pre-Vinson) SC.MyAccount.Configuration.js Disclaimer This string specifies the sales representative information disclaimer that appears at the bottom of the Quote Details page. This message appears if no sales representative is assigned to the quote. What appears on your site depends on how your sales representative information is set up in your account. SuiteCommerce Site Development My Account Tab 125 More Information: Customize Sales Representative Information ID quote.disclaimer UI Location My Account > Quotes JSON file Quote.json Configuration file (pre-Vinson) SC.MyAccount.Configuration.js Default Phone Number for Sales Rep This string specifies the default sales representative phone number. This phone number appears on the Quote Details page if a sales associate is assigned to the quote, but the phone number has not been assigned. What appears on your site depends on how your sales representative information is set up in your account. More Information: Customize Sales Representative Information ID quote.defaultPhone UI Location My Account > Quotes JSON file Quote.json Configuration file (pre-Vinson) SC.MyAccount.Configuration.js Default Email for Sales Rep This string specifies the default sales representative Email address. This email address appears on the Quote Details page if a sales associate is assigned to the quote, but the email address has not been assigned. What appears on your site depends on how your sales representative information is set up in your account. More Information: Customize Sales Representative Information ID quote.defaultEmail UI Location My Account > Quotes JSON file Quote.json Configuration file (pre-Vinson) SC.MyAccount.Configuration.js Request a Quote Bottom Message This string specifies the message shown when a quote is requested. The default text is: “ Once your quote has been submitted, a sales representative will contact you in <strong>XX business days</strong>. For immediate assistance call us at <strong>(000)-XXX-XXXX</strong> or email us at <a href='mailto:xxxx@xxxx.com'>xxxx@xxxx.com</a>" ID quote.requestAQuoteWizardBottomMessage UI Location My Account > Quotes SuiteCommerce Site Development My Account Tab JSON file 126 Quote.json Request a Quote Business Days This string specifies the sales representative contact message. The default text is: “A sales representative will contact you in <strong>XX business days</strong>.“ ID quote.contactBusinessDaysMessage UI Location My Account > Quotes JSON file Quote.json Return Authorization Subtab Applies to: SuiteCommerce | SuiteCommerce Advanced These settings configure properties related to the Return Authorization feature. Cancel URL Root This string specifies a custom domain used to override the domain used to cancel a return authorization. ID returnAuthorization.cancelUrlRoot UI Location My Account > Return Authorization JSON file ReturnAuthorization.json Configuration file (pre-Vinson) Configuration.js Return Authorizations Reasons This array defines the return reasons that are available to the user. Each reason specifies the following properties: ■ Reason (string) – specifies the text of the return reason. ■ ID (number) – specifies the internal ID of the return reason. Each item must have a unique ID. ■ Order (number) – specifies the order of the return reason in a drop down list. ■ Is Other (boolean) – specifies if the return reason is Other. IDs returnAuthorization.reasons.text returnAuthorization.reasons.id returnAuthorization.reasons.order returnAuthorization.reasons.isOther UI Location My Account > Return Authorization JSON file ReturnAuthorization.json SuiteCommerce Site Development My Account Tab Configuration file (pre-Vinson) 127 SC.MyAccount.Configuration.js SCIS Integration Subtab Applies to: SuiteCommerce | SuiteCommerce Advanced Is SCIS Integration Enabled This boolean enables or disables SCIS integration with your Commerce site. ID isSCISIntegrationEnabled UI Location My Account > SCIS Integration JSON file ReturnAuthorization.json Configuration file (pre-Vinson) Configuration.js Location Type Mapping Store Internal ID This string specifies the location-type identifier that Commerce web stores use to associate a transaction with an in-store purchase. 1 = store, 2 = online. ID locationTypeMapping.store.internalid UI Location My Account > SCIS Integration JSON file ReturnAuthorization.json Configuration file (pre-Vinson) Configuration.js Location Type Mapping Store Name This string specifies a descriptive text associated with the locationTypeMapping.store.internalid property. ID locationTypeMapping.store.name UI Location My Account > SCIS Integration JSON file ReturnAuthorization.json Configuration file (pre-Vinson) Configuration.js Transaction Record Origin Mapping This array specifies frontend properties related to what is displayed in a user's account. Each transaction record origin mapping object requires the following properties: ■ ID (string) – specifies the origin of the purchase record (backend, instore, online). ■ Origin (number) – specifies frontend properties related to what is displayed in a user's account. This is related to the locationTypeMapping.store.internalid property. SuiteCommerce Site Development My Account Tab 128 ■ Name (string) – specifies the text displayed in the Origin column of a user’s My Purchases list. ■ Detailed Name (string) – specifies the text displayed in the Purchase Details page. IDs transactionRecordOriginMapping transactionRecordOriginMapping.id transactionRecordOriginMapping.origin transactionRecordOriginMapping.name transactionRecordOriginMapping.detailedName UI Location My Account > Transaction Record Origin Mapping JSON file MyAccount.json Configuration file (pre-Vinson) SC.MyAccount.Configuration.js Subscriptions Subtab Applies to: SuiteCommerce | SuiteCommerce Advanced These properties provide configuration options for the SuiteBilling Subscriptions for Commerce feature: ■ Subscription Line Status Change ■ Allow the User to Cancel/Suspend Required Lines ■ Subscription General Status Change ■ Disallow the User to Upgrade Quantity ■ Disallow the User to Downgrade Quantity More information: SuiteBilling Subscriptions for Commerce Webstores Subscription Line Status Change This property applies to: ■ SuiteCommerce Advanced - 2019.2 and later ■ SuiteCommerce This string specifies whether the user can: ■ Suspend and resume a subscription line item ■ Cancel a subscription line item ■ Change the status of a subscription line item ID subscriptions.lineStatusChange UI Location My Account > Subscriptions JSON file subscriptions.json Allow The User to Cancel/Suspend Required Lines This property applies to: SuiteCommerce Site Development My Account Tab ■ SuiteCommerce Advanced - 2019.2 and later ■ SuiteCommerce This boolean specifies whether a user can cancel or suspend required subscription lines. ID subscriptions.allowToCancelSuspendRequiredLines UI Location My Account > Subscriptions JSON file subscriptions.json Subscription General Status Change This property applies to: ■ SuiteCommerce Advanced - 2019.2 and later ■ SuiteCommerce This string specifies whether the user can: ■ Suspend and resume a subscription ■ Cancel a subscription ■ Change the status of a subscription ID subscriptions.generalStatusChange UI Location My Account > Subscriptions JSON file subscriptions.json Disallow The User to Upgrade Quantity This property applies to: ■ SuiteCommerce Advanced - 2019.2 and later ■ SuiteCommerce This boolean specifies whether a user can increase the quantity of a subscription line item. ID subscriptions.disallowUpgradeQuantity UI Location My Account > Subscriptions JSON file subscriptions.json Disallow The User to Downgrade Quantity This property applies to: ■ SuiteCommerce Advanced - 2019.2 and later ■ SuiteCommerce SuiteCommerce Site Development 129 My Account Tab 130 This boolean specifies whether a user can decrease the quantity of a subscription line item. ID subscriptions.disallowDowngradeQuantity UI Location My Account > Subscriptions JSON file subscriptions.json Transaction List Columns Subtab Applies to: SuiteCommerce | SuiteCommerce Advanced The Transaction List Columns subtab lets you configure how transaction column fields appear in the My Account area of your site. When you enable column management for a list, you can specify what fields appear. You can configure the following transaction lists: ■ Order History ■ Quotes ■ Returns ■ Open Invoices ■ Paid Invoices Note: If you enable column management for a list, the configuration settings on the Transaction List Columns subtab take precedence over any other configuration. For example, if you are integrating SCIS with your site and enable columns management using the Transaction List Columns subtab, your My Account transaction columns render according to these settings. To retroactively add any columns from your SCIS integration, you create them manually as described below. More information: Transaction Lists Enable Return Authorization Columns Management This boolean enables or disables column management for the Returns transaction list. If this property is checked, the MyAccount application uses the properties set in the Transaction List Columns Return Authorization table to render the Return Authorization list on your site. This property is disabled by default. ID transactionListColumns.enableReturnAuthorization UI Location My Account > Transaction List Columns JSON file MyAccountReturnAuthorizationListsColumns.json Enable Quotes Columns Management This boolean enables or disables column management for the Quotes transaction list. If this property is checked, the MyAccount application uses the properties set in the Transaction List Columns Quote table to render the Quotes list on your site. This property is disabled by default. SuiteCommerce Site Development My Account Tab 131 For this column to appear, you must enable the Quotes feature for your account. See the help topic Quotes for more information. ID transactionListColumns.enableQuote UI Location My Account > Transaction List Columns JSON file MyAccountQuoteListsColumns.json Enable Order History Columns Management This boolean enables or disables column management for the Recent Purchases transaction list. If this property is checked, the MyAccount application uses the properties set in the Transaction List Columns Order History table to render the Purchase History list on your site. This property is disabled by default. ID transactionListColumns.enableOrderHistory UI Location My Account > Transaction List Columns JSON file MyAccountOrderHistoryListsColumns.json Enable Invoice Columns Management This boolean enables or disables column management for the Open Invoices transaction list. If this property is checked, the MyAccount application uses the properties set in the Transaction List Columns Open Invoices and Transaction List Columns Paid Invoices tables to render the Open and Paid Invoices list on your site. This property is disabled by default. ID transactionListColumns.enableInvoice UI Location My Account > Transaction List Columns JSON file MyAccountInvoiceListsColumns.json Transaction List Columns Return Authorization This array lets you add columns to the Returns transaction list. The order of the columns in this table determines the order they render on your site (top-down, left-to-right). Add a line for each field you intend to display on your site. The ID and Label properties are strings. The ID property must match the Field ID of the field you want to render. The default properties are: ■ trandate ■ quantity ■ amount ■ status Note: The Return No. column renders by default and cannot be configured. ID transactionListColumns.returnAuthorization transactionListColumns.returnAuthorization.id SuiteCommerce Site Development My Account Tab 132 transactionListColumns.returnAuthorization.label UI Location My Account > Transaction List Columns JSON file MyAccountReturnAuthorizationListsColumns.json Transaction List Columns Quote This array lets you add columns to the Quotes transaction list. The order of the columns in this table determines the order they render on your site (top-down, left-to-right). Add a line for each field you intend to display on your site. The ID and Label properties are strings. The ID property must match the Field ID of the field you want to render. The default properties are: ■ trandate ■ duedate ■ total ■ status Note: The Quote No. column renders by default and cannot be configured. ID transactionListColumns.quote transactionListColumns.quote.id transactionListColumns.quote.label UI Location My Account > Transaction List Columns JSON file MyAccountQuoteListsColumns.json Transaction List Columns Order History This array lets you add columns to the Order History transaction list. The order of the columns in this table determines the order they render on your site (top-down, left-to-right). Add a line for each field you intend to display on your site. The ID and Label properties are strings. The ID property must match the Field ID of the field you want to render. The default properties are: ■ date ■ amount ■ status Note: The Purchase No. and Track Items columns render by default and cannot be configured. ID transactionListColumns.orderHistory transactionListColumns.orderHistory.id transactionListColumns.orderHistory.label UI Location My Account > Transaction List Columns JSON file MyAccountOrderHistoryListsColumns.json SuiteCommerce Site Development My Account Tab 133 Transaction List Columns Open Invoices This array lets you add columns to the Open Invoices transaction list. The order of the columns in this table determines the order they render on your site (top-down, left-to-right). Add a line for each field you intend to display on your site. The ID and Label properties are strings. The ID property must match the Field ID of the field you want to render. The default properties are: ■ duedate ■ trandate ■ amount Note: The Invoice No. column renders by default and cannot be configured. ID transactionListColumns.invoiceOpen transactionListColumns.invoiceOpen.id transactionListColumns.invoiceOpen.label UI Location My Account > Transaction List Columns JSON file MyAccountInvoiceListsColumns.json Transaction List Columns Paid Invoices This array lets you add columns to the Paid Invoices transaction list. The order of the columns in this table determines the order they render on your site (top-down, left-to-right). Add a line for each field you intend to display on your site. The ID and Label properties are strings. The ID property must match the Field ID of the field you want to render. The default properties are: ■ trandate ■ closedate ■ amount Note: The Invoice No. column renders by default and cannot be configured. ID transactionListColumns.invoicePaid transactionListColumns.invoicePaid.id transactionListColumns.invoicePaid.label UI Location My Account > Transaction List Columns JSON file MyAccountInvoiceListsColumns.json Search Tab Applies to: SuiteCommerce | SuiteCommerce Advanced The settings on this tab let you configure properties related to site search. This tab includes the following subtabs: SuiteCommerce Site Development Search Tab 134 ■ Result Display Options Subtab ■ Result Sorting Subtab ■ Search Results Subtab ■ Search Results per Page Subtab ■ Type Ahead Subtab Result Display Options Subtab Applies to: SuiteCommerce | SuiteCommerce Advanced These settings specify display options for search results, grouped by browser type (desktop, phone, and tablet). Each display option contains the following properties (note the different property IDs for each browser type): ■ ID (string) – specifies the internal identifier of the display option. ■ Name (string) – specifies the label of the display option. ■ Template (string) – specifies the template used to display the search result option. ■ Columns (number) – specifies the number of columns used to display search results. This must be a divisor of 12 ( 1, 2, 3, 4, 6, 12). ■ Icon (string) – specifies the icon for the display option. ■ Is Default (boolean) – specifies that the display option is the default. Desktop This array specifies the display options for search results for desktop browsers. IDs itemsDisplayOptions itemsDisplayOptions.id itemsDisplayOptions. name itemsDisplayOptions.template itemsDisplayOptions.columns itemsDisplayOptions.icon itemsDisplayOptions.isDefault UI Location Search > Result Display Options JSON file SearchItemDisplayOptions.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js Phone This array specifies the display options for search results for phone browsers. IDs itemsDisplayOptionsPhone itemsDisplayOptionsPhone.id itemsDisplayOptionsPhone. name SuiteCommerce Site Development Search Tab 135 itemsDisplayOptionsPhone.template itemsDisplayOptionsPhone.columns itemsDisplayOptionsPhone.icon itemsDisplayOptionsPhone.isDefault UI Location Search > Result Display Options JSON file SearchItemDisplayOptions.json Tablet This array specifies the display options for search results for tablet browsers. IDs itemsDisplayOptionsTablet itemsDisplayOptionsTablet.id itemsDisplayOptionsTablet. name itemsDisplayOptionsTablet.template itemsDisplayOptionsTablet.columns itemsDisplayOptionsTablet.icon itemsDisplayOptionsTablet.isDefault UI Location Search > Result Display Options JSON file SearchItemDisplayOptions.json Result Sorting Subtab Applies to: SuiteCommerce | SuiteCommerce Advanced These settings specify the sorting options available in the Sort By drop down menu, grouped by browser type (desktop, phone, or tablet). Sort fields must first be defined in the Web Site Setup record. For details on defining sort fields, see the help topic Select and Configure Sort Fields. Each sort property contains the following (note the different property IDs for each browser type): ■ ID (string) – specifies the ID of the search option. ■ Name (string) – specifies the label used to identify the sort option. ■ Is Default (boolean) – specifies the default active search option. Desktop This array specifies the sorting options available in the Sort By drop down menu on desktop browsers. IDs sortOptions sortOptions.id sortOptions.name sortOptions.isDefault UI Location Search > Result Sorting JSON file SearchSort.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js SuiteCommerce Site Development Search Tab Phone This array specifies the sorting options available in the Sort By drop down menu on phone browsers. IDs sortOptionsPhone sortOptionsPhone.id sortOptionsPhone.name sortOptionsPhone.isDefault UI Location Search > Result Sorting JSON file SearchSort.json Tablet This array specifies the sorting options available in the Sort By drop down menu on tablet browsers. IDs sortOptionsTablet sortOptionsTablet.id sortOptionsTablet.name sortOptionsTablet.isDefault UI Location Search > Result Sorting JSON file SearchSort.json Search Results Subtab Applies to: SuiteCommerce | SuiteCommerce Advanced These settings configure properties related to the search feature in the application header. More Information: Select and Configure Sort Fields Search Results Title This string specifies the title for the facet browse view that appears in the application header. ID defaultSearchTitle UI Location Search > Search Results JSON file SearchResults.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js Search Keyword Maximum Length This number specifies the maximum number of characters the user can enter in the search field. ID SuiteCommerce Site Development searchPrefs.maxLength 136 Search Tab UI Location Search > Search Results JSON file SearchResults.json Configuration file (pre-Vinson) SC.Configuration.js 137 Search Results per Page Subtab Applies to: SuiteCommerce | SuiteCommerce Advanced These settings specify the options that appear in the Results Per Page drop down menu. This array contains the following properties: ■ Items (number) – specifies the number of search results displayed by this option. ■ Name (string) – specifies the label for this option. ■ Is Default (boolean) – specifies that this option is the default. IDs resultsPerPage resultsPerPage.items resultsPerPage.name resultsPerPage.isDefault UI Location Search > Search Results per Page JSON file SearchResultsPerPage.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js Type Ahead Subtab Applies to: SuiteCommerce | SuiteCommerce Advanced These settings define configuration properties for the Type Ahead feature. This feature causes Commerce web stores to begin returning search results while the user is entering text in the search text box. Min Length This number specifies the number of characters the user must enter before beginning the search. ID typeahead.minLength UI Location Search >Type Ahead JSON file SearchTypeAhead.json Configuration file (pre-Vinson) SC.Configuration.js Maximum Results This number specifies the maximum number of search results that are returned. SuiteCommerce Site Development Search Tab ID typeahead.maxResults UI Location Search > Type Ahead JSON file SearchTypeAhead.json Configuration file (pre-Vinson) SC.Configuration.js 138 Sort This string specifies the sort order of items returned by the Item Search API. By default, items are sorted by relevance in ascending order. However, you can sort by other criteria like the name property. ID typeahead.sort UI Location Search > Type Ahead JSON file SearchTypeAhead.json Configuration file (pre-Vinson) SC.Configuration.js Shopping Tab Applies to: SuiteCommerce | SuiteCommerce Advanced The settings on this tab let you configure properties related to the Shopping application and includes the following subtabs: ■ Item Options Subtab ■ Newsletter Subtab ■ Quick Order Subtab ■ Reviews Subtab ■ Wishlist Subtab Item Options Subtab Applies to: SuiteCommerce | SuiteCommerce Advanced This subtab moved to the Shopping Catalog tab in the Elbrus release of SuiteCommerce Advanced. See Item Options Subtab for more information on the properties related to Item Options. Newsletter Subtab Applies to: SuiteCommerce | SuiteCommerce Advanced This subtab moved to the Legacy tab in the 2018.2 release of SuiteCommerce and SCA. See Newsletter Subtab for more information on the properties related to Newsletter. SuiteCommerce Site Development Shopping Tab Quick Order Subtab Applies to: SuiteCommerce | SuiteCommerce Advanced These settings configure properties related to Quick Orders. More Information: Quick Order This feature and its settings require: ■ SuiteCommerce Advanced - 18.2 or later ■ SuiteCommerce Show Quick Order Hyperlink This boolean specifies whether the Quick Order hyperlink displays. Select to display the Quick Order hyperlink. The default value is: true. ID quickOrder.showHyperlink UI Location Shopping > Quick Order JSON file QuickOrder.json Hyperlink Text This string specifies the text of the Quick Order hyperlink. The default value is: Quick Order ID quickOrder.textHyperlink UI Location Shopping > Quick Order JSON file QuickOrder.json Reviews Subtab Applies to: SuiteCommerce | SuiteCommerce Advanced These settings configure properties related to product reviews. More Information: Product Reviews Max Flag Count This number specifies the number of flags a review must receive before being marked as flagged by users. ID productReviews.maxFlagsCount UI Location Shopping > Reviews SuiteCommerce Site Development 139 Shopping Tab JSON file ProductReviews.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js Login Required This boolean specifies if users must be logged in to create a review. ID productReviews.loginRequired UI Location Shopping > Reviews JSON file ProductReviews.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js Flagged Status This number specifies the number of times a review is flagged. If the value of the productReviews.maxFlagsCount property is reached, then this property is set to that value. ID productReviews.flaggedStatus UI Location Shopping > Reviews JSON file ProductReviews.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js Approved Status This number specifies the number of times the review has been approved by a user. ID productReviews.approvedStatus UI Location Shopping > Reviews JSON file ProductReviews.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js Pending Approval Status This number specifies the number of pending approvals the review has. ID productReviews.pendingApprovalStatus UI Location Shopping > Reviews JSON file ProductReviews.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js SuiteCommerce Site Development 140 Shopping Tab 141 Results per Page This number specifies the number of product reviews displayed per page. ID productReviews.resultsPerPage UI Location Shopping > Reviews JSON file ProductReviews.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js Max Rate This number specifies the maximum rating an item can receive. ID productReviews.maxRate UI Location Shopping > Reviews JSON file ProductReviews.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js Compute Overall This boolean, if checked, causes the application to compute and display the overall rating for the product. ID productReviews.computeOverall UI Location Shopping > Reviews JSON file ProductReviews.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js Filter Options This array specifies how product reviews are filtered and displayed. Each filter option defines the following properties: ■ ID (string) – specifies the internal identifier of the filter option. ■ Name (string) – specifies the label of the filter option as it appears in the user interface. ■ Params (string) – defines a JSON object that declares the URL parameters of the filter option. ■ Is Default (boolean) – specifies the default filter option displayed in the drop down list. IDs productReviews.filterOptions productReviews.filterOptions.id productReviews.filterOptions.name productReviews.filterOptions.params productReviews.filterOptions.isDefault UI Location Shopping > Reviews SuiteCommerce Site Development Shopping Tab JSON file ProductReviews.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js Sort Options This array specifies how product reviews are sorted. Each sort option defines the following properties: ■ ID (string) – specifies the internal identifier of the sort option. ■ Name (string) – specifies the label of the sort option as it appears in the user interface. ■ Params (string) – defines a JSON object that declares the URL parameters of the sort option. ■ Is Default (boolean) – specifies the default sort option displayed in the drop down list. IDs productReviews.sortOptions productReviews.sortOptions.id productReviews.sortOptions.name productReviews.sortOptions.params productReviews.sortOptions.isDefault UI Location Shopping > Reviews JSON file ProductReviews.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js Wishlist Subtab Applies to: SuiteCommerce | SuiteCommerce Advanced The settings on this subtab specify properties related to product lists. Product Lists (Wish Lists) provide the ability to group lists of items to be purchased from your web store. This subtab is part of the Shopping tab and contains the following properties: More Information: Product Lists Enable Modifications by Customers This boolean specifies if user is able to modify (add, edit, or delete) a private product list. ID productList.additionEnabled UI Location Shopping > Wishlist JSON file ProductList.json Configuration file (pre-Vinson) SC.Configuration.MyAccount.js Login Required This boolean specifies if users must be logged in to modify a product list. ID SuiteCommerce Site Development productList.loginRequired 142 Shopping Tab UI Location Shopping > Wishlist JSON file ProductList.json Configuration file (pre-Vinson) SC.Configuration.MyAccount.js List Templates This array specifies the pre-defined product lists (templates) that are automatically available to your web store users. Product lists defined here are predefined by default, meaning the user cannot modify or delete them. By default, a single predefined list (My List) is available. New customers will have these template lists by default. Associated records are created when a user adds a product to the list. Each product list contains the following properties: ■ Template ID (string) – specifies the internal identifier for this template. You must ensure that this value is unique. ■ Name (string) – specifies the name of the product list that appears in the user interface. ■ Description (string) – specifies a description of the product list that appears in the user interface. ■ Scope ID (number) – specifies the internal scope ID. ■ Scope Name (string) – specifies whether the product list is public or private. When scope is not explicitly declared, the default applied is private. ■ Type ID – (string) – specifies the internal type ID. ■ Type Name – (string) – defines the list as quote or later. Quote specifies the list to be added to a request for quote. Later specifies the list to be saved in the cart for later addition. More Information: Product ListsSave For Later IDs productList.listTemplates productList.listTemplates.templateId productList.listTemplates.name productList.listTemplates.description productList.listTemplates.scopeId productList.listTemplates.scopeName productList.listTemplates.typeId productList.listTemplates.typeName UI Location Shopping > Wishlist ID (pre-Vinson) product_lists_templates JSON file ProductList.json Configuration file (pre-Vinson) SC.Configuration.MyAccount.js Display Modalities for Product List Items This array specifies display options for product list items in a user’s My Account page. You can display items in various formats in a similar fashion to viewing items in the product display pages. For example, users can view items in a condensed list without images or in a list layout with images. By default, the condensed and list views are included. Each display modality contains the following properties: ■ ID (string) – specifies the display modality ID. ■ Name (string) – specifies the description of the modality. SuiteCommerce Site Development 143 Shopping Tab ■ Columns (number) – specifies the number of columns in the Product List. ■ Icon (string) – Specifies the item icon. ■ Is Default (boolean) – specifies the default modality. IDs productList.templates productList.templates.id productList.templates.name productList.templates.columns productList.templates.isDefault UI Location Shopping > Wishlist ID (pre-Vinson) product_lists_templates JSON file ProductList.json Configuration file (pre-Vinson) SC.Configuration.MyAccount.js Shopping Catalog Tab Applies to: SuiteCommerce | SuiteCommerce Advanced The settings on this tab let you configure properties related to the shopping, including shopping cart, facets, and product details. This tab includes overall catalog properties plus the following subtabs: ■ Facets Subtab ■ Facets Delimiters Subtab ■ Facets SEO Subtab ■ Item Options Subtab ■ Multi-Image Option Subtab ■ Product Details Information Subtab ■ Recently Viewed Items Subtab ■ Structured Data Markup Subtab Add to Cart Behavior This string specifies the action that occurs when the user adds an item to the cart. Possible values are: ■ showCartConfirmationModal (default) ■ goToCart ■ showMiniCart ■ showCartConfirmationModal ID addToCartBehavior UI Location Shopping Catalog JSON file Cart.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js SuiteCommerce Site Development 144 Shopping Catalog Tab 145 Add to Cart from Facets View This boolean specifies if a facet view displays the Add to Cart button on each search result. ID addToCartFromFacetsView UI Location Shopping Catalog JSON file Cart.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js Allow Adding More Than One PromoCode This property applies to: ■ SuiteCommerce Advanced - Elbrus and later ■ SuiteCommerce This boolean enables or disables the SuitePromotions feature. More Information: Promotions in Commerce Web Stores ID promocodes.allowMultiples UI Location Shopping Catalog JSON file Cart.json Allow custom matrix child search in the item list This property applies to: ■ SuiteCommerce Advanced - Kilimanjaro and later ■ SuiteCommerce This boolean enables or disables custom matrix child item search within the Item list. If this property is enabled, the item search uses the field set defined in the Matrix child items fieldset for search property for the Matrix Child Items (Detail) field. More Information: See the help topic Item Search API Input Parameters (matrixchilditems_fieldset parameter information). ID matrixchilditems.enabled UI Location Shopping Catalog JSON file Cart.json Matrix child items fieldset for search This property applies to: ■ SuiteCommerce Advanced - Kilimanjaro and later SuiteCommerce Site Development Shopping Catalog Tab 146 ■ SuiteCommerce This string defines the field set used with the custom matrix child item search feature. The default value of this field uses the matrixchilditems_search field set. This is part of the default field set setup script. However, you can customize this to match any custom matrix child item field set. Note: If this property is left blank, but the Allow custom matrix child search in the item list is enabled, the custom matrix child search feature will not process the custom field set. Instead, the application uses the default matrixchilditems field set. You can also set up this feature manually by customizing the Item Search API. More Information: See the help topic Item Search API Input Parameters (matrixchilditems_fieldset parameter information). ID matrixchilditems.fieldset UI Location Shopping Catalog JSON file Cart.json If the Information is Available to your Country, shows detailed taxes in the Cart This property applies to: ■ SuiteCommerce Advanced - Kilimanjaro and later ■ SuiteCommerce This boolean enables or disables the per line tax details in the Cart and purchase history. This applies to Australian and Canadian accounts using PST, GST, and VAT tax codes. More Information: Commerce Web Store Taxes ID showTaxDetailsPerLine UI Location Shopping Catalog JSON file Cart.json Enable Zoom for Images This boolean enables or disables zoom display of item images. This option is enabled by default so that images in the Product Details Page and Quick View display at zoom size when a user hovers over them. ID isZoomEnabled UI Location Shopping Catalog JSON file Cart.json Default Search URL This string specifies the default search URL. SuiteCommerce Site Development Shopping Catalog Tab ID defaultSearchUrl UI Location Shopping Catalog JSON file DefaultSearchURL.json Configuration file (pre-Vinson) Configuration.js 147 Maximum Option Values Quantity Without Pusher This property applies to: ■ SuiteCommerce Advanced - Elbrus and later ■ SuiteCommerce This number property indicates the maximum number of option values to appear in line on any mobile device's product details pages before displaying a pusher. For example, if an item lists two dimensions with four values each, the item has eight total values to render in the PDP. Setting this property to 6 results in listing the first dimension and its four values plus the second dimension and its first two values on a mobile device’s PDP before displaying a pusher. When a user touches the pusher, the next two item options appear in a new screen. Note: This property applies to the PDP on mobile devices only. ID ItemOptions.maximumOptionValuesQuantityWithoutPusher UI Location Shopping Catalog JSON file ProductDetails.ItemOptions.json Facets Subtab Applies to: SuiteCommerce | SuiteCommerce Advanced Facets as URL Parameters This property applies to: ■ SuiteCommerce Advanced - Elbrus and later ■ SuiteCommerce This boolean specifies if facets are treated as URL query string parameters or as part of the URL path. If checked, all facets are treated as parameters. If unchecked, all facets are treated as part of the URL path. This property applies behavior to all facets unless an individual facet’s isParameter property is specified. See Facets for details. This property is unchecked by default. Note: This can affect SEO. See the help topic Facets as Parameters for details. ID facetsAsUrlParameters SuiteCommerce Site Development Shopping Catalog Tab UI Location Shopping Catalog > Facets JSON file Facets.json 148 Facets More Information: Select and Configure Facet Fields These settings configure the faceted navigation feature. Commerce web stores use modern faceted navigation for displaying product results. With faceted navigation, users can incrementally refine search queries based on specific item attributes defined within the facet configuration. Each facet contains the following properties: ■ Item Field ID (string) – specifies the internal identifier of the facet being customized. The value must match the URL Component of the associated facet field as set up in NetSuite. If not specified in the object, the default is the facet field’s URL Component. If the URL Component is not set up in NetSuite, the default is the facet field’s Field ID. ■ Name (string) – specifies the display name for the facet as it appears in the browser. If not specified, the default equals the value of the id property. ■ URL (string) – specifies the URL fragment that identifies the facet in the URL. If no value is defined, SuiteCommerce web stores use the NetSuite list record ID. This property only applies to pre-Vinson release of SCA. ■ Priority (string) – sets the display order for the list of facet choices. Facets display in descending order of the priority value (largest priority value displays on top followed by smaller values). The priority value must be between 1 and 10. Default value is 5. ■ Behavior (string) – sets type of facet editor as it appears in the browser. If not specified, the default is single. Possible values are: □ Single (string) – displays a list from which users select a single choice. □ Multi (string) – displays a list from which users select multiple choices. □ Range (string) – displays a double slider from which users select a start and end value. ■ Template (string) – specifies the template that defines the HTML source code for the facet. If not specified, the default is facets_faceted_navigation_item_tpl. □ facets_faceted_navigation_item_color_tpl (string) – defines the template for a color facet. □ facets_faceted_navigation_item_range_tpl (string) – defines the template for a ranged facet. □ facets_faceted_navigation_item_tpl (string) – defines the template for any other facet. ■ Color Palette (string) – sets the HTML color values displayed for the facet. ■ Collapsed (boolean) – sets the default state of the facet. If selected, the facet renders in a collapsed state. ■ Non Collapsible (boolean) – specifies if the facet is collapsible and expandable. If set to Yes, the user can collapse or expand the facet by clicking an up/down arrow icon. If set to No, the facet cannot be collapsed or expanded. ■ Show Heading (boolean) – specifies if the facet heading displays in the browser. If set to Yes (checked/ enabled), a heading matching the value set in the name property displays. If set to No (unchecked/ disabled) or if left blank, the facet values display without a heading. ■ Title Format (string) – specifies the format for the facet title displayed when the facet is selected. This can be a string like from $(0) to $(1) for a range behavior or foo $(0) bar for others. Also it can be a function that accepts the facet object as a parameter. SuiteCommerce Site Development Shopping Catalog Tab 149 ■ Title Separator (string) – specifies a string used to separate facets in the page title. If not specified, the default is , (comma space). ■ Parser (string) – includes the user’s currency symbol ($, £, etc.) to the price range. If this value is not set, SuiteCommerce web stores do not display a currency symbol. ■ Is URL Parameter? (boolean) – specifies if the facet is treated as a parameter or as part of the URL path. If Facets as URL Parameters is checked for all facets, any individual facet with Is URL Parameter? set to false (unchecked) acts as part of the URL path. Likewise, if Facets as URL Parameters is unchecked, any individual facet with Is URL Parameter? set to true (checked) acts as a parameter. This property is available in SuiteCommerce and on the Elbrus release of SCA and later. ■ Max (number) – Specifies the limit of options available for a facet. After this options limit is reached, a see more link appears. This applies to mulit behavior. This is particularly useful for facets with a large amount of options to render. This property is available in SuiteCommerce and on the Elbrus release of SCA and later. More Information: Select and Configure Facet Fields IDs facets facets.id facets.name facets.url (pre-Vinson) facets.priority facets.behavior facets.template facets.colors facets.collapsed facets.uncollapsible facets.showHeading facets.titleToken facets.titleSeparator facets.parser facets.isParameter (Elbrus and later) facets.max (Elbrus and later) UI Location Shopping Catalog > Facets JSON file Facets.json Configuration file (pre-Vinson) SC.Checkout.Configuration.js Facets Delimiters Subtab Applies to: SuiteCommerce | SuiteCommerce Advanced These settings specify the characters within the URL that appear between facets, facet names, and their values and options. Ensure that each facet delimiter is unique. For example, if a user made the following facet selections: ■ Category – Shoes (a facet with a single selection behavior). ■ Color – black and brown (a facet with multiplet selection behavior). ■ Display – set to list results as a table. Based on the default delimiters, the URL will appear as: http://www.mystore.com/search/categories/shoes/color/black,brown?display=table SuiteCommerce Site Development Shopping Catalog Tab 150 Between Facet Name and Value This string specifies the character that appears between the facet name and value. The default value is /. NetSuite recommends introducing one character as the value for this property to prevent unexpected results. ID facetDelimiters.betweenFacetNameAndValue UI Location Shopping Catalog > Facet Delimiters JSON file FacetsDelimiters.json Configuration file (pre-Vinson) SC.Configuration.js Between Different Facets This string specifies the character that appears between different facets. The default value is /. NetSuite recommends introducing one character as the value for this property to prevent unexpected results. ID facetDelimiters.betweenDifferentFacets UI Location Shopping Catalog > Facet Delimiters JSON file FacetsDelimiters.json Configuration file (pre-Vinson) SC.Configuration.js Between Different Facets Values This string specifies the character that appears between different facet values. The default value is ,. ID facetDelimiters.betweenDifferentFacetsValues UI Location Shopping Catalog > Facet Delimiters JSON file FacetsDelimiters.json Configuration file (pre-Vinson) SC.Configuration.js Between Range Facets Values This string specifies the characters that delimit facet ranges. The default value is to. ID facetDelimiters.betweenRangeFacetsValues UI Location Shopping Catalog > Facet Delimiters JSON file FacetsDelimiters.json Configuration file (pre-Vinson) SC.Configuration.js Between Facets and Options This string specifies the character that appears between a facet and its options. The default value is ?. SuiteCommerce Site Development Shopping Catalog Tab ID facetDelimiters.betweenFacetsAndOptions UI Location Shopping Catalog > Facet Delimiters JSON file FacetsDelimiters.json Configuration file (pre-Vinson) SC.Configuration.js 151 Between Option Name and Value This string specifies the character that appears between the option name and its value. The default value is =. NetSuite recommends introducing one character as the value for this property to prevent unexpected results. ID facetDelimiters.betweenOptionNameAndValue UI Location Shopping Catalog > Facet Delimiters JSON file FacetsDelimiters.json Configuration file (pre-Vinson) SC.Configuration.js Between Different Options This string specifies the character that appears between two options. The default value is &. NetSuite recommends introducing one character as the value for this property to prevent unexpected results. ID facetDelimiters.betweenDifferentOptions UI Location Shopping Catalog > Facet Delimiters JSON file FacetsDelimiters.json Configuration file (pre-Vinson) SC.Configuration.js Facets SEO Subtab Applies to: SuiteCommerce | SuiteCommerce Advanced Use to define limits on the SEO-generated links in the facets browser. When these limits are reached, the URL is replaced with # in the generated links. More Information: SEO Page Generator Number of Facet Groups This string specifies how many facet groups are indexed. ID facetsSeoLimits.numberOfFacetsGroups UI Location Shopping Catalog > Facets SEO JSON file FacetSeoLimits.json SuiteCommerce Site Development Shopping Catalog Tab Configuration file (pre-Vinson) SC.Shopping.Configuration.js Number of Facet Values This string specifies how many multi-facet groups are grouped together. ID facetsSeoLimits.numberOfFacetsValues UI Location Shopping Catalog > Facets SEO JSON file FacetSeoLimits.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js Options This string specifies which URL options are indexed. If an option is not included here, it is not indexed when appearing in a URL. Valid values are: ■ order ■ page ■ show ■ display ■ keywords ID facetsSeoLimits.options UI Location Shopping Catalog > Facets SEO JSON file FacetSeoLimits.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js Item Options Subtab Applies to: SuiteCommerce | SuiteCommerce Advanced The Item Options subtab displays properties associated with how item options and custom transaction line fields display in your web store across the application. NetSuite provides some templates, as displayed in this tab. Show Only the Fields Listed In: Item Options and Custom Transaction Line Fields This property applies to: ■ SuiteCommerce Advanced - Elbrus and later ■ SuiteCommerce SuiteCommerce Site Development 152 Shopping Catalog Tab 153 This boolean specifies what item options and transaction line fields render in your web store. If unchecked (default), all custom transaction line fields and custom item options appear on your site. If checked, only those fields listed in the Item Options and Custom Transaction Line Fields table (on this subtab) appear. More Information: Commerce Custom Fields ID ItemOptions.showOnlyTheListedOptions UI Location Shopping Catalog > Item Options JSON file Item.Options.json Item Options and Custom Transaction Line Fields Note: This set of properties is titled Item Options in the Vinson release of SuiteCommerce Advanced. This section specifies how some custom fields display in your web store. For SuiteCommerce and the Elbrus release of SuiteCommerce Advanced and later, these properties include Item Options and Custom Transaction Line fields. For Vinson release and earlier, these properties only apply to Item Options. Each field listed in this table can contain the following properties: ■ Item Options ID (string) – specifies the internal identifier of the Custom Item Field being displayed. If declared, this matches the ID field of the corresponding Custom Item Field record in NetSuite. This property is only valid for the Vinson release of SuiteCommerce Advanced and earlier and is not required. ■ Cart Option ID (string) – specifies the internal identifier of the Item Option being displayed. This matches the ID field of the Item Option record you want to display on your site. This property is required and used as the primary key. ■ Color Palette (string) – maps a color label to its hexadecimal value. This object is used by the item options and faceted navigation. ■ Label (string) – specifies the text of the item option displayed in the user interface. ■ URL Parameter Name (string) – specifies the key of the option that appears in the URL. This property applies to Elbrus release and later. ■ Use Labels on URL (boolean) – specifies how the item option appears in the URL. If set to false (default), the URL displays the option’s Internal ID (for example, http://mysite.com/product/485? &color=1. If set to true, the URL contains the option's internal ID label. For example, http:// mysite.com/product/485?&color=blue. This property applies to Elbrus release and later. ■ Sort Index (integer) – specifies the position in which the current option displays in the PDP. The default value is 10. The lower the number, the sooner in the custom field renders. This property applies to Elbrus release and later. ■ Selector Template (string) – specifies the template that renders the item option or transaction column field in the PDP and the Cart. This template provides the user with a means to select an option (for example, Item Color = Blue). The associated field uses this template instead of the default selector template (as defined in the Default Selector Templates by Item Option Type property defined elsewhere on this subtab). ■ Show Option in Item Lists (boolean) – specifies if the item option appears in the faceted search results page. This property applies to Elbrus release and later. ■ Facet Cell Template (string) – specifies the template used to render the item on the faceted search results page. SuiteCommerce Site Development Shopping Catalog Tab 154 The associated field uses this template instead of the default facet cell template (as defined in the Default Facet Cell Templates by Item Option Type property defined elsewhere on this subtab). This property applies to Elbrus release and later. ■ Selected Template (string) – specifies the template used to render the item option or transaction column field in Checkout and My Account. The associated field uses this template instead of the default selected template (as defined in the Default Selected Templates by Item Option Type property defined elsewhere on this subtab). More Information: Commerce Custom Fields IDs ItemOptions.optionsConfiguration ItemOptions.optionsConfiguration.cartOptionId ItemOptions.optionsConfiguration.colors ItemOptions.optionsConfiguration.label ItemOptions.optionsConfiguration.urlParameterName ItemOptions.optionsConfiguration.useLabelsOnUrl ItemOptions.optionsConfiguration.index ItemOptions.optionsConfiguration.templateSelector ItemOptions.optionsConfiguration.showSelectorInList ItemOptions.optionsConfiguration.templateFacetCell ItemOptions.optionsConfiguration.templateSelected IDs (Pre-Elbrus) itemOptions itemOptions.itemOptionId itemOptions.cartOptionId itemOptions.colors itemOptions.label itemOptions.url itemOptions.templateSelected Note: In Vinson release of SCA, these properties are located on the Shopping tab and Item Options subtab. UI Location Shopping Catalog > Item Options JSON file Item.Options.json Configuration file (pre-Vinson) SC.Configuration.js Default Selected Templates by Item Option Type This property applies to: ■ SuiteCommerce Advanced - Elbrus and later ■ SuiteCommerce This array specifies default templates used to render a selected item option or transaction column field (by item option type) in Checkout and My Account. Each item option contains the following properties: ■ Option Type (string) – specifies the option type that uses the listed template. ■ Template Name (string) – specifies the default selected template used to render the field by item option type. More Information: Commerce Custom Fields IDs ItemOptions.defaultTemplates.selectedByType ItemOptions.defaultTemplates.selectedByType.type ItemOptions.defaultTemplates.selectedByType.template JSON file Transaction.Line.Views.ItemOptions.json SuiteCommerce Site Development Shopping Catalog Tab UI Location 155 Shopping Catalog > Item Options Default Selector Templates by Item Option Type This property applies to: ■ SuiteCommerce Advanced - Elbrus and later ■ SuiteCommerce This array specifies default templates used to select an item option (by type) in the Cart or Order Confirmation page. Each item option contains the following properties: ■ Option Type (string) – specifies the option types that uses the listed template. ■ Template Name (string) – specifies the default selector template used to render the item option type. More Information: Commerce Custom Fields IDs ItemOptions.defaultTemplates.selectorByType ItemOptions.defaultTemplates.selectorByType.type ItemOptions.defaultTemplates.selectorByType.template UI Location Shopping Catalog > Item Options JSON file ProductViews.ItemOptions.json Default Facet Cell Templates by Item Option Type This property applies to: ■ SuiteCommerce Advanced - Elbrus and later ■ SuiteCommerce This array specifies default templates used to render an item option (by type) the facets search results page. Each item option contains the following properties: ■ Option Type (string) – specifies the option types that use the listed template. ■ Template Name (string) – specifies the default facets template used to render the item option type. IDs ItemOptions.defaultTemplates.facetCellByType ItemOptions.defaultTemplates.facetCellByType.type ItemOptions.defaultTemplates.facetCellByType.template UI Location Shopping Catalog > Item Options JSON file ProductViews.ItemOptions.json Multi-Image Option Subtab Applies to: SuiteCommerce | SuiteCommerce Advanced This subtab displays properties that configure what item option fields are used to display the final image for the selected product in the PDP. In SuiteCommerce and the Elbrus release of SCA and later, the image change capability extends to configuring two or more item option IDs. SuiteCommerce Site Development Shopping Catalog Tab 156 More Information: Setting Up Multiple Images for an Item ID productline.multiImageOption UI Location Shopping Catalog > Multi-Image Option UI Location (pre-Elbrus) Layout > Images JSON file ProductLine.MultiImages.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js Product Details Information Subtab Applies to: SuiteCommerce | SuiteCommerce Advanced The Product Details Information subtab lets you add detailed information about an item in a stacked list on the Product Details Page. Each entry creates a tab in the PDP. This tab provides information stored in a Item record field and displays it in your web store. Each entry contains the following properties: ■ Name (string) – specifies the label displayed (as a tab) on the PDP. ■ ID (string) – specifies the Item record field value to display under the associated tab in the PDP. ■ Opened (boolean) – specifies if the section is open when the page loads. This property applies to preElbrus implementations of SCA. ■ Itemprop (string) – specifies the itemprop HTML attribute (as defined by schema.org). This property is optional. This property applies to: ■ SuiteCommerce Advanced - Elbrus and later ■ SuiteCommerce IDs productDetailsInformation productDetailsInformation.name productDetailsInformation.contentFromKey productDetailsInformation.itemprop IDs (pre-Elbrus) itemDetails itemDetails.name itemDetails.contentFormatKey itemDetails.opened itemDetails.itemprop Note: These properties appear in the Shopping Catalog tab and Item Details subtab in Vinson implementations of SCA. UI Location Shopping Catalog > Product Details Information UI Location (pre-Elbrus) Shopping Catalog > Item Details JSON file ProductDetails.Information.json Configuration file (pre-Vinson) SC.Configuration.js For example: The following configuration results in a tab on your PDP titled Details that displays information stored in the storedetaildescription field in the Item record. SuiteCommerce Site Development Shopping Catalog Tab Recently Viewed Items Subtab Applies to: SuiteCommerce | SuiteCommerce Advanced These settings specify how recently viewed items are displayed. Use Cookies for Recently Viewed Items This boolean specifies if recently viewed items are tracked with a browser cookie. ID recentlyViewedItems.useCookie UI Location Shopping Catalog > Recently Viewed Items JSON file RecentlyViewedItems.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js Number of Displayed Items This integer specifies the number of recently viewed items to display. The default value is: 6. ID recentlyViewedItems.numberOfItemsDisplayed UI Location Shopping Catalog > Recently Viewed Items JSON file RecentlyViewedItems.json Configuration file (pre-Vinson) SC.Shopping.Configuration.js SuiteCommerce Site Development 157 Shopping Catalog Tab 158 Structured Data Markup Subtab Applies to: SuiteCommerce | SuiteCommerce Advanced These settings specify the type of structured data used on the domain. Markup Type This property applies to: ■ SuiteCommerce Advanced - 2020.1 and later ■ SuiteCommerce This string specifies the type of markup used for all items. Options include: ■ No Markup ■ JSON-LD ID structureddatamarkup.type UI Location Shopping Catalog > Structured Data Markup JSON file structureddatamarkup.json Out of Stock Behavior (When Item Back Orders are Allowed) This property applies to: ■ SuiteCommerce Advanced - 2020.1 and later ■ SuiteCommerce This string specifies how out-of-stock items are shown when back orders are allowed. This option affects the markup for all items. The default is InStock. Options include: ■ InStock ■ PreOrder ID structureddatamarkup.availabilityonbackorder UI Location Shopping Catalog > Structured Data Markup JSON file structureddatamarkup.json Store Locator Tab Applies to: SuiteCommerce | SuiteCommerce Advanced The settings on this tab let you configure properties related to the Store Locator feature. This tab includes the following subtabs: ■ Store Locator Subtab ■ Store Locator Google Maps Subtab SuiteCommerce Site Development Store Locator Tab 159 Store Locator Subtab Applies to: SuiteCommerce | SuiteCommerce Advanced These settings specify the what information is returned when using the Store Locator feature. This feature and its settings require: ■ SuiteCommerce Advanced - Vinson and later ■ SuiteCommerce More Information: Store Locator Icons > Stores This string specifies the store marker icon that appears in the store list, next to the name of the store and in the Store Information popup (if enabled). ID storeLocator.icons.stores UI Location Store Locator > Store Locator JSON file StoreLocator.json Icons > Position This string specifies the store marker icon that appears on the map at the store’s relative location. ID storeLocator.icons.position UI Location Store Locator > Store Locator JSON file StoreLocator.json Icons > Autocomplete This string specifies the store marker icon that appears to the left of the store name within the predicted results of the auto-complete list. ID storeLocator.icons.autocomplete UI Location Store Locator > Store Locator JSON file StoreLocator.json Zoom Level in PDP This number specifies the zoom level to be applied in the map when viewing specific store details (applied in StoreLocator.Details.View.js). Default value is 17. ID storeLocator.zoomInDetails UI Location Store Locator > Store Locator SuiteCommerce Site Development Store Locator Tab JSON file 160 StoreLocator.json Show Store Popup This boolean enables or disables the Store Information popup on the map when a user hovers the pointer over the associated store in the Store Locator list. This is enabled by default. ID storeLocator.openPopupOnMouseOver UI Location Store Locator > Store Locator JSON file StoreLocator.json Title This string specifies the title of the Store Locator feature as rendered on the main view and in the header. The default is Store Locator. ID storeLocator.title UI Location Store Locator > Store Locator JSON file StoreLocator.json Is Enabled This boolean enables or disables the Store Locator feature. This is enabled by default. ID storeLocator.isEnabled UI Location Store Locator > Store Locator JSON file StoreLocator.json Radius This number specifies the search radius from the current location or entered address in which to display stores on the map. The radius units can be configured for kilometers or miles using a different configuration property. The default radius is 50. ID storeLocator.radius UI Location Store Locator > Store Locator JSON file StoreLocator.json Show Localization Map This boolean enables or disables a search map on mobile devices. If this property is set to true, a small map appears at the top of the screen on mobile devices while searching for an address. This property applies to mobile devices only. SuiteCommerce Site Development Store Locator Tab ID storeLocator.showLocalizationMap UI Location Store Locator > Store Locator JSON file StoreLocator.json 161 Number of Stores per Page This number specifies the number of stores listed per page if a shopper selects the See complete list of stores link. The default is 28. ID storeLocator.showAllStoresRecordsPerPage UI Location Store Locator > Store Locator JSON file StoreLocator.json Default Type of Locations This string specifies the type of stores to return (stores, warehouses, or both). If no property is specified, the map and list display both location types. Possible values are: ■ 1 – returns only locations listed as Stores in NetSuite. ■ 2 – returns only locations listed as Warehouse. ■ Leave blank for both ID storeLocator.defaultTypeLocations UI Location Store Locator > Store Locator JSON file StoreLocator.json Default Quantity of Locations This number specifies the maximum number of locations returned if no results exist within the search radius specified using the Radius property. ID storeLocator.defaultQuantityLocations UI Location Store Locator > Store Locator JSON file StoreLocator.json Distance Unit This string specifies the measurement units of the configured radius. Possible values are mi (miles) or km (kilometers). The default is miles. ID storeLocator.distanceUnit UI Location Store Locator > Store Locator SuiteCommerce Site Development Store Locator Tab JSON file 162 StoreLocator.json Store Locator Google Maps Subtab Applies to: SuiteCommerce | SuiteCommerce Advanced These settings specify the Google Maps properties for use with the Store Locator feature. This feature and its settings require: ■ SuiteCommerce Advanced - Vinson and later ■ SuiteCommerce More Information: Store Locator Google > API Key This string specifies the Google Maps API key for the mapping engine. Important: The Store Locator feature uses the Google Maps JavaScript API. For this feature to work properly on your site, you must acquire an authentication API key from Google. ID storeLocator.apiKey UI Location Store Locator > Store Locator Google Maps JSON file StoreLocatorGoogle.json Google > Center Position Latitude This number specifies the default Google-specific latitude position (as a string) to center the map when geolocation is disabled. ID storeLocator.mapOptions.centerPosition.latitude UI Location Store Locator > Store Locator Google Maps JSON file StoreLocatorGoogle.json Google > Center Position Longitude This number specifies the default Google-specific longitude position (as a string) to center the map when geolocation is disabled. ID storeLocator.mapOptions.centerPosition.longitude UI Location Store Locator > Store Locator Google Maps JSON file StoreLocatorGoogle.json SuiteCommerce Site Development Store Locator Tab 163 Google > Zoom Level This number specifies the Google-specific default map zoom level. The default is 11. ID storeLocator.mapOptions.zoom UI Location Store Locator > Store Locator Google Maps JSON file StoreLocatorGoogle.json Google > MapTypeControl This boolean enables or disables the Google-specific Map Type Control. The Map Type Control lets the shopper choose the map type (roadmap, satellite, etc.). If this property is set to true, the map displays this control in the upper left corner of the map. Setting this property to false disables this control. ID storeLocator.mapOptions.mapTypeControl UI Location Store Locator > Store Locator Google Maps JSON file StoreLocatorGoogle.json Google > StreetViewControl This boolean enables or disables the Google-specific Street View Pegman icon. The Pegman icon is a Google-specific control that can be dragged onto the map to enable Street View. If this property is set to true, the map displays this control in the lower right corner of the map. Setting this property to false disables the control. ID storeLocator.mapOptions.streetViewControl UI Location Store Locator > Store Locator Google Maps JSON file StoreLocatorGoogle.json Google > MapTypeID This string specifies the Google-specific default map type. Options include (as string): ■ roadmap – displays the default road map view (default) ■ satellite – displays Google Earth satellite images ■ hybrid – displays a mixture of normal and satellite views ■ terrain – displays a physical map based on terrain information ID storeLocator.mapOptions.mapTypeId UI Location Store Locator > Store Locator Google Maps JSON file StoreLocatorGoogle.json SuiteCommerce Site Development Configuration File Types 164 Configuration File Types Applies to: SuiteCommerce | SuiteCommerce Advanced | SuiteCommerce | SuiteCommerce Advanced This section explains the different configuration files you may encounter when implementing a Commerce web store. The types of files and their purpose differ depending on your implementation. ■ For developing configuration properties for SuiteCommerce, SuiteCommerce MyAccount, and all Vinson implementations of SuiteCommerce Advanced (SCA) and later, see JSON Configuration Files. ■ For configuring Mont Blanc and Denali implementations of SCA, see JavaScript Configuration Files. JSON Configuration Files Applies to: SuiteCommerce | SuiteCommerce Advanced | SuiteCommerce | SuiteCommerce Advanced Commerce web store configuration requires the SuiteCommerce Configuration record. This presents a user interface to easily change configuration settings for a specified domain. Any changes made in this record save to a custom record and apply at runtime, as described below. The SuiteCommerce Configuration record is all that is required to configure properties for a domain. The user interface of this record depends on the following files: ■ JSON files – These files specify configurable properties and metadata related to a module. Modules that include configuration properties contain a subdirectory called Configuration, which contains these individual JSON files. ■ configurationManifest.json – When you activate an extension that includes configuration files, the application concatenates the individual JSON files into the configurationManifest.json file, located in the File Cabinet. If testing locally, you must deploy and activate your extension to see these changes. Metadata stored in this auto-generated file determines the appearance and behavior of the SuiteCommerce Configuration record in NetSuite. Note: JSON configuration files affect the user interface of the SuiteCommerce Configuration record only. They do not configure a domain. To configure properties for a specific domain, see Configure Properties. The following diagram provides an overview of JSON configuration as it relates to Commerce web stores: SuiteCommerce Site Development JSON Configuration Files 165 1. Individual JSON configuration files specify configurable properties and metadata to be used by the SuiteCommerce Configuration record. These files are stored in the modules using the related properties. 2. When you activate an extension for a domain, the application concatenates any JSON configuration files into one configurationManifest.json file. 3. The metadata in the configurationManifest.json file determines what appears in the user interface of the SuiteCommerce Configuration record. The metadata for each property specifies important metadata about each property, including tab or subtab location, titles, possible values, default values of each property, etc. This metadata may optionally also include conditional group (tab) and subtab display logic. The configurationManifest.json file sets this information for all domains linked to the associated SSP Application. 4. At runtime, the application uses the default values declared in the configurationManifest.json file to implement configuration properties. 5. If you modify and save the SuiteCommerce Configuration record, these values exist in a custom record and merge with the data from the configurationManifest.json file at runtime. These changes take precedence over any corresponding values stored in the configurationManifest.json file for the associated domain. Note: The manifest determines the user interface of the SuiteCommerce Configuration record and default property values used by all domains. When you save changes to the SuiteCommerce Configuration record, you create a custom record for the selected domain. To make changes to multiple domains, you must configure each domain individually or use the Copy Configuration functionality. If you do not save any changes to the SuiteCommerce Configuration record, only the values stored in the configurationManifest.json apply at runtime. For example, the Case.json file determines how properties associated with the Case feature appear in the SuiteCommerce Configuration record user interface. This information can include the tab or subtab where a property appears, the default value, and optional values for the property, among other things. When you deploy and activate your extension, the individual JSON configuration files concatenate into one configurationManifest.json file. When you access the SuiteCommerce Configuration record, this manifest defines what you see in the user interface. You then use the record to configure your site. SuiteCommerce Site Development JSON Configuration Files 166 Important: If you are implementing a SuiteCommerce Advanced site using a release prior to Aconcagua, this process occurs when you deploy your customizations to NetSuite. See Create JSON Configuration Files for details on how to add new or modify core JSON configuration files. Create JSON Configuration Files Applies to: SuiteCommerce | SuiteCommerce Advanced | SuiteCommerce | SuiteCommerce Advanced This section explains how to create a custom configuration file. This is useful when creating custom configuration properties for your extension. When you deploy your extension to NetSuite and activate it for a domain, the SuiteCommerce Configuration record user interface reflects any additions specified. Note: If you are implementing the Kilimanjaro release of SCA or earlier, these changes occur when you deploy your custom modules. If you are implementing the Mont Blanc release of SCA or earlier, you must customize configuration JavaScript files to introduce any changes to configuration. See Customize and Extend Core SuiteCommerce Advanced Modules for details. JSON Configuration Files Schema Applies to: SuiteCommerce | SuiteCommerce Advanced | SuiteCommerce | SuiteCommerce Advanced Creating a custom JSON configuration file requires using a custom module and building a new configuration file using JSON Schema V4. Follow this schema when introducing new properties associated with a custom module. Important: Configuration property keys must only contain alphanumeric characters and periods. The developer tools will not deploy configuration customizations that include special characters or spaces. Keys must also be unique across all configuration files. Note: This schema is compliant with Schema V4. JSON schemas, ensuring that all configuration files use a consistent structure and define required objects. For more information, see jsonschema.org. General Structure Each configuration file contains a root object that defines the configuration information for a module. At the root level, all configuration files must define the type, group, and properties objects. This schema allows for the addition of the subtab object as an option. The following example depicts the general structure and order of a JSON configuration file. //... { "type": "object", "group": { //... }, "properties": { //... } } //... SuiteCommerce Site Development JSON Configuration Files 167 Type The type object specifies the type of object defined by the configuration file. The value of this object must always be set to object and it must be specified in the first line of the configuration file. This is required to be compliant with the JSON schema specification. //... { } //... "type": "object", //... Group The SCA Configuration record uses this metadata to determine the tab in which to display configuration properties. The group object defines the following: ■ id – defines an internal identifier for the tab in the SuiteCommerce Configuration record. The id must only contain alphanumeric characters and periods (no other special characters or spaces), and must be unique across all configuration files. ■ title – defines the label of the tab displayed in the SuiteCommerce Configuration record. ■ description – provides a description of the group object. Additional metadata in the group object may also control which groups appear in the SuiteCommerce Configuration record user interface. See Conditional Display of Groups and Subtabs. The following example, taken from the checkoutApplications.json file, initiates the Checkout tab using the group id (checkoutApp). Any subtabs or properties appearing in this tab of the UI must declare this group id. //... "group": { "id": "checkoutApp", "title": "Checkout", "description": "Checkout Application configuration" }, //... Subtab The SCA Configuration record uses this metadata to determine the subtab in which to display any nested properties. The subtab object, if used, defines the following: ■ id – defines an internal identifier for the subtab in the SuiteCommerce Configuration record. The id must only contain alphanumeric characters and periods (no other special characters or spaces), and must be unique across all configuration files. ■ title – defines the label of the subtab displayed in the SuiteCommerce Configuration record. ■ description – provides a description of the subtab object. ■ group – defines the group object to which the subtab is assigned. This is the tab where the subtab appears in the UI. Additional metadata in the Subtab object may also control which subtabs appear in the SuiteCommerce Configuration record user interface. See Conditional Display of Groups and Subtabs. The following example, taken from the checkoutApplications.json file, initiates the Forms subtab using the subtab id (checkoutForms) and group id (checkoutApp). This locates the Forms subtab within the Checkout tab, as shown in the following image. SuiteCommerce Site Development JSON Configuration Files //... { //... 168 "subtab": { "id": "checkoutForms", "title": "Forms", "description": "Checkout configuration related to web forms.", "group": "checkoutApp" }, Conditional Display of Groups and Subtabs To control the display of specific groups (tabs) and subtabs based on the website scope and features enabled in your account, add conditional display keys to module and extension JSON configuration files. These conditional display keys apply to group and subtab objects. The conditional display keys do not apply to individual properties. There are two important considerations when using conditional display keys: ■ You may use one or more condition keys to control the display of a group and subtab. ■ All used condition keys must evaluate to true to conditionally display the group or subtab. There are two valid website scope keys and three valid feature keys. Valid Website Scope Keys (case-sensitive) ■ showIfNoneWebsiteScope Use this key to conditionally display a group or subtab based on a specific website scope (website type) not implemented in your account. ■ showIfAnyWebsiteScope Use this key to conditionally display a group or subtab based on a specific website scope (website type) implemented in your account. SuiteCommerce Site Development JSON Configuration Files 169 Valid Website Scope Values (case-sensitive) Website Scope Value SuiteCommerce SUITE_COMMERCE SuiteCommerce Advanced SUITE_COMMERCE_ADVANCED SuiteCommerce MyAccount SUITE_COMMERCE_MY_ACCCOUNT SuiteCommerce InStore SUITE_COMMERCE_IN_STORE Site Builder Full Web Store FULL_WEB_STORE Site Builder Information and Catalog with Pricing INFO_CATALOG_PRICING Site Builder Information Only INFO_ONLY Valid Feature Keys ■ showIfNoneFeatures Use this key to conditionally display a group or subtab based on a specific feature not implemented in your account. ■ showIfAnyFeatures Use this key to conditionally display a group or subtab based on one or more specific features implemented in your account. ■ showIfAllFeatures Use this key to conditionally display a group or subtab based on a specific set of features all implemented in your account. Valid Feature Values (case-sensitive) Field IDs are used for feature key values. To find the valid values (Field IDs) for feature keys: 1. In NetSuite, go to Home > Set Preferences. 2. In the Defaults section, enable the Show Internal IDs option. 3. Click Save. 4. Go to Setup > Company > Enable Features. 5. Click on the field title of any of the available features to display the field level help. The Field ID is shown at the bottom right portion of the field help text. Field ID Example: Example: The sample below shows how to edit the CheckoutApplication.json file to condition the display of the Checkout group (tab) and Forms subtab by adding conditional website scope and feature keys to the SuiteCommerce Site Development JSON Configuration Files 170 group and subtab objects. This file is located in the Configuration folder of your CheckoutAppplication module folder. In the example code below, the Checkout group (tab) and Forms subtab will only display if the following conditions are true: ■ You are not implementing SuiteCommerce In Store ■ You are implementing either SuiteCommerce Advanced or SuiteCommerce ■ You are not implementing the Web Duplicated Email Management feature ■ You are implementing the Multilanguage or Multicurrency feature ■ You are implementing Advanced Site Management and Commerce Search Analytics features on a SuiteCommerce Advanced site { ... "type": "object", "group": { "id": "checkoutApp", "title": "Checkout", "docRef": "bridgehead_4393268798", "description": "Checkout Application configuration" "showIfNoneWebsiteScope":["SUITE_COMMERCE_IN_STORE"], "showIfAnyWebsiteScope":["SUITE_COMMERCE_ADVANCED","SUITE_COMMERCE"], "showIfNoneFeatures":["webduplicateemailmanagement"], "showIfAnyFeatures":["multilanguage","multicurrency"]. "showIfAllFeatures":["suitecommerce_advanced","advancedsitemanagement","commercesearchanalytics"] }, "subtab": { "id": "checkoutForms", "title": "Forms", "docRef": "section_4700765645", "description": "Checkout configuration related to web forms.", "group": "checkoutApp", "showIfNoneWebsiteScope":["SUITE_COMMERCE_IN_STORE"], "showIfAnyWebsiteScope":["SUITE_COMMERCE_ADVANCED","SUITE_COMMERCE"], "showIfNoneFeatures":["webduplicateemailmanagement"], "showIfAnyFeatures":["multilanguage","multicurrency"], "showIfAllFeatures":["suitecommerce_advanced","advancedsitemanagement","commercesearchanalytics"] }, Resource The resource object specifies data available as a resource within the configurationManifest.json file. You can later refer to this resource using the source of a properties object to determine the possible choices of a configurable property. In the following example from categories.json, the resource object defines the commerce category fields to make available as a resource. //... "resource": { "fields": { "commercecategory": [ "internalid", "name", "description", "pagetitle", "pageheading", "pagebannerurl" //... ] } } //... Properties The properties object defines the configuration properties for a module. This object can define one or more properties as object literals. These object literals define the associated property’s members/ attributes and their values, delimited by commas. SuiteCommerce Site Development JSON Configuration Files 171 Each properties object can define values for the following: ■ Id ■ Group ■ Subtab ■ Type ■ Title ■ Description ■ Items ■ Enum ■ Multiselect ■ Default ■ Mandatory ■ Translate ■ Source ■ Hidden ■ Nstype Id The id is the key used in the properties object as the property object declaration. This forms the location of the property in the final configuration object structure. The id is required. The id must only contain alphanumeric characters and periods (no other special characters or spaces), and must be unique across all configuration files. In the following example, the property declaration, productReviews.maxFlagCount": {type: "string", ...}, results in the following configuration object: //... { productReviews: { maxFlagCount: 1 } } //... Group The group attribute specifies the id of the corresponding group object (tab) where the property appears in the UI. This attribute is required. The following example from checkoutApp.json defines the group value of the checkoutApp.skipLogin property as checkoutApp. As a result, this property appears on the Checkout tab in the UI: //... , "properties": { "checkoutApp.skipLogin": { "group": "checkoutApp", "type": "boolean", "title": "Skip Checkout Login", "description": "Check this box to enable anonymous users to skip the login/register page...", "default": false }, //... SuiteCommerce Site Development JSON Configuration Files 172 Subtab The subtab attribute specifies the id of the corresponding subtab object (subtab) where the configurable property appears in the UI. The following example from checkoutApp.json defines the subtab value of the autoPopulateNameAndEmail property as checkoutForms, defined earlier. Note that this property also declares the group associated with the Checkout tab. As a result, this property appears on the Checkout tab and the Forms subtab in the UI: //... //... "autoPopulateNameAndEmail": { "group": "checkoutApp", "subtab": "checkoutForms", "type": "boolean", "title": "Auto populate name and email", "description": "Check this box to enable auto-population of a guest shopper's name...", "default": true }, Type The type attribute specifies the data type of the configurable property. If specified, the user must enter a value of this type in the SuiteCommerce Configuration record. This must be a valid JSON-supported type: integer, string, boolean, array, or object. This attribute is required. The following example from checkoutApp.json defines the checkoutApp.skipLogin property is defined as a boolean: //... , "properties": { "checkoutApp.skipLogin": { "group": "checkoutApp", "type": "boolean", "title": "Skip Checkout Login", "description": "Check this box to enable anonymous users to skip the login/register page...", "default": false }, //... Title The title attribute defines the label that appears in the SuiteCommerce Configuration record. In the preceding example, the SuiteCommerce Configuration record displays the checkoutApp.skipLogin property as Skip Checkout Login. This attribute is required. Description The description attribute specifies a string that displays as help text when a user points to a label in the SuiteCommerce Configuration record. Any property, subtab, or group can declare a description. The SuiteCommerce Configuration record displays the description on simple properties only. Items If a property’s type value is set to an array, items is required to define the different properties of the table in the SuiteCommerce Configuration record. The following example from facets.json initializes Facets as “type” : “array”. This displays as an array of properties in the SuiteCommerce Configuration record. The items attribute defines metadata to further define each configurable property (column), as shown in the image below. SuiteCommerce Site Development JSON Configuration Files 173 //... "facets": { "group": "catalog", "type": "array", "title": "Facets", "docRef": "bridgehead_4393383668", "description": "Facets editor declarations", "items": { "type": "object", "properties": { "id": { "type": "string", "title": "item field id", "description": "Netsuite item field id, something like 'custitem31'", "mandatory": true }, "name": { "type": "string", "title": "Name", "translate": true, "description": "Label for this facet in the UI", "mandatory": true }, "url": { "type": "string", "title": "Url", "description": "Url fragment for identifying the facet in the url.", }, //... Enum The enum attribute specifies the set of available values for a configurable property. By default, when enum specifies multiple values, the user can only select one of the possible values. This generates a list of possible selections in the UI. Note: Adding the enum attribute to a property renders that property as a select or multi-select field in the SuiteCommerce Configuration record UI. To render a property as a multi-select field, set the multiselect attribute to true. The following example from facets.json specifies five possible values for the facetsSeoLimits.options property (order, page, show, display, or keywords): //... "facetsSeoLimits.options": { "type": "string", "group": "catalog", "subtab": "facetsSeoLimits", "title": "Options", "description": "Description of this property", "enum": ["order", "page", "show", "display", "keywords"], "default": ["page", "keywords"], "multiselect": true SuiteCommerce Site Development JSON Configuration Files 174 }, //... Multiselect The multiselect attribute specifies that a configurable property can contain multiple values in the UI. If set to true, users can select multiple values as defined in enum. This generates a multi-select list in the UI. In the previous example, the facetsSeoLimits.options property is set to accept multiple values with the following code: "multiselect": true As a result, users can choose multiple options from the SuiteCommerce Configuration record UI. The property can also accept multiple default values as defined in the default attribute. Default The default attribute specifies default values based on the property type, defined earlier. These values automatically populate fields in the SuiteCommerce Configuration record UI. Defaults load in the application at runtime. These defaults are only superseded by changes saved in the SuiteCommerce Configuration record. If no user saves a record, the application uses the defaults specified here. In the previous example, the default values for the facetsSeoLimits.options property are page and keywords. Mandatory The mandatory attribute specifies that a property is required. In the following example from facets.json, the name property is set to true. As a result, the attribute is required. //... "name": { "type": "string", "title": "Name", "translate": true, "description": "Label for this facet in the UI", "mandatory": true }, //... Translate The translate attribute specifies that the title and description attribute values must be translated. If this is set to true, its default values are translated. In the preceding example, the name property’s title and description fields are set to be translated. Source The source attribute declares the data source to be used as possible choices when configuring the property in the UI. This can include a variable that refers to the resource object declared within the JSON file (or within another JSON file that makes up the configurationManifest.json). Note: Adding the source attribute to a property renders that property as a select or multi- select field in the SuiteCommerce Configuration record. To render a property as a multi-select field, set the multiselect attribute’s value to true. The following example from categories.json uses the source attribute to refer to a local resource object (fields.commercecategory). In this example, $resource references the fields.commercecategory array: SuiteCommerce Site Development JSON Configuration Files 175 //... "categories.sideMenu.sortBy": { "group": "integrations", "subtab": "categories", "type": "string", "title": "Side menu > sort by", "description": "Enter the Category record field to act as the primary sort field in the Categories sidebar.", "source": "$resource.fields.commercecategory", "default": "sequencenumber" //... The source attribute can also refer to data within some custom records in NetSuite via SuiteScript. In this case, source references elements of a specific record type. The variable used must match the Internal ID of a applicable custom record types. The following fictitious example uses the source attribute to provide a list of all support issues within NetSuite (record type: Issue): //... "issue": { "type": "string", "title": "Support Issues", "source": "issue" } //... Hidden The hidden attribute specifies that a property is hidden and not shown in the user interface. If set to true, the property's default values are still present in configurationManifest.json, but the user will not be able to see or edit the property using the SuiteCommerce Configuration record. Nstype The nstype attribute specifies a concrete NetSuite widget for editing a type parameter. If a text field is too long for normal text entry, the user can declare "nsType": "textarea" and the user interface will show a text area instead a normal text entry. The following example from checkoutApp.json declares the nstype: //... "checkoutApp.invoiceTermsAndConditions": { "group": "checkoutApp", "type": "string", "nsType": "textarea", "title": "Invoice Terms and Conditions", "description": "Invoice payment method terms and conditions text", "default": "<h4>Invoice Terms and Conditions</h4.><p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.<p>" }, //... Configuration Modification Schema Applies to: SuiteCommerce | SuiteCommerce Advanced | SuiteCommerce | SuiteCommerce Advanced This section describes the configuration modification schema. Follow these steps to create a JSON modification file. SuiteCommerce Site Development JSON Configuration Files 176 Step 1: Add the Type Object The type specifies the type of object defined by the configuration file. The value of this object must always be set to object. This is required to be compliant with the JSON schema specification. { } "type": "object", Step 2: Add the Modifications Array When you deploy to NetSuite, the developer tools use the modifications listed in this array to create the configurationManifest.json. Each modifications object requires the target and action components. Some actions require an addition value component. This declares the modifications to include when you deploy to NetSuite. { } "type": "object", "modifications": [ ] Step 3: Add the Target Attribute The target attribute contains a string representing a JSONPath query. The elements returned are the targets to be affected by the action. In this example, when you deploy your customizations, the JSONPath query searches for the enum property of the target addToCartBehavior property. { } "type": "object", "modifications": [ { "target": "$.properties.addToCartBehavior.enum", } ] Note: For more information on how to build a target JSONPath query, see https://github.com/ s3u/JSONPath. Step 4: Add the Action Attribute The action attribute indicates the operation to apply over each element of the target returned by the JSONPath query. Possible actions are: ■ add – adds a new element to the user interface, such as a value, a property, or an option. Only object, array, or string elements can be returned by the target query when using the add action, and each type results in a different behavior. ■ replace – overwrites values in a configuration file. The target query can only return a number, string, boolean, or null. ■ remove – deletes an element from an array. The target query only can return a number, string, boolean, or null inside an array. This example includes the add action. { SuiteCommerce Site Development JSON Configuration Files } 177 "type": "object", "modifications": [ { "target": "$.properties.addToCartBehavior.enum", "action": "add", } ] Step 5: Add the Value Attribute The value attribute specifies the value to be added or replaced. Only the add and replace actions require this attribute. When using the add action, the value attribute behaves differently depending on the target type: ■ Target is an Object – The value attribute merges into the target. If the value has a property with the same name as a value in the target, the target value gets overwritten. ■ Target is an Array – This value attribute is pushed into the array. This value can be any valid JSON element. ■ Target is a String – This value attribute gets concatenated to the end of the target string. This value must be a number or a string. The following example adds the newOption configuration option to the addToCartBehavior list in the user interface. { } "type": "object", "modifications": [ { "target": "$.properties.addToCartBehavior.enum", "action": "add", "value": "newOption" } ] Use Case Examples Applies to: SuiteCommerce | SuiteCommerce Advanced | SuiteCommerce | SuiteCommerce Advanced Add a New Default Property to an Array This example uses the add action to introduce a new property to the object describing a resultsPerPage option. When you deploy this customization, the JSONPath query searches for the resultsPerPage.items property whose value is 12 per page. This example modification then adds newProperty to the array. { } "type": "object", "modifications" : [ { "target": "$.properties.resultsPerPage.default[?(@.items == 12)]", "action": "add", "value": {"newProperty" : "new property value"} } ] After deploying this modification, the code in the configurationManifest.json looks like this: SuiteCommerce Site Development JSON Configuration Files 178 ... "default": [ { "items": 12, "name": "Show $(0) products per page", "newProperty" : "new property value" }, ... Note: This example assume you have created a custom newProperty using the JSON configuration schema. For details, see JSON Configuration Files. Add Text to an Existing String This example uses the add action to append text to a string, such as a label of a property within an array. When you deploy this customization, the JSONPath query searches for the resultsPerPage.default property whose item value is 12. This example modification then appends !!! to the end of the string in the default name property. { } "type": "object", "modifications" : [ { "target": "$.properties.resultsPerPage.default[?(@.items == 12)].name", "action": "add", "value": "!!!" } ] After deploying this modification, the code in the configurationManifest.json looks like this: ... "default": [ { "items": 12, "name": "Show $(0) products per page!!!", }, ... After deploying this modification, the SuiteCommerce Configuration record looks like this: Add a New Default Option to an Array This example uses the add action to introduce a new configuration option within an array. When you deploy this customization, the JSONPath query searches for the resultsPerPage.default property. This modification then adds a new row to the table for a default configuration of 5 items per page. SuiteCommerce Site Development JSON Configuration Files { } "type": "object", "modifications" : [ { "target": "$.properties.resultsPerPage.default", "action": "add", "value": { "items": 5, "name": "Show 5 products per page" } } ] After deploying this modification, the code in the configurationManifest.json looks like this: ... "default": [ { "items": 12, "name": "Show $(0) products per page" }, { "items": 24, "name": "Show $(0) products per page", "isDefault": true }, { "items": 48, "name": "Show $(0) products per page" }, { "items": 5, "name": "Show 5 products per page" } ], ... After deploying this modification, the SuiteCommerce Configuration record looks like this: Change the Default Value of a Property This example uses the replace action to overwrite the default value of a property. When you deploy this customization, the JSONPath query searches for the newsletter.genericFirstName and newsletter.genericLastName properties. This modification replaces the current value, unknown, with FirstName and LastName, consecutively. { "type": "object", "modifications" : [ SuiteCommerce Site Development 179 JSON Configuration Files { }, { } ] }, 180 "target": "$.properties[newsletter.genericFirstName].default", "action": "replace", "value": "FirstName" "target": "$.properties[newsletter.genericLastName].default", "action": "replace", "value": "LastName" After deploying this modification, the code in the configurationManifest.json looks like this: ... "properties": { "newsletter.genericFirstName": { "group": "shoppingApplication", "subtab": "newsletter", "type": "string", "title": "Generic first name", "description": "Enter the generic first name to populate...", "default": "FirstName", "id": "newsletter.genericFirstName" }, "newsletter.genericLastName": { "group": "shoppingApplication", "subtab": "newsletter", "type": "string", "title": "Generic last name", "description": "Enter the generic last name to populate...", "default": "LastName", "id": "newsletter.genericLastName" }, ... After deploying this modification, the SuiteCommerce Configuration record looks like this: Change the Label of a Subtab Note: This procedure is similar for making changes to a tab. To replace the label of a tab, use the group property. This example uses the replace action to overwrite the title of a subtab. When you deploy this customization, the JSONPath query searches for the subtab with the id newsletter. This modification then changes the title from Newsletter to Email Newsletter. { SuiteCommerce Site Development JSON Configuration Files } "type": "object", "modifications" : [ { "target": "$[?(@property == 'subtab' && @.id == 'newsletter')].title", "action": "replace", "value": "Email Newsletter" } ] After deploying this modification, the code in the configurationManifest.json looks like this: ... { "type": "object", "subtab": { "id": "newsletter", "group": "shoppingApplication", "title": "Email Newsletter", "docRef": "bridgehead_4685031554", "description": "Configuration of the Newsletter subscription" }, ... After deploying this modification, the SuiteCommerce Configuration record looks like this: Remove a Configuration Option This example uses the remove action to remove an option for a property. When you deploy this customization, the JSONPath query searches for the addToCartBehavior property’s enum array. This modification removes the showMiniCart option in the user interface. { } "type": "object", "modifications" : [ { "target": "$.properties.addToCartBehavior.enum[?(@ == 'showMiniCart')]", "action": "remove" } ] After deploying this modification, the code in the configurationManifest.json looks like this: ... "properties": { "addToCartBehavior": { "group": "catalog", "subtab": "cart", SuiteCommerce Site Development 181 JSON Configuration Files ... }, 182 "type": "string", "title": "Add to cart behavior", "description": "Choose the action that occurs when the user adds an item to the cart.", "default": "showCartConfirmationModal", "enum": [ "goToCart", "showCartConfirmationModal" ], "id": "addToCartBehavior" After deploying this modification, the SuiteCommerce Configuration record looks like this: Hide a Property from the User Interface This example uses the add action to introduce the hidden property and set it to true. Important: Do not customize the source code to remove any configurable properties included with SCA. Removing configurable properties will result in errors and can break your site. To prevent a property from appearing in the SuiteCommerce Configuration record’s user interface, use the add action to introduce the hidden element to the desired property. This maintains the required code in the configurationManifest.json, but removes the property from the user interface. When you deploy this customization, the JSONPath query searches for the newsletter.companyName. This modification introduces the hidden property and sets it to true. This action prevents the property from appearing in the user interface, but maintains the code in configurationManifest.json. { } "type": "object", "modifications" : [ { "target": "$.properties[newsletter.companyName]", "action": "add", "value": {"hidden": "true"} } ] After deploying this modification, the code in the configurationManifest.json looks like this: ... "newsletter.companyName": { "group": "shoppingApplication", "subtab": "newsletter", "type": "string", "title": "Company Name", "description": "Enter the generic Company name to populate...", "default": "unknown", "hidden": "true", "id": "newsletter.companyName" } SuiteCommerce Site Development JSON Configuration Files 183 ... After deploying this modification, the SuiteCommerce Configuration record looks like this: JavaScript Configuration Files Applies to: SuiteCommerce Advanced This topic applies to the Vinson release of SuiteCommerce Advanced (SCA) and earlier. Configuration files for these implementations are stored as JavaScript files for each application module. Each of the configuration JavaScript files are contained within an application module. Each file is compiled and deployed as part of the application. To edit a configuration file, you must create a custom version of its application module. Note: For information on configurable properties, see Configuration Properties Reference. There are several files used to configure frontend behavior and a single file backend configuration file to modify server-side behavior. Frontend Configuration The SC.Configuration.js file contains general configuration properties used by SCA. Each of the application-specific configuration files contain this file as a dependency. Also, any JavaScript file within a module that needs to access configuration properties directly includes this file as a dependency. SCA uses the following configuration files to configure the behavior of the frontend application. These all return an object called Configuration that is accessed by other modules. ■ SC.Configuration – defines the configuration objects and properties that are used by all SCA applications globally. This is part of the SCA application module. ■ SC.Checkout.Configuration – defines configuration objects and properties that are used by the Checkout application. This is defined in the CheckoutApplication application module. ■ SC.MyAccount.Configuration – defines configuration objects and properties that are used by the My Account application. This is defined in the MyAccountApplication.SCA application module. ■ SC.Shopping.Configuration – defines configuration objects and properties that are used by the Shopping application. This is defined in the ShoppingApplication application module. For a detailed example on how to customize frontend configuration files in a pre-Vinson implementation, see Extend Frontend Configuration Files. Backend Configuration The Configuration.js file within the SspLibraries module defines the backend NetSuite configuration properties for SCA. By modifying this file, you can configure a variety of objects server-side. Amongst SuiteCommerce Site Development JavaScript Configuration Files other things, modifying these objects can often improve performance of your website by restricting search results. There is a single Configuration.js file used for all applications, although some objects are applicable for only certain applications (Checkout). For a detailed example on how to customize the backend configuration file in a pre-Vinson implementation, see Extend the Backend Configuration File. SuiteCommerce Site Development 184 Site Management Tools Configuration 185 Site Management Tools Configuration Applies to: SuiteCommerce | SuiteCommerce Advanced | Site Management Tools See the following help topics for additional information on SMT related configuration: ■ Upgrade from SMT Version 2 to SMT Version 3 ■ SMT Templates and Areas ■ SMT Custom Preview Screen Sizes ■ Working with SMT Landing Pages in a Sandbox Account ■ Changing SMT to Use a Different Hosting Root ■ Configuring Escape to Log In ■ Internationalization of SMT Administration Upgrade from SMT Version 2 to SMT Version 3 Applies to: SuiteCommerce | SuiteCommerce Advanced | Site Management Tools This topic applies to SuiteCommerce and the Kilimanjaro release of SCA and later. To upgrade from SMT version 2 to SMT version 3, follow these steps: 1. Install the SMT Core Content Types Bundle 2. Migrate SMT Content required only when upgrading from version 2 to version 3 of SMT 3. Deploy the Supported SCA Version to a Site Some important benefits of upgrading from SMT version 2 to SMT version 3 include: ■ Version 3 provides you with some features that are not available in version 2. See the help topic SMT Versions for a list of features and version availability. ■ Content for SMT version 3 is stored as NetSuite Records. See CMS Records for SMT. ■ Content records for version 3 content are exposed to SuiteScript. See the help topic Website. Important: It is best practice to run only one version of Site Management Tools on a single site. For example, if you have a single site record with multiple domains, do not run SMT version 2 on one domain and version 3 of SMT on another domain. Each domain should run the same version of SMT. Install the SMT Core Content Types Bundle SMT Version 3 requires installation of the SMT Core Content Types Bundle. This bundle creates the four SMT Core Content Types and their corresponding custom records in your NetSuite account. These content types include: ■ Text ■ Image ■ Merchandising Zone ■ HTML The content types and their associated custom records are locked and cannot be edited or deleted. For information on the custom records and CMS Content Records, see CMS Records for SMT. SuiteCommerce Site Development Upgrade from SMT Version 2 to SMT Version 3 186 Install the SMT Core Content Types bundle as the first step in implementing or migrating to SMT version 3. The bundle ID is 190323. See the help topic Installing a Bundle. Migrate SMT Content Content that you add to a site running SMT version 2 is stored differently from content for version 3 of SMT. When you upgrade your site, such as migrating from a pre-Kilimanjaro release of SCA to Kilimanjaro or greater, the content on the site must be migrated from version 2 to version 3. Without this migration, content created with version 2 of SMT does not display on the site. Important: This process migrates only the published content on your site. If your SMT version 2 site has content that has not yet been published, you must publish the content before the content migration. If you have content that is not ready to be published, you must manually add it to your site after the migration. Multiple Migrations You can run the migration process multiple times. Each time you run the migration, previously migrated content is cleared and re-created from the version 2 content. You receive a warning about this during the migration. An example of when you could encounter this situation is if you run the migration, but then realize you have content that was not yet published. Since unpublished content is not migrated, you must publish the content, and then run the migration again. Important: If you have upgraded your site to version 3, downgraded to version 2, then upgraded to version 3, it is important to re-run the migration to migrate any new content that was added to your version 2 site. To migrate content from SMT version 2 to version 3: 1. Go to Lists > Web Site > CMS Contents. 2. Click CMS Content Migration. This displays the CMS Content Migration page. 3. Select the site you want to migrate from the Site dropdown list. 4. Click Begin Migration. Important: This displays a message that the migration deletes any SMT version 3 content. If you are migrating from SMT version 2 to SMT version 3 then there is no need to be alarmed by the message. You can run the migration multiple times and each time it will clear the previously migrated content and migrate it again from the content on the version 2 site. 5. Click OK to begin the migration. It may take several minutes to complete the migration. You can click Refresh to monitor the status of the migration. Deploy the Supported SCA Version to a Site Site Management Tools version 3 is supported by SuiteCommerce and the Kilimanjaro release of SuiteCommerce Advanced and greater. If you are setting up a new site with the SuiteCommerce or the Kilimanjaro or greater release of SuiteCommerce Advanced, then follow the normal implementation procedure. See the help topic Install Your Commerce Web Store Applications. If your site currently runs on a pre-Kilimanjaro release of SCA, then you must migrate to SuiteCommerce or a supported release of SuiteCommerce Advanced. See Update SuiteCommerce Advanced. SuiteCommerce Site Development SMT Templates and Areas 187 SMT Templates and Areas Applies to: SuiteCommerce | SuiteCommerce Advanced | Site Management Tools The structure of your website pages is controlled by template files. The template files contain HTML markup and place holders for data and scripts. Site Management Tools uses areas defined within the template files to determine the locations on a page where you can add and manage website content. Each of the following SuiteCommerce Advanced (SCA) template files includes pre-defined areas for use with Site Management Tools: ■ Home page template ■ Page header template ■ Page footer template ■ Breadcrumb template ■ Item detail template ■ Facet search template ■ Landing page template For information on using Site Management Tools, see the help topic Site Management Tools Overview. For more information on Site Management Tools areas and templates, see the following help topics: ■ Site Management Tools Areas ■ Templates and Areas for SCA Site Management Tools Areas Applies to: SuiteCommerce | SuiteCommerce Advanced | Site Management Tools Areas are defined by adding div tags to the template. Site Management Tools uses the area div tag to know where the areas are located on each page and also to determine the scope of any content placed within that area. The scope of an area determines on which website pages any assigned content displays. When you add content to a page, each area is labeled with its scope so you know how and when the content is displayed. The three scope types are: ■ All Pages Areas ■ Page Type Areas ■ This Page Areas Each div tag has the two following attributes that name the area and set its scope: ■ data-cms-area — The value of the data-cms-area attribute is a user-defined name given to the area. For an area you want to add to the main part of the page, you might set the value of the data-cmsarea attribute to main, main-header, or main-footer. For an area that you want to place in a sidebar, you might set the value of the data-cms-area to sidebar, sidebar-right, or sidebar-left, and so on. Remember, this is a user-defined value that names the area, so use the naming convention that works best for you. For example, name the area by its intended purpose or page location. Note: The data-cms-area name is used only to define the area in template files. The name is not displayed on the website. ■ data-cms-area-filters — This attribute determines the scope of an area, meaning on which pages content in that area displays. Scope types are defined as follows: SuiteCommerce Site Development SMT Templates and Areas 188 Area Scope data-cms-area-filters Description All Pages global The All Pages area displays content on any page, provided the page has an area with the same data-cms-area. Page Type page_type The Page Type area displays content on any page of the designated type, for example, product list or product detail. This Page path The This Page area is the most specific area with regard to when content displays. Content displays only on the page specified by the path in the page URL. This is the type of area to use if you want to display content for a specific product, facet, or home page. Each page template can include multiple areas. For example, you may want to put one or more This Page areas and a All Pages area on your home page. You may want to include the same All Pages area on the Item Detail and Facet Browse pages. You may also want to include one or more This Page and Page Type areas on the Facet Browse and Item Detail pages. Pages can have multiple areas. Note: Areas are displayed visually in edit mode when you add content to the page. The label for each area indicates the scope of that area. All Pages Areas You create an area with All Pages scope by setting the data-cms-area-filters attribute in the area div to global. All Pages areas display on any page on the site that contains a global area with the same datacms-area name. For example, if you define an area with a data-cms-area equal to main in the, home.tpl, facets_facet_browse.tpl, and item_details.tpl template file, any content you place in that area is displayed on the following pages: SuiteCommerce Site Development SMT Templates and Areas 189 ■ The Home Page ■ All Facet Browse Pages ■ All Item Detail Pages The content is displayed on those pages because each of the pages contains a global area named main. The following code sample illustrates this area: <div data-cms-area="main" data-cms-area-filters="global"></div> By adding this area div to one or more templates, you create a new All Pages area on the template. In the following screen shot, you see two All Pages areas. These two area divs are defined as follows: <div data-cms-area="header_banner" data-cms-area-filters="global"></div> <div data-cms-area="global_banner_footer" data-cms-area-filters="global"></div> In this example, the divs are added to the header and footer template files. By including them in those templates, the areas are available on all shopping pages without having to add them to each template file. Page Type Areas Areas with page type scope are identified by the type of page, for example Product Detail pages or Facet Browse pages . You create an area with page type scope by setting the value of the data-cmsarea-filters attribute to page_type. The page type can be the home page, Product Detail page, or Facet Browse page. For example, you may want an area at the bottom of a product detail page that you can use for displaying text, merchandising zones, banners, etc. To do this, you modify the product details SuiteCommerce Site Development SMT Templates and Areas 190 template file to add an area. Set the value of data-cms-area to item_info_bottom, and set the value of data-cms-area-filters to page_type. The div code for this area is as follows: <div data-cms-area="item_info_bottom" data-cms-area-filters="page_type"></div> By adding this area div to the product detail page template, the area will be available on every product detail page. Content placed in the area displays for every product. The area on the page appears similar to this: Notice that in this example, the area is labeled with the type of page: Product Detail Pages. This lets you know that any content you add to that area displays on every product detail page. This Page Areas You create This Page areas by setting the value of the data-cms-area-filters to path. The This Page area is the most specific of the three areas because the condition for its display is specific to the path of the page. The path is the URL, excluding host and query string parameters. For example, you modify the product detail template and include an area with the data-cms-area equal to item_info and data-cmsarea-filters equal to path. When you add content to the area it is tied to the path. For example, the URL to Reebok Pants is http:// website.name.com/pantsreebok. The path to this product is /pantsreebok. Even though the page is a product detail page, when you add content to that area it displays only when a visitor goes to / pantsreebok. The content does not display for any other product. The div segment for this area can be defined as follows: <div data-cms-area="item_info" data-cms-area-filters="path"> SuiteCommerce Site Development SMT Templates and Areas 191 A more sophisticated use of a This Page area is to apply it to a facet search page. This makes it possible to display content specific to the facet the visitor is viewing. For example, the path to a facet search of black items is /color/black. When you place content in a This Page area, the content displays only when a visitor views items with a facet filter of black. To take this example a step further, the path to a facet filter of black pants is /category/pants/color/ black. When you place content in a This Page area, the content displays only when a visitor views the pants page with a facet filter of black. Facet Order in URLs When URLs for a search page that includes facet filters are constructed, the facets in the URL are always listed in the same order, regardless of the sequence in which the visitor selects the facets. For example if one visitor filters first on pants and then on black and another visitor filters first on black and then on pants, the URL for both visitors is identical. This means that the path for black pants is always /cateogry/ pants/color/black regardless of the order the visitor applies the facet filters. Templates and Areas for SCA Applies to: SuiteCommerce Advanced | Site Management Tools Template files for SCA pages are part of the corresponding module. These templates contain pre-defined Site Management Tools areas. This enables you to quickly add content and achieve a variety of page layouts without the need for creating custom page templates. See the following topics for template specific areas: ■ Header and Footer Module Default Areas ■ Home Module Default Areas SuiteCommerce Site Development SMT Templates and Areas 192 ■ Breadcrumb Default Areas ■ Facets Module Default Areas ■ Item Details Module Default Areas ■ Landing Page Default Areas ■ Customizing Template Files If you determine that the default page layouts do not fully meet your needs, you can customize the modules to create your own areas or make changes to the existing areas. For example, you may want to change the scope of an existing area to Page Type or to add a new All Pages area across all shopping pages. For more information on adding areas to pages, see Customizing Template Files. Header and Footer Module Default Areas Applies to: SuiteCommerce | SuiteCommerce Advanced | Site Management Tools The layout of the header and footer areas of your site pages is determined by the Header and Footer modules. Area divs placed in the template files for these modules adds areas to your page header and footer. The scope of these pre-defined areas is All Pages, which means any content you add to these areas displays across all of your shopping pages. When a web page on your site is displayed, the page contains not only the areas defined in the header and footer modules but also those areas defined by the module that creates that page. In the following screen shot, you see the header and footer areas as they are displayed on the home page when adding content. These same areas also display on the search page and item detail pages. 1. The header template file is header.tpl, and it contains one area named header_banner_top with All Pages scope. SuiteCommerce Site Development SMT Templates and Areas 193 2. The footer template file is footer.tpl, and it contains one area named global_banner_footer with All Pages scope. Home Module Default Areas Applies to: SuiteCommerce | SuiteCommerce Advanced | Site Management Tools The layout of your site’s home page is determined by the home.tpl template file in the Home@x.x.x module. In the following screen shot you see the defined areas. Note that you also see the All Pages header and footer module areas at the top and bottom of the page. The home.tpl template file contains the following This Page areas. 1. home_main 2. home_banner_1 3. home_banner_2 4. home_banner_3 5. item_list_banner_bottom 6. home_bottom Breadcrumb Default Areas Applies to: SuiteCommerce | SuiteCommerce Advanced | Site Management Tools The breadcrumb navigation section of web pages on your site is created by the global_views_breadcrumb.tpl template file in the GlobalViews@x.x.x module. There are two default areas. One area is located directly above the breadcrumb navigation and the other area is located directly below: SuiteCommerce Site Development SMT Templates and Areas The global_views_breadcrumb.tpl template file contains the two following All Pages areas. ■ breadcrumb_top ■ breadcrumb_top Facets Module Default Areas Applies to: SuiteCommerce | SuiteCommerce Advanced | Site Management Tools The layout of your site’s search page is determined by the facets_facet_browse.tpl template file in the Facets@x.x.x module. The facets_facet_browse.tpl template file has four Page Type areas and one This Page area. 1. Page Type —item_list_banner 2. Page Type —facet_navigation_top SuiteCommerce Site Development 194 SMT Templates and Areas 195 3. This Page —item_list_banner_top 4. Page Type —facet_navigation_bottom 5. Page Type —item_list_banner_bottom Item Details Module Default Areas Applies to: SuiteCommerce | SuiteCommerce Advanced | Site Management Tools The layout of the item detail pages on your site is determined by the item_details.tpl template file in the ItemDetails@x.x.x module. The item_details.tpl file contains three Page Type areas and one This Page area. 1. Page Type — item_details_banner 2. This Page — item_info SuiteCommerce Site Development SMT Templates and Areas 196 3. Page Type — item_info_bottom 4. Page Type — item_details_banner_bottom Landing Page Default Areas Applies to: SuiteCommerce | SuiteCommerce Advanced | Site Management Tools The layout of landing pages is determined by the cms_landing_page.tpl file in the CMSadapter@x.x.x module. In the following screen shot you see the defined areas. Note that you also see the header, footer, and breadcrumb areas that are defined in those modules. The cms_landing_page.tpl file contains one Page Type area and one This Page area. 1. Page Type — cms-landing-page-placeholder-page-type 2. This Page — cms-landing-page-placeholder-path Customizing Template Files Applies to: SuiteCommerce | SuiteCommerce Advanced | Site Management Tools If you want to create a new area, remove an area, or change an area, you must customize the corresponding module and apply your changes to the relevant template file. For example, if you want to add more CMS areas to the item detail page, you must create a custom ItemDetails module that overrides SuiteCommerce Site Development SMT Templates and Areas 197 the default item_details.tpl template file with a customized item_details.tpl template file. See Core SuiteCommerce Advanced Developer Tools. Module Template File Local Source File Module Template Location home@x.x.x home.tpl Modules\suitecommerce\home@x.x.x\Templates ItemDetails@x.x.x item_details.tpl Modules\suitecommerce\ItemDetails@x.x.x\Templates Facets@x.x.x facets_facet_browse.tpl Modules\suitecommerce\Facets@x.x.x\Templates Header@x.x.x header.tpl Modules\suitecommerce\Header@x.x.x\Templates Footer@x.x.x footer.tpl Modules\suitecommerce\Footer@x.x.x\Templates GlobalViews@x.x.x global_views_breadcrumb.tpl Modules\suitecommerce\GlobalViews@x.x.x\templates SMT Custom Preview Screen Sizes Applies to: SuiteCommerce | SuiteCommerce Advanced | Site Management Tools If you want to preview your site for dimensions that are not already defined, you can create your own preview sizes by adding the dimensions to the adapter file. Additionally, you can override the default preview sizes so that only your custom preview sizes are available for selection. The following sample code illustrates several custom preview screen sizes. Notice that each preview option is designated as either desktop, tablet, or phone. The attributes for each preview size includes the name, width dimension, and height dimension. var setup = { // Config values the adapter can give the cms on startup. // Screen size preview override/extension screen_preview: { override_defaults: false, sizes: { desktop: [{ name: 'XL', width: 2000, height: 3000 }, { name: 'XXL', width: 3000, height: 4000 }, { name: 'Portrait', width: 768, height: 1024 }], tablet: [{ name: 'Huge', width: 1300, height: 2000 }], phone: [{ name: 'Massive', width: 1400, height: 2400 }] } } }; When you define custom dimensions for tablets and phones, Site Management Tools forces the width dimension to be greater than the height dimensions. If you define a dimension where the height is SuiteCommerce Site Development SMT Custom Preview Screen Sizes 198 greater than the width, Site Management Tools swaps the width and height dimensions so that width is greater than height. This rule does not apply to desktop dimensions. Override Defaults If you want to make only your custom preview sizes available, in the CMS adapter, set the value of the override_defaults flag to true. Only custom dimensions will be available. When set to false, both default and custom preview dimensions are listed on the dimensions dropdown list. Enabling Custom Preview Sizes and Overriding Defaults To enable custom preview screen sizes or override default preview sizes, you must customize the CMS adapter file to include the code for the custom screen sizes and to set the value of the override_defaults flag. For information on customizing a module, see Customize and Extend Core SuiteCommerce Advanced Modules. Working with SMT Landing Pages in a Sandbox Account Applies to: SuiteCommerce | SuiteCommerce Advanced | Site Management Tools When working with Site Management Tools in a sandbox account, you must configure the URL for landing pages to reflect the domain of the sandbox environment. If you fail to set this configuration property, you receive a Page Not Found error when attempting to access an SMT landing page in the sandbox environment. For configuration information, see Configure Properties. To set the Landing Pages URL 1. Select the domain to configure at Setup > SuiteCommerce Advance > Configuration. 2. In the SuiteCommerce Configuration record, navigate to the Integrations subtab and then the Site Management Tools subtab. 3. In the Landing Pages URL field, enter the URL for your sandbox account. The format of the sandbox domain is your account specific domain appended with the unique identifier for the sandbox, for example, https://345678_SB1.app.netsuite.com. 4. Click Save. See the help topics NetSuite Sandbox and URLs for Account-Specific Domains for additional information. To set the Landing Pages URL (pre-Elbrus) 1. Create a custom CMSAdapter module to extend CMSadapter.model.js 2. Add a custom property to set cmsPagesUrl is as follows: 'https://345678_SB1.app.netsuite.com/api/cms/pages?site_id=' + siteSettings.siteid + '&c=' + nlapiGetContext().getCompa ny() + '&{}' SuiteCommerce Site Development Working with SMT Landing Pages in a Sandbox Account 199 Note: This sample URL uses the account specific domain and the unique identifier for the sandbox. For more information on customizing a module, see Customize and Extend Core SuiteCommerce Advanced Modules. For information on deploying customizations to a sandbox account, see Deploy to a NetSuite Sandbox . Note: When the sandbox account is refreshed, your customization will be overwritten and will need to be redeployed to the sandbox account. Important: If you make customizations in your sandbox account and then move those customizations to production, you must edit the cmsPagesUrl in the CMSadapter.model.js file to change the sandbox URL to the production URL. Changing SMT to Use a Different Hosting Root Applies to: SuiteCommerce | SuiteCommerce Advanced | Site Management Tools When you create a website, the Website Setup record specifies the HTML Hosting Root. When you implement Site Management Tools on that site, it utilizes the same HTML Hosting Root as the website. If you move the site to a different HTML hosting root, you will also need to create a new CMS SSP application. This application will utilize the new HTML Hosting Root so that SMT can continue to function and your content continue to display. This is required because Site Management Tools and the website must utilize the same HTML hosting root. To configure SMT to use a different HTML hosting root: Note: For the purpose of example only, the following procedure uses the sample folder name, Custom Hosting Root. Your custom hosting root can be named differently. 1. Publish any unpublished changes to your site. See the help topic Publish Content for more information. 2. Make a copy of your SSP application in the new HTML hosting root folder. This process includes: ■ Creating the directories in the file cabinet, for example, Custom Hosting Root/SSP Applications. ■ Copying the SSP application to the new SSP Applications folder. ■ Creating the new SSP application record and pointing it to the copy of the SSP application. See the help topic Create a SuiteScript 1.0 SSP Application Record . 3. Copy the NetSuite Inc. - CMS folder to the Custom Hosting Files/SSP Applications folder in the file cabinet. Important: The folder must be named NetSuite Inc. - CMS. Do not rename this folder or any of its subfolders. 4. Create a new SSP application record for SMT. See the help topic Create a SuiteScript 1.0 SSP Application Record. Use the original SSP application record as your model: SuiteCommerce Site Development Changing SMT to Use a Different Hosting Root 200 a. Give the application a unique, CMS-related name. b. Give the application a unique ID or leave the ID empty to use a system-generated ID. c. Set the Application Folder to Custom Hosting Root: /SSP Applications/Netsuite Inc. — CMS/CMS. d. Set the URL Root to /CMS. e. Enter a description of the CMS SSP application. The description should provide enough information to prevent confusion. f. Save the new application. 5. Edit the Website Setup record to change the Default Hosting Root to Web Site Hosting Files : Custom Hosting Files. 6. Link the new SSP application record to your site. 7. Clear the website cache. 8. Go to your site and log in to Site Management Tools. Important: This is a crucial step so don’t forget it. 9. Add simple text content to any page on your site and publish the change. 10. After you confirm that the text content published correctly, delete the text content and publish the change to remove the text from your site. Configuring Escape to Log In Applies to: SuiteCommerce | SuiteCommerce Advanced | Site Management Tools Available in the Elbrus release of SuiteCommerce Advanced and greater. Use the following procedure to enable or disable the Site Management Tools Escape to Login feature, see the help topic Disable Esc Key to Log In for more information. To enable or disable Escape to Login: 1. Select the domain to configure at Setup > SuiteCommerce Advance > Configuration. 2. In the SuiteCommerce Configuration record, navigate to the Integrations subtab and then the Site Management Tools subtab. SuiteCommerce Site Development Configuring Escape to Log In 201 3. Select the Disable Esc Key to Login box to disable the Escape key for logging in or clear the box to enable the Escape key for logging in. Internationalization of SMT Administration Applies to: SuiteCommerce | SuiteCommerce Advanced | Site Management Tools Internationalization enables the website administrator to set the language for the Site Management Tools user interface. SMT uses the language preference selected in your NetSuite account. To select your language preference, see the help topic Choosing a Language for Your NetSuite User Interface. This enables administrators to set their own language preferences when using SMT. For example, one administrator can use SMT in English and one administrator can use SMT in Spanish. SMT uses the language preference selected in the administrator’s NetSuite account. Internationalization does not affect the language for visitors to the website. Visitor language is controlled by language preference in SuiteCommerce Advanced. See the help topic Web Site Language Preferences. Currently, internationalization is only supported in SMT V3. To check your version of SMT, see the help topic Determine Your Version of SMT. All foreign languages available in NetSuite are available to select for internationalization. Note: Custom Content Types are not currently supported for internationalization. CMS Records for SMT Applies to: Site Management Tools When you add content to your website with Site Management Tools and publish it, the content and the information regarding how it is displayed on the site is saved as NetSuite records. These include the following: ■ Custom Record for CMS Content ■ CMS Contents Record ■ CMS Page Record ■ CMS Page Type Record The custom record contains the actual content that you added to the site. For example, if you add a banner image to your site, there is a custom CMS_IMAGE record that includes the source for the image file, the alternate text for the image, and the link for the image. For each custom record, there is a corresponding CMS Content record. The CMS Content record details specific information about how and where that content from the custom record is displayed on the site. SuiteCommerce Site Development CMS Records for SMT 202 Note: Only published content is available as NetSuite records. Unpublished content is not accessible in the NetSuite Admin. Example 1. Example: Records Created when Adding Content You add a banner image to the header area of your site. When you add the image, you specify the following information: ■ Visibility Options ■ Image File ■ Alternate Text ■ Link The area where you add the image is defined in the page template file and the area attributes provide a couple of important pieces of information. These are the scope of the content which can be global, current page, or page type. In this example, the area is in a page header and it is defined with global scope. The area also has a unique name. In this example, the name is global_banner_top. When the you publish the content, a new CMS_IMAGE custom record is created. This record stores the content which is the image file source, alternate text, and link. A CMS Content record is also created. This CMS Content record links to the custom record with the custom record id. The CMS Content record includes the visibility date and times, area scope, area name, and several other data elements regarding the contents. See Custom Record for CMS Content and CMS Contents Record. Custom Record for CMS Content Applies to: SuiteCommerce | SuiteCommerce Advanced | Site Management Tools The SMT Core Content Types bundle creates the custom records for the SMT core content types. These content types include: ■ Text ■ Image ■ Merchandising Zone ■ HTML Note: The SMT core content type custom records are locked and cannot be edited or deleted. The custom records are defined as follows: Content Type Custom Record Name Custom Fields Text CMS_TEXT clob_html Image CMS_IMAGE string_link string_alt string_src Merchandising Zone CMS_MERCHZONE exclude_cart exclude_current merch_rule_url SuiteCommerce Site Development CMS Records for SMT 203 merch_rule_count merch_rule_id merch_rule_template HTML CMS_HTML clob_html When you add content to your site and publish it, the content is saved as a custom record of one of these types. You can view or edit the record, and any edits you make to the custom record are immediately visible on the site. An example of when to edit the custom record is if you notice a misspelled word in a piece of text content. You can edit the custom record and correct the misspelling in the text. This makes the correction available immediately. For each content custom record, there is also a CMS Content record that defines information specific to how and when the content is displayed on the site. See CMS Contents Record. Note: If you create custom content types, a custom record is created for each custom content type. See Custom Content Type. To view the custom record for SMT content: 1. Go to Customization > List, Records, & Fields > Record Types. 2. In the Record Types list, locate the CMS Content Type record for the content you want to view. The core content type records are CMS_HTML, CMS_IMAGE, CMS MERCHZONE, and CMS_TEXT. You may also have a content type record for any custom content type you enable. 3. Click List for the content type record. This displays the list of content for that record type. 4. Click View. CMS Contents Record Applies to: SuiteCommerce | SuiteCommerce Advanced | Site Management Tools The CMS Content record defines specific information about how each instance of SMT content is displayed. Each CMS Content record links to a corresponding custom record for content. For example for each CMS_IMAGE custom record, there is one corresponding CMS Content record. The CMS Content record specifies how and where content is displayed. The CMS Content record includes the following fields: Name The name is an internal identifier for the content. The name is not displayed to the visitor on the website. The name field is left empty for content created through SMT. Description This is a user defined description of the content. The description field is left empty for content created through SMT. Site This specifies the site for the content. Content Type Identifies the content type. The core content types include: ■ CMS_IMAGE ■ CMS_HTML ■ CMS_MERCHZONE ■ CMS_TEXT Additional type values may also be available for custom content types. SuiteCommerce Site Development CMS Records for SMT 204 Settings Identifies the ID for the custom record that stores the content. This ID links the custom record for the content instance to the corresponding CMS Content record. Template Determines the template used when rendering content. This should be set to default. Match Type The Match Type field is not used by Site Management Tools or Commerce web stores at this time. Change URL Specifies the URL used when the content was created or changed. This URL does not necessarily reflect the only URL where the content is displayed. For example, content with page type and global context, can display on many pages. The URL in this field reflects only the URL of the page where the content was added or last edited. Page Type Context This corresponds with the SMT This Page area scope and is used for content that you want to place on a specific type of page such as a product detail page or a facet browse page. Available options are: ■ ProductDetails — denotes a product detail page. ■ facet-browse — denotes a facet browse page or a category page. ■ cms-landing-page — denotes a landing page. See This Page Areas. Global Context This corresponds with the SMT All Pages area type. When content is configured to display in all pages, this field contains the *. See All Pages Areas. Path Context The corresponds with the This Page area type and denotes the URL to the page. See This Page Areas. Area Name Specifies the name of the area on the page where this content is placed. Area name is the value of the data-cms-area attribute from the page template file. Start Date The visibility start date and time for the content. End Date The visibility end date and time for the content. This identifies the date and time when the content expires. When this field is empty the content never expires. Edit CMS Content Even though you can make changes to content by editing the CMS Content record, best practice for editing content is to make your edits in SMT. Editing the CMS content record directly is not recommended because, if done incorrectly, you can cause content to disappear from your site. Add CMS Content CMS Content records are created automatically when you add content to your site and publish it. The CMS Content record lets you add a new record directly from within NetSuite. Remember, each CMS Content record links to a corresponding CMS custom record. Although you can manually add CMS Content and CMS custom records to add content to your site, NetSuite recommends using SMT for adding or editing content. Delete CMS Content The CMS Content record lets you delete SMT content from your site. When you delete a CMS Content record, the corresponding CMS custom record is also deleted, and the content is immediately and permanently removed from the site. SuiteCommerce Site Development CMS Records for SMT 205 To delete a CMS Content record: 1. Go to Lists > Web Site > CMS Contents. 2. Click Edit for the record you want to delete. 3. Select Delete from the Actions menu. 4. When asked if you are sure you want to delete the record, click OK. CMS Page Record Applies to: SuiteCommerce | SuiteCommerce Advanced | Site Management Tools The CMS page record gives you access to the NetSuite records for Site Management Tools landing and enhanced pages. These include landing and enhanced pages for both SMT version 2 and SMT version 3. These records include landing and enhanced pages that were created directly within SMT and also those created with the CMS Page record. The CMS Page record lets you: ■ Delete a CMS Page Record The CMS Page record gives you access to only the page, not to the SMT content on that page. You can add content to the page by logging in to SMT. The page attributes that you can set for a landing or enhanced page are the same attributes that you set for a page with SMT and include the following: Name The page name is an internal identifier for the page. This name is not displayed to the visitor on the website, but it does identify the page in NetSuite and in SMT. Site Determines the site for this page. Type Specifies if this record is for a landing page or an enhanced page. ■ 1 = landing page ■ 2 = enhanced page Addition to Head This field lets you specify additional information such as JavaScript or CSS to include in the <head> area of the page. URL Identifies the relative path to use for accessing this page on the website. The URL should contain only the relative URL with no slashes or spaces. Template Determines the template for the page. Page Title The page title populates the HTML title element. For SEO, titles should be descriptive and include target keywords to help improve the page's ranking on search results pages. Additionally, search engines often display this title on search results pages and link it to the page. Follow SEO best practice when creating page titles. Page Heading Specifies the heading for the page. If the page template file supports it, this heading is displayed on the page. Meta Description The Meta Description populates the HTML meta description element. The description is an important SEO tool and is often displayed on search results pages as a description of the page. Setting a meaningful and accurate description that contains your target keywords can help improve your ranking in search results pages. Use SEO best practice when writing descriptions. Meta Keywords The Meta Keywords populate the HTML meta keywords element for the page. It is important to follow SEO best practice when defining Meta Keywords for the page, because using them incorrectly can have a negative impact on the page’s ranking on search results pages. Start Date The visibility start date and time for the content. SuiteCommerce Site Development CMS Records for SMT End Date 206 The visibility end date and time for the content. This identifies the date and time when the content expires. When this field is empty, the content never expires. Delete a CMS Page Record When you delete a CMS Page record, that page is removed and is no longer available. It can no longer be accessed by visitors, and it is no longer available for editing in SMT. Be sure to consider the SEO consequences of removing a page. If the page had been indexed by search engines, then you should create a 301 redirect so that search engines know the page has been permanently removed and the address of the page that replaces it. This helps prevent a negative hit on your search engine ranking. The 301 redirect also ensures that visitors who try to access the page directly are taken to an alternative page rather than just receiving a 404 Page Not Found error. For more information on redirects, see the help topic Setting Up a URL Redirect. If you delete a page that has not yet been published, then the record is removed and the unpublished changes list in SMT no longer lists the unpublished page. Since the page is unpublished there are no SEO considerations when you delete it. To delete a CMS Page record: 1. Go to Lists > Web Sites > CMS Pages. 2. Click Edit next to the page link. 3. Point to the Actions menu and select Delete from the dropdown list. 4. When asked if you are sure you want to delete the record, click OK. Landing Pages and Sitemap Generator When using a new NetSuite account, there are two circumstances where new landing pages may not be included in the site map: ■ You create CMS Landing Page records in NetSuite instead of with SMT ■ You use the CSV import to create CMS Landing Page records To ensure Landing Pages are included in the sitemap, you must log in to Site Management Tools. Logging in to SMT creates the necessary version records for the system to create the sitemap. There are no additional actions needed while logged in to SMT. To avoid potential issues, you should use SMT to manage CMS content, CMS Landing Pages, and Commerce Categories. For more information and best practices, see the help topic Sitemap Generator. For more information on CSV Import Files, see the help topic Guidelines for CSV Import Files. CMS Page Type Record Applies to: SuiteCommerce | SuiteCommerce Advanced | Site Management Tools The CMS Page Type record gives you access to the NetSuite records for Site Management Tools page types. The CMS Page Type record gives you access to only the page type, not to the SMT content SuiteCommerce Site Development CMS Records for SMT 207 associated with that page type. A new page type record is also created when a user registers an extension. You create a new CMS Page using your desired CMS Page Type, then add any desired SMT content to your new page. The 19.1 release has one standard page type, landing page, that you cannot delete. You can set the following CMS Page Type Record attributes in NetSuite: Name The page name is an internal identifier for the page. This name is not displayed to the visitor on the website, but it does identify the page in NetSuite and in SMT. This field is also populated when an extension is registered. Display Name The display name is the external identifier for the page. This the name displays on the dropdown list when the creating a new page. This field is also populated when an extension is registered. Description This is a user defined description of the page type. Base URL Path The base URL path lets you customize the URL for all the pages of that type. For example, if you a have a page type of blog and a base URL path of blog, all blog pages are accessed by mysite.com/ blog/[page url]. Custom Record Type This lets you create a Custom Content Type (CCT) and associate with a page type. You create the new CCT and choose your customizations, this can be fields, Javascript code, CSS elements, and other custom module resource. This must be implemented through SuiteCommerce extensions or SCA. CMS Creatable When CMS Creatable is set to yes, then the page type is available on the page type list when creating a new page. When CMS Creatable is set to No, then the page type is not available as an available type when creating a new page. Inactive When a page type is checked Inactive, it cannot be used to create a new page. Existing pages using this page type continue to work. Inactive page types remain visible in SMT for use in sorting and filtering operations. Domain Data Subtab ■ Domain — Use the dropdown list to select the domain you want to associate with this page type. ■ Template — Type the exact name of the template file you want to associate to this page type. This field is case sensitive. Add a new CMS Page Type Record The CMS Page Type record lets you create a new page type. The CMS Page Type record enables you to only create the page type. You must then create a new page in SMT using the new page type. After you create a new page with the desired CMS Page Type, you can add content using SMT. To add a CMS Page Type Record: 1. Go to Lists > Web Site > CMS Pages > New. 2. Enter the following information. ■ Name — Enter a name to identify this page in NetSuite. The name is not displayed to website visitors and only identifies the record in NetSuite. This field is also populated when an extension is registered. SuiteCommerce Site Development CMS Records for SMT 208 ■ Display Name — This is used to indicate the page type to the SMT admin. This field is also populated when an extension is registered. ■ Description — This is a user-defined description of the page type. ■ Base URL Path — The base URL path lets you customize the URL for all the pages of that type. For example, if you a have a page type of blog and a base URL path of blog, all blog pages are accessed by mysite.com/blog/[page url]. ■ Custom Record Type — This lets you create a Custom Content Type and associate with a page type. You create the new CCT and choose your customizations. These can be fields, Javascript code, CSS elements, and other custom module resource. This must be implemented through SuiteCommerce extensions or SCA. ■ CMS Creatable — Select Yes if the SMT admin can create pages of this type. Select No if the SMT admin cannot create pages of this type. ■ Inactive — Check the Inactive box to prevent users from creating pages of this type. Any existing pages of this type continue to display on the site. 3. Click Save. Edit a CMS Page Type Record The CMS Page Type record lets you edit an existing CMS Page Type. You can edit the attributes of your page type, but not any of the content on any page associated with the page type. To edit a CMS Page Type Record: 1. Go to Lists > Web Site > CMS Page Type. 2. Click Edit next to the page type link. 3. Make your changes. 4. Click Save. Delete a CMS Page Type Record You can only delete a CMS Page Type record if no pages of that type exist. If you want to delete a CMS Page Type record from your NetSuite account, you must first delete all CMS Page records associated with that page type. To delete a CMS Page Type record: 1. Go to Lists > Web Sites > CMS Page Type. 2. Click Edit next to the page type link. 3. Point to the Actions menu and select Delete from the dropdown list. 4. When asked if you are sure you want to delete the record, click OK. Page Types Domain Level Data This information refers to SuiteCommerce or the 2019.2 release of SuiteCommerce Advanced or later. Along with creating different page types, you can also create and assign page types to a specific domain in your account. This lets you apply page types at the domain level. Only one entry is allowed for a specific SuiteCommerce Site Development CMS Records for SMT 209 page type and domain combination. This means you can only have one page type named blog attached to one domain. If you want to attach multiple blog page types to a single domain you must use a different name for each blog page type associated with that domain. This It can be as simple as naming different page types, blog1, blog2, blog3, etc. To associate a Page Type to a Domain: 1. Go to Lists > Web Site > CMS Page Types. 2. Choose the page type you want to associate to a specific domain and click Edit. 3. Under Domain Data, choose the domain in the dropdown list you want to assign the page type to. 4. In the Template field, enter the exact name of the template you want to assign. This field is case sensitive. 5. Click Add. 6. Click Save. 7. This page type is now associated with the specific domain. To remove a Page Type association to a Domain: 1. Go to Lists > Web Site > CMS Page Types. 2. Choose the page type you want to disassociate from a specific domain and click Edit. 3. Under Domain Data, choose the domain and template to want to remove. 4. Click Remove to delete the association between the page type and the domain. 5. Click Save. 6. This page type is no longer associated with the specific domain. Custom Content Type Applies to: SuiteCommerce | SuiteCommerce Advanced This information refers to the Kilimanjaro release of SuiteCommerce Advanced or later. Site Management Tools custom content type provides a platform for Commerce extension developers to create custom website applications or features that are enabled and managed through the SMT user interface. This enables Commerce users to implement custom content and expand functionality of their website with Site Management Tools. The process for implementing CCTs on your Commerce site can be broken down into two major activities. The first activity is to create your custom Commerce module. This consists of creating your JavaScript code, CSS, and other supporting custom module resources. These must all be implemented in following Commerce best practice. See Create a CCT Module for best practice on creating a custom CCT module. After you create your custom module, the next step is to setup the CCT for use in SMT. This process includes the following: ■ Create the custom records and fields for your custom content type. See Custom Record for Custom Content Type. ■ Create the Content Type Record for your custom content type. See CMS Content Type Record. ■ Enable the Custom Content Type in the SMT Content Manager. See the help topic Settings. SuiteCommerce Site Development Custom Content Type 210 Custom Record for Custom Content Type Applies to: SuiteCommerce | SuiteCommerce Advanced SMT custom content types use NetSuite’s Custom Records and Fields for defining the settings and values required for the custom content type. For example, if you have a custom content type that displays an image with a text overlay, you must create a custom record for the content type and then create the custom fields for the values required by your content. In the following screen shot you see the custom record for the SC CCT ImageViewer. As part of implementing a CCT you associate this custom record with a corresponding CMS Content Type Record. See CMS Content Type Record for more information. Important: The Access Type for the custom record must be set to No Permission Required. Custom Fields for Custom Content Type After you create the custom record, the next step is to define the custom fields. The custom fields you define here are displayed in the side panel in Site Management Tools when you add the custom content type to a page. In this example, the custom fields are used to define the information that is displayed by the custom content type. These fields include: ■ Message — A text area that lets you enter text to overlay on the image. ■ Vertical Align — Lets you select the vertical alignment for the text. Notice that in this example, the Vertical Align field is defined as a list/record type, and is associated with a custom list. ■ URL — Identifies the source for the image. To reference the custom fields in your CCT module, use the ID assigned to each custom field. In this example, the IDs for custom fields are: SuiteCommerce Site Development Custom Content Type 211 ■ custrecord_sc_cct_iv_text — Message field ■ custrecord_sc_cct_iv_valign — Vertical Align field ■ custrecord_sc_cct_iv_imageurl — URL field Note: Custom content types do not support the Password field type. After your custom content type is fully implemented, it is displayed in SMT. The following screenshot illustrates the SC CCT ImageViewer custom content type. Important: A Custom Content Type is available in SMT only after you have completed all implementation steps. Tabs for Custom Content Type Depending upon your custom content type and the number, type, or function of fields, you may want to create tabs to organize the fields. You can create tabs in the custom record for your custom content type and assign fields to the tabs. The tabs and field organization are reflected in the custom content types settings in the side panel in SMT. For more information on custom records and fields, see the help topic Custom Records. Custom Content Type Records Each time you use SMT to add an instance of a Custom Content Type to your site, a CMS content record and a custom record for the Custom Content Type is created. The CMS content record determines how and where the custom content is displayed, see CMS Contents Record. The custom record for the content type stores the values for the custom content elements. In the example of the ImageViewer custom content type, these values include: SuiteCommerce Site Development Custom Content Type 212 ■ Message ■ Vertical Align ■ URL Although you can view or edit instances of the Custom Content Types in NetSuite, best practice is to make your changes to the Custom Content Type in SMT. To view a Custom Content Type Record in NetSuite: 1. Go to Customizations > Lists, Records, & Fields > Record Types. 2. In the Record Types list, locate the record for your Custom Content Type and click List. 3. This displays a listing of all instances of that Custom Content Type. Parent Child Record Associations This information refers to SuiteCommerce or the 2019.2 release of SuiteCommerce Advanced or later. By using parent-child record associations you can create more complex data sets in your custom content types. For example, you create a Custom Record Type named blog. Next, you create a new CMS Page Type named blog. Finally, you use the Custom Record Type dropdown menu to select which record type you want to associate to your page type. Using this method to create new page types provides you with many options including the abilities to apply specific templates to your page type, add headers or footers, and many other options. You must use SuiteScript or NetSuite to add, edit, or delete the custom records. Site Management Tools manages only the page types you have associated to the custom record. SMT lets you manage the fields created in your custom record. When you create a new page in SMT, the pop out menu renders your custom fields when you click Landing Page and you can manage the content in your fields there. CMS Content Type Record Applies to: SuiteCommerce | SuiteCommerce Advanced | Site Management Tools The CMS Content Type record defines the different types of content for SMT. When you install the SMT Core Content Types bundle, the bundle creates the CMS Content Type records for the following core content types: ■ CMS_HTML ■ CMS_IMAGE ■ CMS_MERCHZONE ■ CMS_TEXT CMS Content Type Record for CCT When you create custom content types, you must manually create a CMS Content Type record for each custom content type. The CMS Content Type Record links to the custom record you created for your CCT. You must create the CMS Content Type Record before your custom content type is available in SMT. To create a Content Type Record 1. Go to Lists > Website > CMS Content Types > New. SuiteCommerce Site Development Custom Content Type 213 2. Click New. 3. In the Name field, enter a name for this content type. The name must be all lowercase and best practice is to use no spaces. The name identifies this record in NetSuite so make it descriptive of the custom content type. The name you specify here must be set as the value of the id property within the registerCustomContentType() method used to initialize your CCT module. See Create a CCT Module. 4. In the Description field, enter more details about this custom content type to explain its purpose. 5. In the Icon Image Path field, enter the path in the file cabinet for the icon you want to use for this content type. Only the scalable vector graphics (*.svg) format is supported. If you do not specify an icon, a default icon is used for the content type. 6. Specify the Label to use in SMT for this content type. The label identifies the content type to the user. 7. In the Custom Record field, enter the name of the custom record you created for this custom content type. 8. Click Save. CCT Icon Requirements Icons for custom content type should be a single-color SVG image. From a design perspective, the image should be simple but distinctive enough for users to recognize the icon at a glance and associate it with the content type. Images that are comprised of SVG shape elements that can be filled, rather than SVG strokes, work best. Shapes should have no defined color. The icon can utilize strokes, but the element's fill attribute must be set to "none", and its stroke attribute must be set to "currentColor". Icon styling should be done using presentational attributes, not CSS. Style elements present in the SVG image may be removed. Required Settings ■ Valid SVG ■ One root element (<svg>) with valid value for xmlns attribute ■ Root element's viewBox attribute is set to "0 0 48 48" ■ Color ■ Elements without a stroke must have fill set to "currentColor" or no fill attribute. ■ Elements with a stroke must have fill set to "none" and stroke set to "currentColor". Recommended Settings ■ Desc element ■ Should describe what the image contains or looks like ■ Should be the first child of the root element ■ Should generally only contain shape elements (circle, ellipse, line, path, polygon, polyline, rect), but may also contain structural elements (g, defs, use, symbol) Not Permitted ■ text, except when integral to a logo/branding where a non-text version is not available or would violate brand guidelines. Convert any included text to outlines. ■ raster images SuiteCommerce Site Development Custom Content Type ■ style elements ■ script elements ■ animation elements ■ gradient elements ■ font elements ■ filter primitive elements ■ animation attributes ■ event attributes ■ conditional processing attributes SuiteCommerce Site Development 214 Overview 215 Overview Applies to: SuiteCommerce | SuiteCommerce Advanced Commerce websites provide a fully functional application that you can use to implement your ecommerce solutions. Theme developers create HTML templates and Sass files as themes. The SuiteCommerce Base Theme is an excellent place to start building a theme and is available as a SuiteApp. Extension developers create extensions to introduce functionality to a site. If you are developing a SuiteCommerce Advanced (SCA) site, you have access to the core SCA source code as well, although this comes with a different set of instructions and best practices you must follow. Note: If you are developing customizations for SuiteCommerce or SCA, be sure to review the information in Commerce Migration to SuiteScript 2.0 to learn more about a phased initiative to improve the developer experience. This initiative will ultimately enable application developers to interact with core NetSuite records in a unified way. This topic explains how to customize the following: ■ Themes Commerce themes contain any number of HTML templates, Sass files, and assets, such as images and fonts. These are organized into modules and act as a single package that can be later applied to any domain on a Commerce site. Read this section if you are a theme developer (SuiteCommerce or the Aconcagua release of SCA or later). ■ Extensions Extensions introduce added functionality to your website through any number of JavaScript, SuiteScript, configuration JSON, and other files. You use the extension developer tools to build a baseline extension and build from there. Extensions can also include HTML and Sass. Read this section if you are an extension developer (SuiteCommerce or the Aconcagua release of SCA or later). Note: The Extensibility API is only available to extension developers. This means that you must be building extensions for SuiteCommerce or sites implementing the Aconcagua release of SCA or later to access this API. ■ Theme and Extension SuiteApps This section explains how to bundle themes and extensions as SuiteApps, making them available for distribution to NetSuite accounts. ■ Core SCA Source Code This section is for SuiteCommerce Advanced developers only. Read this section if you are customizing objects that are not accessible using the Extensibility API. This requires using the core SCA developer tools and customization procedures to extend SuiteCommerce Advanced Source code. You must also read this section if you are implementing the Kilimanjaro release of SuiteCommerce Advanced or earlier. SuiteCommerce Advanced Developers Applies to: SuiteCommerce Advanced As a SuiteCommerce Advanced developer, you have different options when customizing the application. The tools, practices, and procedures available all depend on your implementation. SuiteCommerce Site Development SuiteCommerce Advanced Developers 216 Aconcagua Release of SCA and Later – If you are implementing the Aconcagua Release of SuiteCommerce Advanced have access to themes and extensions. You can alter a site’s appearance using Sass and HTML files deployed or bundled as themes. To introduce new functionality to a site through JavaScript and SuiteScript, you can use the Extensibility API to build extensions using the SuiteCommerce Extension Framework. However, if you are developing JavaScript, SuiteScript, or configuration objects that are not accessible using the Extensibility API, you must use the core SCA developer tools and follow SCA module customization practices. Kilimanjaro Release of SCA and Earlier – If you are customizing the Kilimanjaro Release of SuiteCommerce Advanced or earlier, you must either migrate to the latest release of SCA or use the core SCA developer tools and follow specific procedures to customize SuiteCommerce Advanced modules. Themes and extensions are not available for these earlier releases of SCA. For a list of components exposed using the Extensibility API, see the help topic Extensibility Component Classes. For information on using the core SCA developer tools and customizing SCA modules, see Core SCA Source Code. SuiteCommerce Site Development Commerce Migration to SuiteScript 2.0 Commerce Migration to SuiteScript 2.0 Applies to: SuiteCommerce | SuiteCommerce Advanced SuiteCommerce Advanced is undergoing an initiative to improve the developer experience when developing a SuiteCommerce Advanced site. These improvements will ultimately enable Commerce application developers to interact with core NetSuite records in a unified way, leveraging the benefits of SuiteScript 2.0. This change is being introduced in phases across multiple releases of SuiteCommerce and SuiteCommerce Advanced. When completed, this new approach will: ■ Leverage the benefits of SuiteScript 2.0 ■ Provide developers a single, unified experience to interact with core NetSuite APIs ■ Eliminate duplication of business logic within the Commerce API ■ Eliminate the need to access the Commerce API Migration Status This section explains the current state of the SCA migration to SuiteScript 2.0. Because this migration spans multiple releases, check this topic periodically for status updates and a list of what modules have been migrated. Migration Updates (by release) SCA Release Description of Changes Modules Migrated to SS 2.0 New Modules 2019.1 Added SSP Application support for SuiteScript 2.0 for implementations utilizing the SuiteTax feature. None None During this release of SuiteCommerce and SCA, this was required for anyone using the SuiteTax feature. 2019.2 ■ Partial Module Migration to Unified Developer Case Experience Subscriptions (Limited Release) ■ Initial implementation of My Account backend components (Service Controllers) ■ Updated some modules for SuiteScript 2.0 migration to TypeScript ■ Expanded SSP Application support for SuiteScript 2.0. This change impacts all Commerce web store SuiteApp installation and setup procedures. See the help topic Install Your Commerce Web Store Applications for details. 2020.1 ■ Continued Module Migration to Unified Developer Experience ■ Continued implementation of My Account backend components (Service Controllers) SuiteCommerce Site Development StoreItem Transaction TransactionHistory None 217 Migration Status SCA Release Description of Changes Modules Migrated to SS 2.0 New Modules ■ Updated some modules for SuiteScript 2.0 migration to TypeScript Note: Modules that have been migrated to SuiteScript 2.0 are located in the Backend directory of the SCA source code: <SC_xxx/Backend/SC/ (where xxx refers to the release). If your current SCA implementation includes customizations to these modules, you can review changes to the code base and adjust your customizations as needed to ensure continued functionality. However, if you are developing extensions, attempts to import or include migrated modules in your customization will produce runtime errors. SuiteCommerce Site Development 218 Themes 219 Themes Applies to: SuiteCommerce | SuiteCommerce Advanced A theme is a special type of extension that affects a domain’s design and appearance (layouts and styles). Themes contain any number of HTML templates, Sass files, and other assets that are available as published themes (bundled into a single SuiteApp) or deployed to a NetSuite account by on-site theme developers. After downloading the theme developer tools and creating your developer environment, you are ready to create your own themes. This topic includes the following topics: ■ Themes Overview ■ Develop Your Theme ■ Best Practices for Creating Themes ■ Theme Manifest Themes Overview Applies to: SuiteCommerce | SuiteCommerce Advanced Benefits of Using Themes The following list describes some of the benefits of using themes: ■ Themes let non-technical users change the layout and styles of their web store by installing and activating any number of pre-developed themes from a marketplace. ■ Themes allow any developer working with SuiteCommerce or SuiteCommerce Advanced (SCA) to create and manage their own themes and activate them for any domains associated with their site. Partners can also publish and distribute themes as bundled SuiteApps. ■ Themes leverage the features and functionality of Site Management Tools (SMT). You can expose variables to the Theme Skin Manager. This allows SMT administrators to further customize any theme using the SMT user interface. Before You Begin Be aware of the following important information: ■ These procedures assume that you have already created your developer environment, fetched an active theme to use as a baseline, and are ready to build your theme. For more information, see Theme Developer Tools. ■ To develop a theme, you must have experience working with HTML, Sass/CSS, and Handlebars.js. Before customizing any theme or extension source code, read and understand the Best Practices for Creating Themes. ■ As a best practice use the SuiteCommerce Base Theme as a baseline for theme development. This is available as a SuiteApp. See the help topic Install Your Commerce Web Store Applications for details on this SuiteApp. ■ The examples presented in this section describe customizing Sass files. However, you can customize HTML files as well to suit your needs. You can also introduce new images and fonts as assets. SuiteCommerce Site Development Themes Overview 220 ■ After fetching the active theme using the developer tools, you can customize theme-related files directly within your Workspace/<THEME_DIRECTORY> folder. ■ If you are implementing the Aconcagua release of SuiteCommerce Advanced, you must implement themes to customize Sass or HTML templates. Develop Your Theme Applies to: SuiteCommerce | SuiteCommerce Advanced As a theme developer, you start with a baseline theme and develop your own from there. Best practice is to start development using the SuiteCommerce Base Theme. This is available as a SuiteApp in NetSuite. Simply install this SuiteApp and activate it using the Manage Extensions Wizard. Use the theme developer tools to fetch the theme files into a theme development workspace and start developing. Theme Development Tutorials The following tutorials assume that you have already activated the SuiteCommerce Base Theme using the Manage Extensions Wizard and fetched theme files using the theme developer tools. If you are planning to override extension-related HTML and Sass to accommodate your theme, you must activate any related extensions as well. You should also familiarize yourself with the Best Practices for Creating Themes. Refer to the following topics for assistance before creating a theme: ■ See Fetch Active Theme Files for details on fetching files for development. ■ See the help topic Themes and Extensions for details on activating themes and extensions. Step Description More Information 1 Create a baseline theme using the SuiteCommerce Base Theme. Follow the best practices related to the Base Theme when using this theme. SuiteCommerce Base Theme 2 Edit existing theme Sass and HTML files. Customize Pre-Existing Theme Files 3 Create new HTML, Sass, or asset files to meet your needs. Add a New File to a Theme 4 If you want elements of your theme (HTML and Sass) to impact an active extension (use a new color, for example), you can create overrides that implement your changes to the active extension. Override Active Extension Files These procedures explain how to introduce HTML and Sass changes to a deployed extension using the override method. 5 If you want your theme to be customizable using the Site Management Tools Set Up Your Theme for Theme Skin Manager, follow these instructions to expose variables and Customization in SMT organize how those variables look in the SMT user interface. You can also create skins for your theme. Skins are predefined settings that change the appearance of a theme in a specific way. Follow these instructions to create skin preset files, which define new values for any number of exposed variables. 6 Understand the theme manifest. This is a JSON file that includes all the information required to compile resources for an active theme. 7 Throughout development, you may want to test your theme on a local server Test a Theme on a Local or on a test domain. You have the following options: Server SuiteCommerce Site Development Theme Manifest Develop Your Theme Step Description More Information ■ When you are ready to test your theme, you can use the theme development tools to test on a local server. Deploy a Theme to NetSuite 221 ■ To see your theme on a development or production domain, you must deploy to your NetSuite account and activate the theme (and any extensions that include overrides) for the domain. 8 Activate your theme to view your theme to your NetSuite account. Manage Themes and Extensions Customize Pre-Existing Theme Files Applies to: SuiteCommerce | SuiteCommerce Advanced When you download a theme’s source files, you have access to the HTML, Sass, and assets used by that theme. You can customize the HTML and Sass files directly within your Workspace directory. Best practice, when making changes to existing Sass variables, is to edit the existing Sass files directly. To customize a pre-existing theme file: 1. Open the theme directory in your top-level development directory. For example: Workspace/<THEME_DIRECTORY>/ 2. Locate the subdirectory containing the file or files you want to customize. For example, you want to customize the top margin of the Add to Cart button for this theme. You locate the _cart-add-to-cart-button.scss file in the theme’s Cart module: Workspace/<THEME_DIRECTORY>/Modules/Cart@1.0.0/Sass/_cart-add-to-cart-button.scss 3. Edit the HTML or Sass file within the associated module. You can edit this file directly. See Best Practices for Creating Themes for details. In this example, you edit the .cart-add-to-cart-button-button class and change the margin-top value from lv3 to lv5. //... // New code with new margin-top value: .cart-add-to-cart-button-button{ @extend .button-primary; @extend .button-large; width: 100%; font-weight: $sc-font-weight-semibold; margin-top: $sc-margin-lv5; } /* Previous Code: .cart-add-to-cart-button-button{ @extend .button-primary; @extend .button-large; width: 100%; font-weight: $sc-font-weight-semibold; margin-top: $sc-margin-lv3; }*/ //... 4. If you want to expose Sass variables to the Site Management Tools Theme Skin Manager, add the editable() function to expose any variables. See Set Up Your Theme for Customization in SMT for details. 5. Save the file. SuiteCommerce Site Development Develop Your Theme 222 6. Repeat this procedure in this fashion for any other theme-related HTML or Sass files you intend to customize. When you are ready, use the theme developer tools to test or deploy your theme. See Theme Developer Tools for procedures on how to use these tools. Add a New File to a Theme Applies to: SuiteCommerce | SuiteCommerce Advanced When you customize a theme, you can also create new HTML, Sass, or asset files to meet your needs. This procedure includes editing a manifest file to ensure that your new file compiles at activation. Note: To reference assets within your code, use the HTML and Sass Helpers provided. See Asset Best Practices for more information. To create a new file for a theme: 1. Create your new HTML, Sass, or asset file in the correct location, as required. File Type Location Within Workspace/<THEME_DIRECTORY>/ HTML Modules/<MODULE>/Templates Sass Modules/BaseSassStyles/Sass/reference-theme Assets assets 2. Create each file as required. See Best Practices for Creating Themes for details. Important: To avoid file name collisions, do not create any new files or folders that share the same name, even if they reside in different locations. 3. Save this file in the correct location within your directory structure. For example, you want to add a new Sass file titled _newSass.scss. As a best practice, save this file in the following location: Workspace/<THEME_DIRECTORY>/Modules/BaseSassStyles/Sass/reference-theme/_newSass.scss 4. Open the theme’s manifest.json file. For example: Workspace/<THEME_DIRECTORY>/manifest.json 5. Include your new file in the appropriate location as required: ■ If adding a template, list the file by application. Include the .tpl file in the files array of the appropriate application object (Shopping, MyAccount, or Checkout). When declaring your new file, include the path to the correct module. The order of your declaration does not matter. For example: //... "templates": { "application": { "shopping": { "files": [ //... ] } } //... SuiteCommerce Site Development Develop Your Theme 223 ■ If adding a Sass file, list the .scss file in the files array of the sass object. You set up the Sass entry point in a later step. When declaring your new file, include the path to the correct module. Add this line in a location that makes the most semantic sense within the Sass hierarchy. For example: //... "sass": { "entry_points": { "shopping": "Modules/Shopping/shopping.scss", "myaccount": "Modules/MyAccount/myaccount.scss", "checkout": "Modules/Checkout/checkout.scss" } "files": [ //... ] } //... ■ If adding an asset, add your asset as part of the files array of the img, font-awesome, or font object, as appropriate. When declaring your new file, include the path to the correct folder (img/, font-awesome/, or font/). The order of your declaration does not matter. For example: //... "assets": { "img": { "files": [ //... ] } "font-awesome": { "files": [ //... ] } } //... This ensures that the compiler includes your customizations. In this example, you are adding a Sass file. Therefore, you add newSass.scss as a dependency to the files array of the sass object. Your manifest file might look similar to the following example: "sass": { "entry_points": { "shopping": "Modules/Shopping/shopping.scss", "myaccount": "Modules/MyAccount/myaccount.scss", "checkout": "Modules/Checkout/checkout.scss" } "files": [ //... "Modules/BaseSassStyles@x.y.z/Sass/reference-theme/_newSass.scss", //... 6. Save the manifest.json file. 7. If your new file is an asset or template, you have no further action required. However, if your new file is a Sass file, follow these additional steps: a. Identify the application or applications impacted by your new Sass file. b. Edit the application entry point file to include the same dependency you introduced in the manifest file. Application Impacted Application Entry Point Shopping Modules/Shopping/shopping.scss SuiteCommerce Site Development Develop Your Theme Application Impacted Application Entry Point My Account Modules/MyAccount/myaccount.scss Checkout Modules/Checkout/checkout.scss 224 In this example, the Cart module impacts the Shopping application. Therefore, you open the Shopping entry point file and include the dependency. Your Shopping.scss file should look similar to the following example: //... @import "../BaseSassStyles@x.y.z/Sass/reference-theme/newSass"; //... Just as you did in the manifest.json file, place this file in such a manner that makes semantic sense within the Sass hierarchy you are customizing. c. Save the application Sass file. When you are ready, use the theme developer tools to test or deploy your theme. See Theme Developer Tools for procedures on how to use these tools. Override Active Extension Files Applies to: SuiteCommerce | SuiteCommerce Advanced When creating a theme, you can customize the HTML and Sass of any active extensions for a domain and deploy them with your theme customizations. When you run the gulp theme:fetch command, you download the theme Sass, HTML, and asset files. You also download all extension-related HTML and Sass files. The developer tools place these in the appropriate folder within the Workspace/Extras/extension directory. This section explains how to use the Override method to customize HTML and Sass files related to extensions. Important: Extension-related files placed in the Extras directory are provided as a reference only. Never edit these files directly. Instead, use the Override method described in this section. Example You activate a theme for your domain. You also activate an extension for the same domain. You create your theme to include a new color variable. You want the extension that is active with your theme to use this same variable. However, the extension’s Sass does not include the new variable. You must customize the extension’s Sass files to include this color variable using the Override method. This ensure that the active extension includes your Sass variable, without actually changing the extension’s code. Instead, you override it. All of your theme customizations and extension overrides are maintained as part of your theme. Therefore, when you later activate your theme and the extension for your domain, the active extension includes your new color variable. This does not change the extension. Instead, this change belongs to the theme. The Override Method To customize extension-related HTML and Sass files, you must use the Override method. This involves placing copies of source HTML and Sass from your Extras directory into your theme directory and making SuiteCommerce Site Development Develop Your Theme 225 your customizations there. When you deploy your changes, the theme development tools detect the new files and initiate an override within the manifest. Note: When you downloaded an extension’s HTML and Sass files, the theme developer tools placed them in your Extras/Extensions directory, sorted by extension. These are for reference only. At the same time, the developer tools created an identical directory structure in your theme’s Overrides directory. Important: You cannot override asset files. To introduce new assets for your template customizations or extension overrides, add them as you would for any new files within the template directory, then reference the assets using the HTML and Sass Helpers. See Add a New File to a Theme. See Asset Best Practices for details on using helpers. To customize an extension using the Override method: 1. Locate the source file you want to override. For example, you want to override the _Pub-Extend-Error.scss file of the Published Extension 1 extension. Therefore, the file you want to override is in the following location: Workspace/Extras/Extensions/PublishedExtension1/Modules/PubExtendModule@1.0.0/Sass/ _PubExtend-Error.scss 2. Copy the source file to your operating system’s clip board. 3. Paste a copy of the file in the corresponding location within the theme’s Overrides directory. For example: Workspace/<THEME_DIRECTORY>/Overrides/Modules/PubExtendModule@1.0.0/Sass/_Pub-ExtendError.scss Important: Do not rename these files. These files must share the same name for the Override method to function correctly. 4. Open your new file in your Overrides directory. 5. Follow best practices to customize your new file. See Best Practices for Creating Themes for important details on customizing these files. 6. Repeat this procedure for all extension-related files you intend to customize. SuiteCommerce Site Development Develop Your Theme 226 When you are ready, use the theme developer tools to test or deploy your theme. See Theme Developer Tools for procedures on how to use these tools. Set Up Your Theme for Customization in SMT Applies to: SuiteCommerce | SuiteCommerce Advanced As the theme developer, you edit your theme's Sass files and expose variables for customization. This can include, at your option, preset files (JSON) that define skins for each theme. Within your Sass structure, you can also establish a schema for displaying each variable in the SMT user interface. Before reading the topics in this section, familiarize yourself with the best practices outlined in Sass Best Practices Note: Site Management Tools Version 3 includes the Theme Skin Manager. This interface lets SMT administrators customize styles and layouts of an active theme based on the settings that you define during theme development. SMT administrators can apply changes to individual settings or apply skins to change multiple settings at one time. Expose Sass Variables for Customization Applies to: SuiteCommerce | SuiteCommerce Advanced You control the variables that your theme exposes for customization by introducing metadata into your Sass files. You expose variables using the editable() function as described in this section. To expose a variable for customization: 1. Open the Sass file containing the variable you want exposed. 2. Create an inline comment (//) or a block comment (/* ... */) immediately following the variable declaration. You can use either comment method. For example: $sc-primary-color: red; // $sc-primary-color: red; /* */ 3. Use the editable() function within your comment tags to declare the variable as editable. See The editable() Function for details. This function is required. 4. Save the file. If you are creating a new Sass file, you must declare the file within the manifest file and the appropriate application entry point. See Add a New File to a Theme for details. 5. Repeat this procedure for every variable you want to expose. For exposed variables to appear in Site Management Tools, you must declare the Sass file containing the variable and its metadata in the manifest file and entry points for each application using that variable. For example, you can define and declare a Sass variable that works in Checkout only. You add the containing Sass file to the theme manifest and the Checkout entry point. Later, when viewing your theme in the SMT Theme Skin Manager, your variable only appears in the SMT user interface when navigating to Checkout. If you want your variable to appear in multiple applications, you must declare the new file within each. Limiting global definitions to the BaseSassStyles module helps ensure functionality of global variables. SuiteCommerce Site Development Develop Your Theme 227 When you are ready, use the theme developer tools to test or deploy your theme. See Theme Developer Tools for procedures on how to use these tools. The editable() Function The metadata to expose a variable takes the form of an editable() function call wrapped inside a comment in your Sass files. This function call accepts a JSON object as its single argument with the following properties: ■ type – declares the variable type. This property is required. Possible values include: □ color – displays a color picker in SMT. □ string – declares a value as a string (font-weight, font-style, thumbnail size, etc.). Important: SMT only supports color and string as values for the type property. If you wish to declare a number value or a font, you must do so as string. ■ label – provides a formatted string to reference the variable in the SMT user interface. If not defined, SMT displays the Sass variable name as the label. ■ description – describes the variable in a long-formatted string. This property is optional. ■ options – provides a list of options as an array for the variable. Use this property to limit possible values using a dropdown list. See Limit Selections. This property is optional. The following code snippet is an example of how to expose a color variable using inline notation: $sc-primary-color: red; // editable({"type": "color", "label": "Primary Color"}) You can also use the editable() function with block notation: $sc-primary-color: red; /* editable({ "type": "color", "label": "Primary Color", "description": "Used mainly for 'call to action' elements." })*/ Important: The comment must start immediately after the variable declaration. This is essential for the Sass preprocessor to relate the variable name with the declared metadata in the comment. Limit Selections You can use the options property of the editable() function to specify one or more values within a dropdown list in SMT. For example, you can declare a list of available font weights as selections within a list instead of requiring SMT administrators to manually enter a numeric value as a string. In this example, each option’s value property is the value to be processed for $base-font-weight, and the text property is the corresponding option as viewed in the dropdown list: $base-font-weight: 200; /* editable({ "type": "string", "label": "Font Weight", "options": [ {"value": 200, "text": "light"}, {"value": 400, "text": "normal"}, {"value": 800, "text": "bold"}] }) */ SuiteCommerce Site Development Develop Your Theme 228 You can also apply this option to colors. Using the option property on a color requires the SMT administrator to choose from a list of possible colors instead of using a color picker. Note that the option value must be a string in this case. The following example displays a list of color options: $feedback-color: white ; /* editable({ "type": "color", "label": "Feedback Color", "options": [ {"value": "white", "text": "normal"}, {"value": "black", "text": 'contrast'}, {"value": "#ededed", "text": 'low contrast'} ] }) */ Organize Variables for Display in SMT Applies to: SuiteCommerce | SuiteCommerce Advanced When you expose Sass variables for customization, SMT displays each exposed variable in the side panel. Without any organizational structure, these variables do not display in any meaningful, intuitive way. To aid SMT administrators when customizing their theme, you can define how each exposed variable displays in the SMT side panel. You do this by creating group metadata using the group() function as described in this section. You can create group metadata in any Sass files within your theme. To group variables in the SMT side panel: 1. Open the Sass file within your theme development files that contains the exposed variable you want to group. You can place this in any location within the Sass file. 2. Use the group() function within comment tags to create an organization scheme. Build your group schema here. See The group() Function for details. 3. Save the file. If you are creating a new Sass file, you must declare the file within the manifest file and the appropriate application entry point. See Add a New File to a Theme for details. 4. Repeat this for every new variable you want to expose for your theme. When you are ready, use the theme developer tools to test or deploy your theme. See Theme Developer Tools for procedures on how to use these tools. Note that you must also activate your theme to make these changes available for SMT. See the help topic Manage Themes and Extensions for details. The group() Function You introduce the group() function within comments, as you do with the editable() function. However, group() does not need to be located immediately after a variable declaration within a Sass file. Note: Functionally, you can add the group() function at any point within your theme’s Sass files. However, as a best practice, introduce group() in the same file that contains the associated variable. Each group() function call accepts a JSON object as its single argument with the following properties: SuiteCommerce Site Development Develop Your Theme 229 ■ id – declares the group ID. This is used to define and reference the group. ■ label – provides a formatted string for the group to be shown in the SMT Theme Skin Manager. ■ description – describes the group in a long-formatted string. This property is optional. ■ children – provides an array of variable names or group IDs (for a nested subgroup). If declaring a variable, you must precede the variable with $. The SMT user interface mirrors the order of any children declared here. Note: Any variables or subgroups listed here do not need to be defined before the group definition to be referenced as a group children. This function lets you declare groups and organize your Sass variables in an intuitive way within the SMT side panel. 1. Parent (Group) 2. Child (Subgroup) 3. Child (Variable) A top-level (parent) group displays as a heading in the SMT side panel, such PALETTE. Should a further subgroup be necessary, nested children appear as expandable/collapsible subgroups, such as Theme palette. Children of a subgroup are variables exposed for editing. SMT only supports two group levels. Example The following code declares one parent group called Pallette-color and four children to create subgroups. Each of these children is defined later in the code. Any children of the subgroups are declared variables. /* group({ "id": "palette-color", "label": "Palette", "description": "", "children": [ "theme-palette", "neutral-shades", SuiteCommerce Site Development Develop Your Theme ] }) */ "text-colors", "container-colors" /* group({ "id": "theme-palette", "label": "Theme palette", "description": "", "children": [ "$sc-color-theme", "$sc-color-theme-900", "$sc-color-theme-700", "$sc-color-theme-500", "$sc-color-theme-300", "$sc-color-theme-100", "$sc-color-primary", "$sc-color-secondary" ] }) */ /* group({ "id": "neutral-shades", "label": "Neutral palette", "description": "", "children": [ "$sc-neutral-shade", "$sc-neutral-shade-700", "$sc-neutral-shade-500", "$sc-neutral-shade-300", "$sc-neutral-shade-0" ] }) */ /* group({ "id": "text-colors", "label": "Text", "description": "", "children": [ "$sc-color-copy", "$sc-color-copy-dark", "$sc-color-copy-light", "$sc-color-link", "$sc-color-link-hover", "$sc-color-link-active" ] }) */ /* group({ "id": "container-colors", "label": "Containers", "description": "", "children": [ "$sc-color-body-background", "$sc-color-theme-background", "$sc-color-theme-border", "$sc-color-theme-border-light" ] }) */ The preceding code, after it is deployed and activated for a domain, displays in the SMT side panel as depicted in the following images. The first image shows the parent group, Palette. and the four nested subgroups: Theme palette, Neutral shades, Text colors, and Containers. SuiteCommerce Site Development 230 Develop Your Theme Children of the parent group are the nested subgroups. Children of each subgroup must be variable names because SMT does not support more than two group levels. These appear as expandable/ collapsible groups. SMT administrators can now edit the settings as they please. SuiteCommerce Site Development 231 Develop Your Theme 232 Note: The design architecture style definitions used to maintain the Sass structures use derived/ calculated values. By exposing derived colors, as in this example, any UI selections of the base value results in changes of any derived values automatically. SMT admins can further edit each derived value within the UI as well, assuming those variables are exposed for editing. See Style Definitions for more information on how these Sass structures work. Create Skins Applies to: SuiteCommerce | SuiteCommerce Advanced What is a Skin? Generally speaking, a skin is a selectable set of predefined settings that change the appearance of a theme. One theme can include any number of skins that SMT administrators select to change that theme’s appearance. For example, a theme might include multiple skins with a different color scheme for specific seasons. ■ Theme – a ready-made package that can be activated for any number of domains. A theme can include any number of skins. ■ Skin – a set of predefined variables that lets SMT administrators alter a theme in a specific way. From a development perspective, you define a skin using a JSON file. Each file contains the variables and corresponding values that change when the skin is applied using SMT. You create one file in the theme’s Skins directory for each skin you want available. When you run the gulp theme:local or gulp theme:deploy command, the developer tools update the theme’s manifest file, automatically adding a skin for each file located in Skins directory. When you deploy and later activate the theme for a domain, your presets appear as selectable skins in the SMT user interface. When SMT administrators apply your skin, the application compiles the values, and the theme incorporates the changes. Important: If you apply a skin, then make changes to one or more variables, you will see your changes in the theme preview. However, if you then select a new skin, your changes to the individual variables will be lost. Important Information Be aware of the following information when creating skins: ■ When developing your skin, include only variables that are exposed for customization. If your skin includes variables that are not editable, they will not change when the skin is applied. Expose Sass Variables for Customization for details. ■ A theme can include any number of skins or no skins at all. If you do not create any skin preset files, SMT does not provide the option to select any. ■ Any Sass variables exposed to SMT are available for customization at any time using the SMT Theme Skin Manager. A theme does not need to include skins for exposed variables to be editable. Likewise, after an SMT administrator selects a skin, they can make their own changes to individual variables. ■ When SMT administrators apply changes to any exposed variables, those changes apply to the domain, but they do not overwrite the predefined skin or the theme’s Sass files. The only way to permanently change a Sass variable or save changes to a skin is to edit the theme’s development files or create a new theme using the developer tools. SuiteCommerce Site Development Develop Your Theme The Skin Preset File Applies to: SuiteCommerce | SuiteCommerce Advanced Creating a skin involves building a JSON preset file. This file contains the variables you want your skin to change. Each variable listed includes the new value to use when the skin is applied. To create a skin preset file: 1. Expose all Sass variables you want your skin to override. See Expose Sass Variables for Customization for instructions. 2. Navigate to your theme’s Skins directory. This directory is located in your top-level theme development directory. For example: <Top-LevelDevelopmentDirectory>/ Workspace/ Skins/ 3. Create a new JSON file. Name this file in an intuitive manner. Do not include spaces or special characters. For example: ../Workspace/Skins/winter_skin.json 4. Open this file and define the Sass variables you want your skin to change and include the values your skin changes. For example, your winter skin might look like the following: { , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , "$sc-color-body-background": "white" "$sc-button-primary-text-color": "white" "$sc-button-primary-hover-text-color": "white" "$sc-button-primary-active-text-color": "white" "$sc-button-primary-text-transform": "none" "$sc-button-secondary-text-color": "white" "$sc-button-secondary-hover-text-color": "white" "$sc-button-secondary-active-text-color": "white" "$sc-button-secondary-text-transform": "none" "$sc-button-tertiary-hover-text-color": "white" "$sc-button-tertiary-active-text-color": "white" "$sc-button-tertiary-text-transform": "none" "$sc-button-large-line-height": "1" "$sc-button-large-letter-spacing": "1px" "$sc-button-large-mobile-width": "100%" "$sc-button-large-desktop-width": "auto" "$sc-button-medium-line-height": "1" "$sc-button-medium-letter-spacing": "0.5px" "$sc-button-medium-mobile-width": "100%" "$sc-button-medium-desktop-width": "auto" "$sc-button-small-line-height": "1" "$sc-button-small-letter-spacing": "normal" "$sc-button-small-mobile-width": "auto" "$sc-button-small-desktop-width": "auto" "$sc-body-line-height": "1.6" "$sc-h1-line-height": "1.2" "$sc-h2-line-height": "1.2" "$sc-h3-letter-spacing": "0" "$sc-h4-line-height": "1.4" "$sc-h5-line-height": "1.4" "$sc-h6-line-height": "1.4" "$sc-blockquote-line-height": "1.6" "$sc-color-primary": "#e23200" "$sc-color-secondary": "#15607b" SuiteCommerce Site Development 233 Develop Your Theme , , , , } 234 "$sc-neutral-shade": "#4D5256" "$sc-color-theme": "#97CCDF" "$sc-color-link": "#0067b9" "$sc-color-link-active": "#0067b9" Important: When creating a skin preset file, include only variables that are exposed for editing within your theme’s Sass files. If you include a variable that is not exposed, that value does not change when the skin is applied to the theme. See Expose Sass Variables for Customization. 5. Save the JSON file. 6. Include your new skin in the extension manifest file. See Add a Skin to the Theme Manifest. Add a Skin to the Theme Manifest Applies to: SuiteCommerce | SuiteCommerce Advanced For your skin to appear in the SMT Theme Skin Manager, it must be declared in the theme’s manifest. The developer tools do this automatically when you run either gulp theme:local or gulp theme:deploy. Note: You can also edit the manifest file manually, following the example in this section. The theme’s manifest.json file is located at ../Workspace/<Theme_Directory>/manifest.json. To update the theme manifest file: 1. Perform one of the following Gulp commands: ■ gulp theme:local – the developer tools update the manifest and start the local server. ■ gulp theme:deploy – the developer tools update the manifest and deploy the theme to NetSuite. Note: Running gulp theme:local updates the manifest, but it does not deploy anything to NetSuite servers. You must deploy your theme files to NetSuite to view your skins in the SMT Theme Customizer. 2. If necessary, you can edit the manifest.json file to provide a more visually appealing value for the name property. Any edits you make to the manifest.json file do not apply to your domain until you redeploy your theme. When you are ready, use the theme developer tools to deploy your theme. See Theme Developer Tools for procedures on how to use these tools. Note that you must also activate your theme to make these changes available for SMT. See the help topic Manage Themes and Extensions for details. See Theme Manifest for more information on this file. Customize Site Search Elements Applies to: SuiteCommerce | SuiteCommerce Advanced This topic applies to SuiteCommerce and the 2018.2 release of SuiteCommerce Advanced only. SuiteCommerce Site Development Develop Your Theme 235 Any themes created using these implementations include the ability to customize the site search button and input bar. You can customize your theme to locate the site search button (magnifying glass button) and input bar in any location within any template or independently within different templates. 1. Site Search Button 2. Site Search Input Bar and Go Button Site Search Button The site search button is visible by default in the SuiteCommerce Base Theme. Site users must click this button to activate the site search input bar. You can locate this button in any template for desktop or mobile use with the following code: Note: The code displayed in this topic is backward compatible with Commerce themes created prior to the 2018.2 release. Desktop <div class="header-menu-search" data-view="SiteSearch.Button"></div> ■ Base Theme Module: Header ■ Base Theme Template: header_menu.tpl Mobile <div class="header-menu-searchmobile" data-view="SiteSearch.Button"></div> ■ Base Theme Module: Header ■ Base Theme Template: header.tpl Site Search Input Bar Site users rely on this input bar to search a site. You can locate the site search input bar and Go button in any template for desktop or mobile use with the following code: Site Search <div class="site-search" data-type="site-search"> <div class="site-search-content"> SuiteCommerce Site Development Develop Your Theme 236 <form class="site-search-content-form" method="GET" action="/search" data-action="search"> <div class="site-search-content-input"> <div data-view="ItemsSeacher"></div> <i class="site-search-input-icon"></i> <a class="site-search-input-reset" data-type="search-reset"><i class="site-search-input-reset-icon"></i></a> </div> <button class="site-search-button-submit" type="submit">{{translate 'Go'}}</button> </form> </div> </div> ■ Base Theme Module: SiteSearch ■ Base Theme Template: site_search.tpl The site search input bar is hidden by default in the SuiteCommerce Base Theme. However, you can customize your templates to make this input bar visible by default. To do so, add the active class to sitesearch as shown in the following example: <div class="site-search active" data-type="site-search"> Go Button <button class="site-search-button-link" data-action="show-itemsearcher" title="{{translate 'Search'}}"> <i class="site-search-button-icon"></i> </button> ■ Base Theme Module: SiteSearch ■ Base Theme Template: site_search_button.tpl Best Practices for Creating Themes Applies to: SuiteCommerce | SuiteCommerce Advanced Before creating a theme or overriding extension-related files, read and understand these best practices. The information in this section provides important steps you must take to ensure that your themes and extension overrides deploy without error. SuiteCommerce Base Theme Applies to: SuiteCommerce | SuiteCommerce Advanced The SuiteCommerce Base Theme provides a basic theme that developers can activate and use as a baseline for further theme development and activation on a domain. This is a managed bundle. This theme includes all best practices as described in Best Practices for Creating Themes. Use this theme as a starting point for theme development to ensure that your theme is compatible with your site. To use the SuiteCommerce Base Theme: 1. Install the SuiteCommerce Base Theme SuiteApp. See the help topic Install Your Commerce Web Store Applications. SuiteCommerce Site Development Best Practices for Creating Themes 237 2. Activate the SuiteCommerce Base Theme on a domain. See the help topic Manage Themes and Extensions. 3. Use the Theme Developer Tools to fetch the active theme files for the domain. See Fetch Active Theme Files. 4. Customize your theme. See Develop Your Theme and Best Practices for Creating Themes. Important Information About the SuiteCommerce Base Theme ■ When you deploy a theme based on the SuiteCommerce Base Theme, the Theme Developer Tools prompt you to create a unique name. You cannot overwrite the Base Theme but you can create a new theme based upon it. ■ The Base Theme is a managed bundle. Updates to this theme coincide with major releases of SuiteCommerce and SuiteCommerce Advanced (SCA). ■ SuiteCommerce updates are all backward compatible with the SuiteCommerce Base Theme. Therefore, when your version of SuiteCommerce receives to the latest update, any themes created with older versions of SuiteCommerce Base Theme are compatible with your SuiteCommerce site. ■ SCA customers must take care when creating themes using later releases of the SuiteCommerce Base Theme. Each managed update of the Base Theme is intended to be used with the corresponding core releases of SCA or later. Therefore, a theme created using the SuiteCommerce Base Theme 2019.1 release is compatible with sites implementing the same major release (SCA 2019.1) and later. That same theme might not be compatible on sites implementing an earlier SCA release (2018.2, for example). General Best Practices for Themes Applies to: SuiteCommerce | SuiteCommerce Advanced The following list provides some general knowledge and best practices to remember when customizing themes for Commerce web stores: ■ Use themes to customize HTML templates and Sass for your site. ■ If you are using a published theme as a baseline, the developer tools force you to create a new theme. This new theme includes your changes as a custom theme. ■ Whenever possible, use the existing folder structure as created when you downloaded themes and extensions to your Workspace directory. If you must add new subdirectories, make sure the paths to any files are included in the theme manifest and any required entry points. ■ Do not move, delete, or edit any files located in your Workspace/Extras directory. Any files located here are for reference and overrides only. ■ When you fetch a theme, you also get the HTML and Sass files for any active extensions. You can customize these files to suit your theme using the Override method. See Override Active Extension Files for details. ■ Place any new assets (images or fonts) in the appropriate location within the theme’s assets directory. ■ Use helpers when referencing any assets within your HTML or Sass customizations and overrides. See Asset Best Practices for details. ■ Follow the template context when editing HTML template files or creating overrides. See HTML Best Practices for details. SuiteCommerce Site Development Best Practices for Creating Themes 238 ■ To avoid file name collisions, do not create any new files or folders that share the same name, even if they reside in different locations. The exception to this practice is when working with extension overrides. ■ Limit the number of files and folders at the same level to 100 when developing themes and extensions. Some options include introducing images across multiple folders and placing custom modules in a different top-level directory. For more information on file and folder limiting, see the help topic SOAP Web Services Governance Overview. HTML Best Practices Applies to: SuiteCommerce | SuiteCommerce Advanced Commerce templates use the Handlebars.js templating engine to keep the HTML (presentation layer) separate from any deeper code logic. These logic-less templates help you build your themes without requiring access to deeper code. Templates define the HTML for specific areas of the user interface, such as a button or Home banner. When an associated theme is activated, the template engine combines all of these files into a single, finished web page. To achieve this, templates use an easy-to-understand syntax, which is a combination of HTML and Handlebars.js expressions (helpers). These helpers tell the templating engine to include the value of variables (properties and objects) when rendering your site or executing functions. These variables are specific to each template, depending on what the template is designed to render. This information is called the template’s context. Template Context Each template relies on its context to know what variables are available (what data the template can render). You cannot customize a template to render information it cannot provide. Therefore, you must operate within this context when making any customizations to pre-existing templates or introducing your own. Commerce templates include a list of context variables within the file itself. This lists the context objects, types, or any properties as part of an array. This information is nested within comment blocks at the end of each file. Note: If you are an extension developer making a template for an extension, the context is defined by your own custom views. See the help topic Extensibility API Tutorials for details. Note: SuiteCommerce Advanced users have access to the context within the associated view files. The following example from case_list.tpl depicts this context notation. ... {!---Use the following context variables when customizing this template: pageHeader (String) hasCases (Number) isLoading (Boolean) showPagination (Boolean) showCurrentPage (Boolean) showBackToAccount (Boolean) SuiteCommerce Site Development Best Practices for Creating Themes 239 ----}} The following code snippet depicts the hasCases number and isLoading boolean variables as used in the case_list.tpl template code. This code either renders a support case list or renders a Loading or No Cases Found string, depending on the query results. ... {{#if hasCases}} <table class="case-list-recordviews-table"> <thead class="case-list-content-table"> ... </thead> <tbody data-view="Case.List.Items"></tbody> </table> {{else}} {{#if isLoading}} <p class="case-list-empty">{{translate 'Loading...'}}</p> {{else}} <p class="case-list-empty">{{translate 'No cases were found'}}}</p> {{/if}} {{/if}} ... To find the template context in a template file: 1. In an editor, open the source .tpl file for the template you intend to customize. 2. At the end of the file, look for the following string, located within comment tags: {{!-Use the following context variables when customizing this template: ... 3. Note the context variables available to the template and customize accordingly. To find the context variables using the browser developer tools: At this time, some template files do not include this context as described above. In these cases, you can use the {{log this}} helper as described below. This procedure assumes that you have already begun customizing a template. Do not edit source files directly. Note: The examples in this section uses Google’s Chrome browser developer tools. 1. Open the template file you are customizing in an editor. 2. Include the following helper as the first line in the template for which you want to reveal the context. {{log this}} 3. Deploy your customization to your local server. See Test a Theme on a Local Server. 4. Navigate to the page rendering your custom template. 5. Using your browser’s developer tools, inspect and refresh the page. 6. The developer tools Console tab lists the variables available to the template as the output of the {{log this}} helper: SuiteCommerce Site Development Best Practices for Creating Themes 240 Sass Best Practices Applies to: SuiteCommerce | SuiteCommerce Advanced Commerce themes let you customize the design elements of your web store experience using Sass, or Syntactically Awesome StyleSheets. Sass is a scripting language that is transformed into CSS when you use the theme development tools to compile and deploy your customizations to the application. The SuiteCommerce Designer’s Guide provides more information on customizable Sass styles. See Design Architecture for details. Note: All Commerce Sass files are named as partials (with a preceding underscore), such as _BaseSassStyles.scss. Creating Sass Variables The SuiteCommerce Base Theme SuiteApp includes the BaseSassStyles module. This module contains all Sass variables and metadata (for exposing and organizing variables in SMT). The best practice when creating a theme is to use the Base Theme as a baseline. See SuiteCommerce Base Theme for details on installing this theme. You can create your own Sass variables. You can introduce variables within new Sass files, as part of a new module, or within the BaseSassStyles module. Observe the following best practices regarding new variables and their metadata: ■ If you are defining a new module as part of a theme, define all new variables and any metadata within that module. ■ If you are defining a variable for a particular module only, define that variable within the associated module. Avoid introducing global definitions within one module. ■ If you are defining a variable that controls multiple properties in different modules (such as a new theme color $sc-color-theme-250), define that variable within the BaseSassStyles module. ■ If you are adding a new Sass file to your theme, you must declare each file in the theme’s manifest.json and the applicable entry point file. See Add a New File to a Theme for details. ■ Always test any new variables in your domain, across all applications. This includes checking to ensure that any exposed variables display as expected in the Site Management Tools Theme Skin Manager. Formatting Sass for SMT Some Sass development practices can affect the Site Management Tools Theme Skin Manager user experience. As you build Sass for your theme, you can expose any variables to the SMT Theme Skin Manager. When an SMT administrator changes an exposed variable, the application compiles any changes and renders them for preview. This action includes two separate compilations. The first compilation occurs on the SuiteCommerce Site Development Best Practices for Creating Themes 241 frontend within 2 seconds. However, after 5 seconds of user idle time, the application triggers a second compilation on the backend. As a result, the following Sass practices result in variables that are only accessible in the backend. As a best practice, avoid using the following for any Sass variables exposed to SMT: ■ Sass variables that receive user-defined function calls ■ If conditional statements ■ Mixins User-defined function calls Avoid user-defined function calls. For example, consider the following example, assuming that $sc-primary-color is also : $sc-color-secondary: myfunc($sc-primary-color) /*editable(…) In this example, you set the result of an exposed variable, such as $sc-color-secondary, to a custom function, myfunc($sc-primary-color). Assuming $sc-primary-color is also declared as editable, when the SMT admin changes the primary color value, the primary color value compiles quickly in the frontend. The problem with this approach is that myfunc($sc-primary-color only exists in the backend and takes a longer time to preview. If Statements and Mixins Avoid if constructions using exposed Sass variables. For example: @if $sc-color-secondary == $12345 { background-color: $sc-color-primary;} @else { background-color: $56789;} The problem with this example is that the frontend does not know the else condition. Passing values within or grouping variables as mixins causes a similar issue. All of these issues are solved during the backend compilation, but this can take a considerable amount of time. Sass Entry Points Every theme relies on an entry point file to load Sass into the correct application (Shopping, My Account, or Checkout). Each entry point declares the Sass files that are part of the application. For example, if a Sass file affects the shopping application only, it needs to load through the shopping.scss entry point. If it affects all three applications, it needs to load through all three entry points. For an example of how to edit an entry point, see Add a New File to a Theme. Important: All Sass files must also be declared in the theme’s manifest.json file. See Theme Manifest for more information. Each theme includes the following Sass entry points: Application Impacted Application Sass File Shopping Modules/Shopping/shopping.scss My Account Modules/MyAccount/myaccount.scss Checkout Modules/Checkout/checkout.scss SuiteCommerce Site Development Best Practices for Creating Themes 242 Asset Best Practices Applies to: SuiteCommerce | SuiteCommerce Advanced An asset is an image or font that is not managed by a NetSuite account but still part of a theme or extension. An example of an asset is a carousel image, an icon, or a new font. This can be either a preexisting asset or one that you introduce as part of a new theme. When you run the gulp theme:fetch command: ■ Assets for the active theme download to your Workspace/<THEME_DIRECTORY>/assets folder. This is the location where you manage all of your assets (new and pre-existing). ■ Assets for any active extensions download to your Workspace/Extras/Extensions/ <EXTENSION_DIRECTORY>/assets folder. Do not move, delete, edit, or add files in this location. When you activate your theme, all assets are placed in specific locations in your NetSuite File Cabinet based on parameters you specify when you deployed your theme (vendor name, theme name, and theme version). Later, when you activate a newer version of the same theme, your assets are now located in a different location in your File Cabinet. Your code must adapt to the change in the path. If you use absolute paths, the links to these assets will break. Important: Do not use absolute paths when referring to assets in your code customzations and overrides. Asset files are managed in different locations in NetSuite based on the theme’s vendor, extension name, version, etc. As a best practice, always use the HTML and Sass helpers when referencing assets to ensure that you maintain dynamic paths without unnecessary code changes. We provide a few HTML Helpers and Sass Helpers to maintain dynamic paths to your assets, regardless of the vendor, theme, version, etc. Example: Using the theme development tools, you deploy a new theme (MyTheme1, Version: 1.0.0). You then activate that theme for a specific site and domain. The compiler places all assets in your NetSuite File Cabinet. The exact location is specific to the SSP Application, vendor, extension, and version that you specified when you deployed your theme. This location might be similar to the following: SuiteCommerce Site Development Best Practices for Creating Themes 243 Later, you decide to update your theme, giving it a new version, 2.0.0. When you activate your latest version, the compiler places all assets into a new location: HTML Helpers Applies to: SuiteCommerce | SuiteCommerce Advanced The following four Handlebars.js helpers provide a means to maintain dynamic paths to your assets when customizing HTML templates. getExtensionAssetsPath(default_value) Use this HTML template helper: ■ To access pre-existing assets included with an active extension ■ In your extension overrides (templates) Note: The default_value argument is the relative path to the asset. Example Syntax in a Template File: The following is an example of how to use this helper in an HTML template: <img src="{{ getExtensionAssetsPath 'img/logo.png' }}"> Example Result: This helper returns the active extension’s asset path (where <FULL_PATH> is the SSP Application base path): SuiteCommerce Site Development Best Practices for Creating Themes 244 <FULL_PATH>/extensions/<VENDOR>/<EXTENSION>/<VERSION>/img/logo.png getExtensionAssetsPathWithDefault(config_value, default_value) Use this HTML template helper: ■ To access pre-existing assets included with an active extension ■ In your extension overrides (templates) ■ When you expect that the asset has a configured path in NetSuite, but want to provide a default path if the configuration does not exist. Note: The first argument (config_value) is the path as configured in NetSuite. In cases where the asset is not configured, you provide a fallback path (default_value) to be retrieved from the extension’s assets. Example Syntax in a Template File: The following is an example of how to use this helper in an HTML template: <img src="{{getExtensionAssetsPathWithDefault logo_path 'img/logo.png' }}" > Example Result: This helper returns the active extension’s asset path. If the first argument is defined, this helper returns the path as configured in NetSuite: <MY_PATH>/img/other_logo.png If the first argument is undefined, this helper uses the second argument to return the correct path of the active extension: <FULL_PATH>/extensions/<VENDOR>/<EXTENSION>/<VERSION>/img/logo.png getThemeAssetsPath(default_value) Use this HTML template helper: ■ To access new and pre-existing assets included in your theme directory ■ In your extension overrides (templates) ■ In your theme customizations (templates) Using this helper, default_value is the relative path to the asset. Example Syntax in Template File: <img src="{{ getThemeAssetsPath 'img/logo.png' }}" > Example Result: This helper returns the active theme’s asset path (where <FULL_PATH> is the SSP Application base path): SuiteCommerce Site Development Best Practices for Creating Themes 245 <FULL_PATH>/extensions/<VENDOR>/<THEME_NAME>/<VERSION>/img/logo.png getThemeAssetsPathWithDefault(config_value, default_value) Use this HTML template helper: ■ To access new and pre-existing assets included in your theme directory ■ In your extension overrides (templates) ■ In your theme customizations (templates) ■ When you expect that the asset has a configured path in NetSuite, but want to provide a default path if the configuration does not exist. Using this helper, config_value is the path as configured in NetSuite. In cases where the asset is not configured, you provide a fallback path (default_value) to be retrieved from the extension’s assets. Example Syntax in Template File: <img src="{{ getThemeAssetsPathWithDefault logo_path 'img/logo.png' }}" > Example Result: This helper returns the active theme’s asset path. If the first argument is defined, this helper returns the path as configured in NetSuite: <MY_PATH>/img/other_logo.png If the first argument is undefined, this helper uses the second argument to return the correct path of the active theme: <FULL_PATH>/extensions/<VENDOR>/<THEME_NAME>/<VERSION>/img/logo.png Sass Helpers Applies to: SuiteCommerce | SuiteCommerce Advanced The following two helpers provide a means to maintain dynamic paths to your assets when customizing Sass files. getExtensionAssetsPath($asset) Use this Sass helper: ■ To access pre-existing assets included with an active extension ■ In your extension overrides (Sass) Example Syntax in a Sass File: body { background-image: url(getExtensionAssetsPath('img/background-image.png')); SuiteCommerce Site Development Best Practices for Creating Themes 246 } Example Result: This helper returns the active extensions’s asset path. <FULL_PATH>/extensions/<VENDOR>/<EXTENSION>/<VERSION>/img/logo.png getThemeAssetsPath($asset) Use this Sass helper: ■ To access new and pre-existing assets included in your theme directory ■ In your extension overrides (Sass) ■ In your theme customizations (Sass) Example Syntax in a Sass File: body { background-image: url(getThemeAssetsPath('font-awesome')); } Example Result: This helper returns the active theme’s asset path. <FULL_PATH>/extensions/<VENDOR>/<THEME_NAME>/<VERSION>/font-awesome Design Architecture Applies to: SuiteCommerce | SuiteCommerce Advanced The Commerce design architecture provides an intuitive, robust, and flexible solution that lets you customize the design elements of your web store experience with ease. Commerce web stores use the Sass CSS extension language. With Sass, CSS syntax is fully supported in addition to features such as variables and imports. Sass source code also uses KSS notation to assist in building a Style Guide. This requires the Kilimanjaro release of SuiteCommerce Advanced. Important: This section provides details on the design architecture. For a complete catalog of all design components and the user experience workflows see the Design section of the SuiteCommerce Developer’s Portal at developer.suitecommerce.com. Design Hierarchy Applies to: SuiteCommerce | SuiteCommerce Advanced Sass styles are organized in a hierarchy as follows: SuiteCommerce Site Development Best Practices for Creating Themes 247 ■ Base Sass Styles: These are the basic components designed to be combined and reused across the site. ■ Template Specific Styles: Sass styles specific to a page or template are defined here. These are extensions and combinations of the base components. ■ Application Level Styles: Within the Base Sass Styles, you can define components that are referenced from a specific application: ShopFlow, My Account, or Checkout. This lets you define unique styling for each application experience. Base Sass Styles In SuiteCommerce Advanced core styles are defined as reusable components. Core reusable components can then be iteratively combined to create increasingly complex structures such as templates and pages. All basic components are defined within the BaseSassStyles folder at Modules > suitecommerce > BaseSassStyles. Components are categorized into three different types: ■ atoms: basic building blocks to be used within other structures. For example, buttons, messages, and forms. ■ molecules: simple combinations of atoms. Molecules are built for reuse but serve different purposes depending on the page context. ■ variables: basic styling rules such as spacing and typography, that are then referenced and extended in atoms and molecules. Template Specific Styles Each module contains a Sass folder that defines styling rules specific to the templates used for that module. Within these Sass files, the Base Sass Style components are used as the starting point and then extended as needed. There is generally a single Sass file corresponding to each template file within a module. For example, the Address module has a address-details.tpl file in the Templates folder of the module with a corresponding _address-details.scss Sass file in the Sass folder of the module. Within the _address-details.tpl file the address-details-remove-address class is referenced. This class is defined in the _address-details.scss file where base classes are extended to add styles specific for this template. Class Referenced in Template File: {{#if showRemoveButton}} <button class="address-details-remove-address" data-action="remove" data-id="{{internalid}}" {{#if isInvalidAddressToRemove}}dis abled{{/if}}> {{translate 'Remove'}} SuiteCommerce Site Development Best Practices for Creating Themes 248 </button> {{/if}} Class Defined in Sass File: .address-details-remove-address { @extend .button-edit; margin-right: $sc-base-margin-lvl2; cursor: pointer; } Application Level Styles In addition to defining styles specific to a module using template-specific classes, you can define styles to be specific to each application. The ShopFlow, My Account, and Checkout experiences can all have a unique design. By default, for each application module, there is a single layout Sass file with several application specific style extensions defined. ■ _shopping-layout.scss ■ _myaccount-layout.scss ■ _myaccount-layout-sb.scss ■ _checkout-layout.scss Also, you can define application specific dependencies for base styles or customizations in the theme manifest file. Each file must also be added as a dependency to the appropriate application in the sass object before styles defined in those files can be included when you deploy. See Theme Manifest for details. Style Definitions Applies to: SuiteCommerce | SuiteCommerce Advanced To help you maintain and develop Sass variables, Commerce web stores use the following Sass style definitions. These provide flexible, comprehensible, and easy-to-maintain variables and their values. This section explains how Commerce web stores use the following style definitions: ■ Colors ■ Typography ■ Spacing Note: To ensure inheritance and to define variables in a readable way, Commerce web stores use the KSS notation to define them. See Style Guide for details. Colors Colors represent a large number of variables throughout SuiteCommerce and SuiteCommerce Advanced. These are represented as primary colors, secondary colors, themes, messaging, links, and neutral shades. Neutral shades and theme colors are handled with a slight difference to other color definitions. Both neutral shades and theme color palettes use a shading scale from 1000 (dark) to 0 (light). SuiteCommerce Site Development Best Practices for Creating Themes 249 For example, the BaseSassStyle module defines neutral shades in the following variables: //... $sc-neutral-shade-base: #222426; $sc-neutral-shade-900: $sc-neutral-shade-base; $sc-neutral-shade-600: lighten($sc-neutral-shade-base, 18); $sc-neutral-shade-300: lighten($sc-neutral-shade-base, 55); $sc-neutral-shade-0: lighten($sc-neutral-shade-base, 100); //... In this example, sc-neutral-shade-base defines the base neutral value #222426, which is a very dark gray. Commerce web stores declare other neutral shades as calculated percentages of the base. Therefore, sc-neutral-shade-900 has no calculation and matches the base shade. However, sc-neutral-shade-600 renders as the base shade lightened by 18%. As we progress through each neutral shade, shades becomes lighter. You can extend the class definitions in the _colors.scss file to introduce intermediate shades in this manner. The theme color palette handles colors in a similar way. Instead of defining a hexadecimal value, the theme palette defines a previously declared color value. For example, $sc-color-secondary. Typography Like color variables, Commerce web stores declare typography variables in an intuitive, human-readable manner. This relies on the familiar sizing method of extra-small (xs) through triple-extra-large (xxxl). Each of these sizes is relative to a base font size ($sc-font-size-base). The source Sass expresses the base font size in pixels and all related font sizes in rem units (relative em). 1rem equals the font size of the base element. Therefore, 1.067rem is a calculation meaning the value for $sc-font-size-base times 1.067. In the following example from _typography.scss, $sc-font-size-m is equal to 15 pixels (1 x 15px), and $scfont-size-l is equal to about 16 pixels (1.067 x 15px). Likewise, $sc-font-size-xxxl is equal to about 26 pixels (1.73 x 15px). //... SuiteCommerce Site Development Best Practices for Creating Themes 250 $sc-font-size-base: 15px; $sc-font-size-xxs: 0.75rem; $sc-font-size-xs: 0.87rem; $sc-font-size-s: 0.93rem; $sc-font-size-m: 1rem; $sc-font-size-l: 1.067rem; $sc-font-size-xl: 1.2rem; $sc-font-size-xxl: 1.47rem; $sc-font-size-xxxl: 1.73rem; //... Spacing Spacing variables affect the structural height, width, and spacing of elements. These are most commonly referred to as the padding and margins. Like color and typographic variables, spacing variables are declared in an intuitive, human-readable manner. Commerce web stores use levels to indicate the added or reduced space for a class relative to a base style. Each level designation in the named variable equals the multiplier. That is, lv2 bares a multiplier of 2. In the following example from _spacing.scss, $sc-padding-base is equal to 5 pixels, and $sc-padding-lv2 is equal to 10 pixels (2 x 5px). Likewise, $sc-padding-lv8 equals 40 pixels (8 x 5px). //... $sc-padding-base: 5px; $sc-padding-lv1: $sc-padding-base; $sc-padding-lv2: $sc-padding-base * $sc-padding-lv3: $sc-padding-base * $sc-padding-lv4: $sc-padding-base * $sc-padding-lv5: $sc-padding-base * $sc-padding-lv6: $sc-padding-base * $sc-padding-lv7: $sc-padding-base * $sc-padding-lv8: $sc-padding-base * 2; 3; 4; 5; 6; 7; 8; //... Style Guide Applies to: SuiteCommerce Advanced This information refers to the Aconcagua and Kilimanjaro releases of SuiteCommerce Advanced only. A style guide helps developers and designers use the various style elements defined for a site. Contributors can refer to a style guide to create new pages and elements or customize existing ones. A style guide can also ensure that your best practices for site design are being met by multiple contributors. You can use the developer tools to create a style guide automatically. To do so, the source BaseSassStyles module uses KSS notation to document and define Sass elements. As a best practice, build any Sass customizations using KSS notation as defined in this section. To create a style guide using the developer tools: 1. In your local developer environment, open a command line or terminal and access the top-level development directory. 2. Run the following command: gulp theme:local styleguide SuiteCommerce Site Development Best Practices for Creating Themes 251 3. Point your browser to: localhost:3000 You should see your style guide appear, looking similar to the following example: KSS Notation Commerce web stores use Knyle Style Sheets (KSS) notation to automate the creation of a Sass style guide. KSS is simply a documentation syntax for CSS, written in a human-readable way. A style guide serves as a place to publish KSS documentation and visualize different states of user interface elements defined in your Sass. Note: KSS does not affect the performance or rendering of CSS in any way. It is meant to document your styles in a human-readable way and automate the creation of a related style guide. The following elements of this notation appear before each element defined in a Sass file. These are parsed and used to create a style guide automatically using the developer tools. ■ Title – defines the element. Best practice is to use an intuitive, human-readable title. ■ Description – briefly explains the intended purpose and implementation of the element. ■ Markup – provides the HTML markup used to generate the element. ■ Index – defines where the element exists within the style guide structure. For example: 2.0 2.1 2.1.1 2.1.2 SuiteCommerce Site Development Best Practices for Creating Themes 252 2.2 2.2.1 The following example comes from the base Sass style atom _buttons.scss and highlights the basics of KSS notation as used by Commerce web stores. //... // Primary buttons (This is an example of the Title element) // // The primary action is generally the action that completes a task or desired action. // Primary buttons use bright and use saturated colors to provide stronger visual weight that catches the users attention to avoid confusion and competing with secondary actions. (This is an example of the Description element) // // Markup: // <button class='button-primary button-medium">Button Primary</button> (This is an example of the Markup element) // // Styleguide 2.1.1 (This is an example of the Index element) .button-primary { color: white; font-weight: $sc-font-weight-normal; background: $sc-color-button-primary; display: inline-block; border: 1px solid $sc-color-button-primary; border-radius: $sc-border-radius; //... Mobile First Applies to: SuiteCommerce | SuiteCommerce Advanced SCA is developed with a Mobile First approach. Mobile First design results in faster, sleeker sites while enabling for easier design. Developing sites with the Mobile First approach promotes using only the most important elements on your screen while avoiding cluttering the screen with secondary elements not critical to the current task. This enhances the user experience by allowing users to quickly find and finish the task at hand whether it be finding a product to purchase in a B2C environment or reordering in bulk in a B2B environment. Using the Mobile First approach, element styles are defined for mobile devices and then scaled progressively for tablet and desktop display. For example, in the following code sample the .button—medium style is defined with a width of 100%. Only when the media is of $screen—sm—min size (tablet) is the width adjusted. The default media sizes are all defined in Sass variable files. .button-medium{ padding:$sc-base-padding * 2.5 $sc-base-padding * 4; letter-spacing:0.5px; font-size: $sc-button-medium-font-size; width:100%; text-align: center; line-height:1; } @media(min-width: $screen-sm-min){ width: auto; } SuiteCommerce Site Development Theme Manifest 253 Theme Manifest Applies to: SuiteCommerce | SuiteCommerce Advanced Your theme’s workspace includes a manifest.json file for the theme. This file is located in each theme directory within the Workspace directory. The theme’s manifest is a JSON file that includes all the information required to compile resources for an active theme. This topic explains this file. Workspace/<THEME_DIRECTORY>/manifest.json This file lists all HTML templates, Sass, and assets related to the active theme that you downloaded when you ran the gulp theme:fetch command. You only need to edit this file to introduce any new HTML, Sass, or assets you create as part of your theme customizations. You can edit Skin labels as well at your option. Note: See Add a New File to a Theme for instructions on how to edit this file when you add any new HTML, Sass, or assets. This file also manages any extension overrides. However, the theme development tools add the necessary overrides to this manifest when you deploy your customizations. This section describes the following sections of the theme manifest: ■ Theme Metadata ■ Overrides ■ Templates ■ Sass ■ Skins ■ Assets ■ Record Paths Theme Metadata The first entries in the manifest file include metadata about the theme or extension itself. These fields are automatically populated when you initially run the gulp theme:deploy command. { "name": "StandardTheme", "vendor": "SuiteCommerce", "type": "theme", "target": "SuiteCommerce", "version": "1.2.0", "description": "Standard theme for SuiteCommerce", //... ■ Name (string) – uniquely identifies the name of the theme. This field is required. ■ Vendor (string) – identifies the vendor as a string. This field is required. ■ Type (string) – indicates if the type as a theme. This field is required. ■ Target (comma-separated string) – indicates the Commerce applications supported by the theme. This field is required. ■ Version (string) – indicates the version of the theme, such as 1.0.0. This field is required. ■ Description (string) – provides a description of the theme as it appears in NetSuite. This field is optional. SuiteCommerce Site Development Theme Manifest 254 Overrides The override object is only included if you introduce extension overrides. When you use the Override method, the Gulp.js commands detect any HTML or Sass overrides and include them in this file automatically. For example, if you override the _error.sass file of the Extension1 extension and run the gulp theme:deploy command, the theme development tools add the following override your theme’s manifest.json file as part of the deployment process: //... "override": [ { "src": "Overrides/Extension1/Modules/MyExamplePDPExtension1/Sass/_error.scss", "dst": "Extension1/Modules/MyExamplePDPExtension1/Sass/_error.scss" }, //... Templates The templates object lists all HTML template files included in the theme by application. The application object includes one object per application (shopping, myaccount, and checkout). Each application lists each file in the files array. You manually add any new template files to this array that you introduced as part of your theme customizations. //... "templates": { "application":{ "shopping":{ "files":[ "Modules/AddToCartModifier/Templates/add_to_cart_modifier.tpl" //... ] } "myaccount":{ "files":[ //... ] } "checkout":{ "files":[ //... ] } } } //... Sass The sass object declares the paths to each application entry point and all Sass files to be loaded when you deploy. You manually add any new Sass files to the files array that you introduced as part of your theme customizations. Note: When listing a new Sass file, declare each file in an order that makes the most semantic sense within the Sass hierarchy. //... SuiteCommerce Site Development Theme Manifest 255 "sass": { "entry_points":{ "shopping":"Modules/Shopping/shopping.scss", "myaccount": "Modules/MyAccount/myaccount.scss", "checkout": "Modules/Checkout/checkout.scss" } "files":[ "Modules/Shopping/shopping.scss", "Modules/MyAccount/myaccount.scss", "Modules/Checkout/checkout.scss", "Modules/twitter-bootstrap-sass@3.3.1/assets/stylesheets/bootstrap/_alerts.scss", //... ] } //... Skins The skins array is automatically populated when you run either the gulp theme:local or gulp theme:deploy commands. This array defines an object for each new skin preset file located in the Skins directory when you run these commands. Each skin object includes the following properties: ■ name – declares the name of the skin as it appears in SMT. As a default, this value equals the file name. ■ file – declares the name and location of the skin preset file. This name must match the name of the file in the Skins directory. //... , 'skins': [ { 'name': 'winter_skin' , 'file': 'Skins/winter_skin.json' } , { 'name': 'spring_skin' , 'file': 'Skins/spring_skin.json' } , { 'name': 'summer_skin' , 'file': 'Skins/summer_skin.json' } , { 'name': 'fall_skin' , 'file': 'Skins/fall_skin.json' } ] //... By default, If necessary, you can edit the manifest.json file to provide a more visually appealing value for the name property. Example 2. Example You want to provide four selectable skins for a theme, each with a different color scheme to correspond with the different seasons: winter, spring, summer, and fall. You create four individual skin preset files in your theme’s Skins directory: winter_skin.json, spring_skin.json, summer_skin.json, and fall_skin.json. You use the theme developer tools to run the theme gulp:local command. The developer tools automatically edit your theme’s manifest.json file: Later, you decide that you want the SMT Theme Skin Manager to display different names for each skin. You open the manifest.json file and make the following edits to each skin object’s name property: SuiteCommerce Site Development Theme Manifest 256 Assets The assets object defines paths to the images and fonts located in the theme directory’s assets folder. This defines an array for each image and font used. These paths are relative to the theme’s assets folder path. This is where you add any new asset files introduced as part of your theme customizations. //... "assets": { "img": { "files": [ "img/favicon.ico", "img/image-not-available.png", "img/add-to-cart-logo.png", //... ] }, "font-awesome": { "files": [ "font-awesome/FontAwesome.otf", "font-awesome/custom/fontawesome-webfont.eot", //... ] }, "fonts": { "files": [ "fonts/DancingScript-Bold.ttf", "fonts/DancingScript-Regular.ttf", //... ] } } //... Record Paths The final part of the manifest file lists the path to the theme, the Extension record and Activation IDs as stored in NetSuite. //... "path": "SuiteBundles/Bundle 193239/SuiteCommerce Base Theme", "extension_id": "4535", "activation_id": "59" SuiteCommerce Site Development Extensions 257 Extensions Applies to: SuiteCommerce | SuiteCommerce Advanced This topic introduces you to extension development for SuiteCommerce, SuiteCommerce MyAccount, and SuiteCommerce Advanced (SCA). Explore the following topics: ■ Develop Your Extension – This topic provides a general checklist to follow when creating an extension. This process includes building baseline files and calling the Extensibility API to customize the application and add new features or functions. ■ Create Page Types – This topic explains how to create a new page type within your extension for use with Site Management Tools (SMT). ■ Extension Manifest – This topic describes the manifest.json file, an auto-generated file that manages all compilation information for your extension. This topic also explains how to manually edit this file. ■ Troubleshoot Activation Errors – This topic explains how to use the Extension Manager in NetSuite to investigate errors with your activations. You build extensions to interact with the Extensibility API to accomplish some task. Instead of altering frontend or backend code, you create extensions using SuiteCommerce Components to interact with the API. The API then makes calls to deeper structures of the code base. See the help topic Extensions API for more details. Important: To develop an extension, you must have experience working with JavaScript, HTML, and Sass/CSS. The level of experience required depends on the types of changes you want to make. Advanced JavaScript programming skills, including knowledge of APIs, Backbone.js and jQuery are required. Benefits of Using Extensions Extensions introduce added functionality to a Commerce website through any number of JavaScript, SuiteScript, configuration JSON, and other files bundled into a single SuiteApp or deployed to a NetSuite account for later activation using the Manage Extensions wizard (included with the SuiteCommerce Extensions Management SuiteApp). One important benefit of extensions is that they allow non-technical users to extend and update their site by installing and activating any number of pre-developed features from a marketplace. Extensions provide many other benefits: ■ Partners can publish and distribute extensions as bundled SuiteApps. ■ In-house site developers working with SuiteCommerce or SuiteCommerce Advanced (SCA) can create and manage their own extensions and activate them for any domains associated with a site. ■ Extension developers can access much of the functionality that the NetSuite platform currently provides (SuiteScript, custom records/fields/forms, etc.). ■ Extensions eliminate version lock within SCA. This means that users have access to easier upgrades that do not compromise the functionality of features previously activated or enabled for a site. SuiteCommerce Site Development Develop Your Extension 258 ■ Extensions rely on accessing the Extensibility API, which ensures developers maintain backwards compatibility with SuiteCommerce code or with previous releases of SCA. Develop Your Extension Applies to: SuiteCommerce | SuiteCommerce Advanced Extensions require interacting with the Extensibility API. The Extensibility API is available to extension developers for both SuiteCommerce and SuiteCommerce Advanced (SCA). Be aware of the following requirements: ■ SuiteCommerce – The Extensibility API is required to create extensions for SuiteCommerce. ■ SuiteCommerce Advanced (Aconcagua and later) – Creating extensions using the Extensibility API is a best practice for developing Suite Commerce Advanced. However, if your SCA customizations require access to JavaScript, SuiteScript, or configuration objects that are not accessible using this API, you must use the core SCA developer tools and customization practices. See Core SCA Source Code for details. ■ SuiteCommerce Advanced (Kilimanjaro and earlier) – The Extensibility API is not available for these implementations of SCA. To take advantage of themes, extensions, and the Extensibility API, you must either migrate your site to the latest release of SCA or use the core SCA developer tools and customization practices to customize your site. See Core SCA Source Code for details. Extension Development Steps Follow this general guide to develop your extension: Step Description More Information 1 Create a set of baseline extension files. Create Extension Files The extension developer tools give you a starting point for extension development. Follow these instructions to create a baseline Hello World extension. 2 Customize your extension. Extensions API You can introduce JavaScript, SuiteScript, Json, HTML templates, and Sass files, as needed. The Extensibility API is available to access frontend and backend modules within the application. 3 Add any assets to your extension source files, such as fonts and images. This step requires manually updating your extension’s manifest.json file. Extension Manifest 4 Optionally build your extension to integrate with Site Management Tools (SMT). Create a Custom Content Type You can create your extension as a Custom Content Type (CCT) or create new CMS Page Types and designate tempaltes as selectable layouts for new and existing pages in SMT. Create Page Types Deploy your extension. Deploy an Extension to NetSuite 5 You can test your extension on a local server. However, you must first deploy your extension files to your account and activate the extension on a domain before testing locally. SuiteCommerce Site Development Develop Your Extension Step Description More Information 6 Activate your extension. Manage Themes and Extensions To see your extension in action, you must activate it for a domain. 259 7 After activating your extension for a domain in NetSuite, you can test your extension code on a local server for debugging purposes. Test an Extension on a Local Server 8 When you are satisfied with your extension code, deploy using the extension developer tools. Deploy an Extension to NetSuite Important: You must activate the extension before any deployed changes take effect. See the help topic Manage Themes and Extensions for details. 9 Create a bundle for your extension. If you intend to publish your extension and share it with other accounts, follow these instructions to bundle your extension as a SuiteApp. Theme and Extension SuiteApps Create Page Types Applies to: SuiteCommerce | SuiteCommerce Advanced Page types let Site Management Tools (SMT) administrators introduce a variety of pages and layouts to a website. When SMT admins create new pages in SMT, they define it as a specific page type. This can be either the default landing page or any newly created page type introduced through an extension. SMT admins can also change the layout of existing pages. When SMT admins edit an existing core page, they create an enhanced page and can select from a list of different layouts, based on the layout options defined by the extension. However, for these elements to be available in SMT, extension developers must first set up an extension to register page types and templates using the Extensibility API. Note: Page types are associated with CMS Page Type records. For more information on these records in NetSuite, see CMS Page Type Record. For more information on creating new pages using SMT, see Page Layout Selector. The following steps explain how to set up a Commerce extension to: ■ Create a new CMS Page Type record in NetSuite ■ Register new page types to be available when creating new pages for a Commerce website using SMT ■ Create templates and define them as either a default layout for a page type or as alternative layout options SuiteCommerce Site Development Create Page Types Note: These steps assume that you have already started building an extension using the extension developer tools. See Extension Development Steps for a checklist of steps required to build an extension. Step Description More Information 1 Set up your extension to create a new CMS Page Type record in NetSuite. This requires manually editing your extension’s manifest.json file. Add a CMS Page Type Record During testing and development, you need to create this CMS Page Type record manually. Note: Your extension automatically creates the CMS Page Type record when it is installed into an account from a bundle. During early testing, however, your extension is not yet part of a bundle, so you must manually create it. 2 Create a view for your new page type. This JavaScript file is essential to render the instance of the page type. This file must extend PageType.Base.View.js. Create a View to Render a Registered Page Type 3 Create a template to act as the default layout for your registered page type. SMT Templates and Areas 4 Register your new page type using the Extensibility API. Register a Page Type 5 Register alternative layouts using the Extensibility API. Register a Template Every page type includes a default layout. However, you can register other templates to be available as alternative layout options for a new or existing page types. SuiteCommerce Site Development 260 Create Page Types Step Description More Information 6 Create template thumbnails as assets. Create Layout Thumbnails 261 Each template file corresponds to a different layout option, selectable in SMT when creating a new page. Each template includes a thumbnail preview image that you include with the extension. 7 Deploy your changes. You can test your extension on a local server. However, you must first deploy your extension files to your account and activate the extension on a domain to test the functionality in SMT. Deploy an Extension to NetSuite. Important: You must activate the extension before any deployed changes take effect. See the help topic Manage Themes and Extensions for details. 8 Log into SMT and use the Layout Selector when creating a new page or editing Page Layout Selector an enhanced page. Add a CMS Page Type Record Applies to: SuiteCommerce | SuiteCommerce Advanced You set up your extension’s manifest.json file to automatically create a new CSM Page Type record. When a user installs your extension from a bundle, NetSuite automatically creates the record based on the parameters you set here. To set up your extension to create a CMS Page Type record: 1. Open your extension’s manifest.json file. This is located in your Workspace/[extension] folder. 2. Add the page object and types array. Create a new object in the types array for each new page type you want your extension to create. See Page in the Extension Manifest topic for details. 3. Save your manifest.json file. Page Types in a Development Environment During early testing and development, no bundle exists for your extension. You can test an extension by deploying it to an account. However, since the bundle installation is what triggers the CMS Page Type record creation, you must manually create the record in NetSuite to test your extension. This is not the typical user experience, but it is necessary to build the mechanism during development. Observe these minimum requirements for testing a CMS Page Type record with your extension: ■ The Name and Display Name fields are mandatory. ■ The Name field must match the name parameter in the registerPageType() method in your extension’s entrypoint JavaScript file. No spaces or special characters are allowed in this field. See the help topic Register a Page Type for details. ■ To appear in SMT, the CMS Creatable field must be set to Yes. To create a CMS Page Type record manually, see CMS Page Type Record. SuiteCommerce Site Development Create Page Types 262 Create Layout Thumbnails Applies to: SuiteCommerce | SuiteCommerce Advanced Part of setting up a layout in your extension includes specifying a layout thumbnail. This image acts as a small preview or representation of the associated layout. Here is an example of thumbnails in use in Site Management Tools (SMT): You can download a collection of stock images to use for your thumbnails or as a starting point when developing your own: Stock SMT Layout Thumbnails. If you create your own thumbnails, follow these best practices when creating thumbnails: ■ When possible, use the stock thumbnails provided as a starting point. ■ Format thumbnail images as SVG files. Other image types are supported, but SVGs provide more versatility and scalability with typically smaller file sizes. ■ Limit file sizes to NetSuite file size limitations. See the help topic Best Practice for Preparing Files for Upload to the File Cabinet for details. ■ Create thumbnail images with either of the following pixel dimensions: □ 84 x 84 px □ 180 x 180 px □ 245 x 245 px ■ Introduce thumbnail images within your extension as assets. This requires editing your extension’s manifest.json file and using HTML helpers to register them. See the following help topics for details: □ Asset Best Practices □ Extension Manifest ■ Include a reference to these thumbnails when you register your page types or layouts. See the help topics Register Page Types and Templates for SMT and HTML Helpers for help. Extension Manifest Applies to: SuiteCommerce | SuiteCommerce Advanced Your extension’s Workspace directory includes a manifest.json file, which includes all the information required to compile resources for the extension. SuiteCommerce Site Development Extension Manifest 263 ../Workspace/<EXTENSION_DIRECTORY>/manifest.json This file is auto-generated when you execute the gulp extension:create command and includes all JavaScript, JSON, SuiteScript, HTML templates, Sass, and assets required to compile and activate your extension. Manual Edits This file lists all JavaScript, JSON, SuiteScript, HTML templates, Sass, and assets related to your extension. Although this file is automatically generated, you may need to update it manually if adding Sass entry points for any newly introduced Sass files or changing CCT labels. Warning: Potential data loss. Besides compiling and deploying your extension to a local server, the gulp extension:local and gulp extension:deploy commands update the extension’s manifest.json file and overwrites any manual changes you made to this file. To preserve manual changes to manifest.json use the following commands to test your extension locally or deploy to NetSuite: ■ gulp extension:local --preserve-manifest ■ gulp extension:deploy --preserve-manifest Extension Metadata The first entries in the manifest file include metadata about the extension itself. These fields are automatically populated when you initially run the gulp extension:create command. { "name": "MyCoolExtension", "fantasyName": "My Cool Extension!", "vendor": "Acme", "type": "extension", "target": "SCA,SCS", "target_version": { "SCA": "19.2.0", "SCS": "19.2.0" }, "version": "1.0.0", "description": "My cool extension does magic!", //... ■ name (string) – uniquely identifies the name of the extension. This field is required. This must be alphanumeric characters without spaces. ■ fantasyName (string) – identifies the label for the extension. This field can include special characters. ■ vendor (string) – identifies the vendor as a string. This field is required. ■ type (string) – indicates the type as an extension. This field is required. ■ target (comma-separated string) – indicates the SuiteCommerce or SCA applications supported by the extension. This field is required. ■ target_version ( array) – indicates the SuiteCommerce or SCA application versions supported by the extension. This field is required. ■ version (string) – indicates the version of the extension, such as 1.0.0. This field is required. ■ description (string) – provides a description of the extension as it appears in NetSuite. This field is optional. SuiteCommerce Site Development Extension Manifest 264 Important: To take advantage of extension update requirements, version numbers should follow this format, where d is a single digit: dd.dd.dd. Assets The assets object defines paths to the images and fonts located in the extension directory’s assets folder. This defines an array for each image and font used. These paths are relative to the extension’s assets folder path. Extensions treat services as assets. These are created on NetSuite servers when you activate/ deploy your extension. If the extension developer tools detect a file name with the pattern XYZ.ServiceController.js, they create the service (.ss) file and add a reference in the manifest. Later, when you activate the extension, the .ss file deploys to the backend as an asset. //... "assets": { "img": { "files": [] }, "fonts": { "files": [] }, "services": { "files": [ "services/MyCoolModule.Service.ss", "services/AdditionalCoolModule.Service.ss" ] } }, //... Configuration The configuration object defines paths to the JSON files in your extension directory’s Configuration folder. //... "configuration": { "files": [ "Modules/MyCoolModule/Configuration/MyCoolModule.json", "Modules/AdditionalCoolModule/Configuration/AdditionalCoolModule.json" ] }, //... Templates The templates object lists all HTML template files included in the extension by application. The application object includes one object per application (shopping, myaccount, and checkout). Each application lists each file in the files array. //... "templates": { "application": { SuiteCommerce Site Development Extension Manifest } }, //... 265 "shopping": { "files": [ "Modules/MyCoolModule/Templates/acme_mycoolextension_mycoolmodule_list.tpl", "Modules/MyCoolModule/Templates/acme_mycoolextension_mycoolmodule_edit.tpl", "Modules/AdditionalCoolModule/Templates/acme_mycoolextension_additionalcoolmodule_list.tpl", "Modules/AdditionalCoolModule/Templates/acme_mycoolextension_additionalcoolmodule_edit.tpl" ] }, "myaccount": { "files": [ "Modules/MyCoolModule/Templates/acme_mycoolextension_mycoolmodule_list.tpl", "Modules/MyCoolModule/Templates/acme_mycoolextension_mycoolmodule_edit.tpl", "Modules/AdditionalCoolModule/Templates/acme_mycoolextension_additionalcoolmodule_list.tpl", "Modules/AdditionalCoolModule/Templates/acme_mycoolextension_additionalcoolmodule_edit.tpl" ] }, "checkout": { "files": [ "Modules/MyCoolModule/Templates/acme_mycoolextension_mycoolmodule_list.tpl", "Modules/MyCoolModule/Templates/acme_mycoolextension_mycoolmodule_edit.tpl", "Modules/AdditionalCoolModule/Templates/acme_mycoolextension_additionalcoolmodule_list.tpl", "Modules/AdditionalCoolModule/Templates/acme_mycoolextension_additionalcoolmodule_edit.tpl" ] } Sass The sass object declares the paths to each application entry point and all Sass files to be loaded when you deploy. If you introduce a new Sass file into your extension workspace, you must manually add it to the files array within the sass object. Note: If manually listing Sass files, declare each file in an order that makes the most semantic sense within the Sass hierarchy. If the developer tools automatically added a Sass file, the entry is always at the end of the files array. However, your dependencies may require that this order be changed. Check the order in which a file was added to the array because the developer tools always add a file to the end of the array. //... "sass": { "entry_points": { "shopping": "Modules/MyCoolModule/Sass/_mycoolextension-mycoolmodule.scss", "myaccount": "Modules/MyCoolModule/Sass/_mycoolextension-mycoolmodule.scss", "checkout": "Modules/MyCoolModule/Sass/_mycoolextension-mycoolmodule.scss" }, "files": [ "Modules/MyCoolModule/Sass/_mycoolextension-mycoolmodule.scss", "Modules/MyCoolModule/Sass/_mycoolmodule.scss", "Modules/AdditionalCoolModule/Sass/_mycoolextension-additionalcoolmodule.scss", "Modules/AdditionalCoolModule/Sass/_additionalcoolmodule.scss" "Modules/AdditionalCoolModule/Sass/sass-extension_myNewSassFile.scss" ] }, //... JavaScript The javascript object declares the paths to each application entry point and all JavaScript files to be loaded when you deploy. SuiteCommerce Site Development Extension Manifest //... "javascript": { "entry_points": { "shopping": "Modules/MyCoolModule/JavaScript/Acme.MyCoolExtension.MyCoolModule.js", "myaccount": "Modules/MyCoolModule/JavaScript/Acme.MyCoolExtension.MyCoolModule.js", "checkout": "Modules/MyCoolModule/JavaScript/Acme.MyCoolExtension.MyCoolModule.js" }, "application": { "shopping": { "files": [ "Modules/MyCoolModule/JavaScript/Acme.MyCoolExtension.MyCoolModule.js", "Modules/MyCoolModule/JavaScript/MyCoolModule.Router.js", "Modules/MyCoolModule/JavaScript/MyCoolModule.List.View.js", "Modules/MyCoolModule/JavaScript/MyCoolModule.Edit.View.js", "Modules/MyCoolModule/JavaScript/MyCoolModule.Collection.js", "Modules/MyCoolModule/JavaScript/MyCoolModule.Model.js", "Modules/AdditionalCoolModule/JavaScript/Acme.MyCoolExtension.AdditionalCoolModule.js", "Modules/AdditionalCoolModule/JavaScript/AdditionalCoolModule.Router.js", "Modules/AdditionalCoolModule/JavaScript/AdditionalCoolModule.List.View.js", "Modules/AdditionalCoolModule/JavaScript/AdditionalCoolModule.Edit.View.js", "Modules/AdditionalCoolModule/JavaScript/AdditionalCoolModule.Collection.js", "Modules/AdditionalCoolModule/JavaScript/AdditionalCoolModule.Model.js" ] }, "myaccount": { "files": [ "Modules/MyCoolModule/JavaScript/Acme.MyCoolExtension.MyCoolModule.js", "Modules/MyCoolModule/JavaScript/MyCoolModule.Router.js", "Modules/MyCoolModule/JavaScript/MyCoolModule.List.View.js", "Modules/MyCoolModule/JavaScript/MyCoolModule.Edit.View.js", "Modules/MyCoolModule/JavaScript/MyCoolModule.Collection.js", "Modules/MyCoolModule/JavaScript/MyCoolModule.Model.js", "Modules/AdditionalCoolModule/JavaScript/Acme.MyCoolExtension.AdditionalCoolModule.js", "Modules/AdditionalCoolModule/JavaScript/AdditionalCoolModule.Router.js", "Modules/AdditionalCoolModule/JavaScript/AdditionalCoolModule.List.View.js", "Modules/AdditionalCoolModule/JavaScript/AdditionalCoolModule.Edit.View.js", "Modules/AdditionalCoolModule/JavaScript/AdditionalCoolModule.Collection.js", "Modules/AdditionalCoolModule/JavaScript/AdditionalCoolModule.Model.js" ] }, "checkout": { "files": [ "Modules/MyCoolModule/JavaScript/Acme.MyCoolExtension.MyCoolModule.js", "Modules/MyCoolModule/JavaScript/MyCoolModule.Router.js", "Modules/MyCoolModule/JavaScript/MyCoolModule.List.View.js", "Modules/MyCoolModule/JavaScript/MyCoolModule.Edit.View.js", "Modules/MyCoolModule/JavaScript/MyCoolModule.Collection.js", "Modules/MyCoolModule/JavaScript/MyCoolModule.Model.js", "Modules/AdditionalCoolModule/JavaScript/Acme.MyCoolExtension.AdditionalCoolModule.js", "Modules/AdditionalCoolModule/JavaScript/AdditionalCoolModule.Router.js", "Modules/AdditionalCoolModule/JavaScript/AdditionalCoolModule.List.View.js", "Modules/AdditionalCoolModule/JavaScript/AdditionalCoolModule.Edit.View.js", "Modules/AdditionalCoolModule/JavaScript/AdditionalCoolModule.Collection.js", "Modules/AdditionalCoolModule/JavaScript/AdditionalCoolModule.Model.js" ] } } }, //... Ssp-libraries The ssp-libraries object declares the paths to all SuiteScript files to be loaded when you deploy. //... "ssp-libraries": { "entry_point": "Modules/MyCoolModule/SuiteScript/Acme.MyCoolExtension.MyCoolModule.js", "files": [ SuiteCommerce Site Development 266 Extension Manifest ] } //... 267 "Modules/MyCoolModule/SuiteScript/Acme.MyCoolExtension.MyCoolModule.js", "Modules/MyCoolModule/SuiteScript/MyCoolModule.ServiceController.js", "Modules/MyCoolModule/SuiteScript/MyCoolModule.Model.js", "Modules/AdditionalCoolModule/SuiteScript/Acme.MyCoolExtension.AdditionalCoolModule.js", "Modules/AdditionalCoolModule/SuiteScript/AdditionalCoolModule.ServiceController.js", "Modules/AdditionalCoolModule/SuiteScript/AdditionalCoolModule.Model.js" Suitescript 2 The suitescript2 object declares the paths to SuiteScript 2.0 services to be loaded when you deploy. This object defines an array that can include .js or .ss files. //... "suitescript2": { "files": [ "Modules/MyCoolModule/SuiteScript2/MyCoolModule.Service.ss" ] } //... CCT If your extension is set up to include a CCT, your manifest’s metadata includes specific information regarding your CCT. The cct array declares the specific information required to build a CCT in NetSuite. This includes the following attributes: ■ label (required) – lists the name you gave your CCT. ■ icon – lists the path of the icon to be displayed in SMT for the CCT. ■ settings_record (required) – lists the ID of the custom record you associate with this CCT. ■ registercct_id (required) – lists the Name field of the CMS Content Type Record for your CCT. This is also the value of the id property within the registerCustomContentType() method of your CCT module’s entry point JavaScript file. ■ description – lists the description you gave your CCT. //... "cct": [ { "label": "This is My CCT!", "icon": "img/cct_acme_mycct_icon.svg", "settings_record": "customrecord_cct_acme_mycct", "registercct_id": "cct_acme_mycct", "description": "My cool CCT does magic!" }, { "label": "This is My Second CCT", "icon": "img/cct_acme_mycct2_icon.svg", "settings_record": "customrecord_cct_acme_mycct2", "registercct_id": "cct_acme_mycct2", "description": "My cool CCT does magic!" } ] } SuiteCommerce Site Development Extension Manifest 268 Page If your extension is set up to include a new CMS Page Type, you must manually add a page type definition within your extension’s manifest.json. When an Extension SuiteApp is installed into a NetSuite account, this entry ensures that the CMS Page Type record is created in NetSuite. This is required if creating a new Page Type for use with Site Management Tools (SMT). The page object includes the types array, which introduces each new page type included in the extension. All fields correlate to the CMS Page Type record in NetSuite: ■ name (required) – Sets the name of the Page Type. This becomes the name of the CMS Page Type record. This must match the name attribute when registering your Page Type with PageTypeComponent.registerPageType() in your extension. See the help topic Register Page Types and Templates for SMT for details. This is required. ■ displayName (required) – This string sets the label displayed in SMT for the Page Type when creating a new page. ■ description – (optional) This string sets the description of the Page Type. ■ baseUrlPath (optional) – This string sets the base URL path for all the pages of this page type. For example, if you a have a page type called blog and a base URL path of blog, all blog pages are accessed by mysite.com/blog/[page url]. ■ settingsRecord (optional) – This string sets the ID of any custom record you associate with this page type, inheriting the custom record settings when you add or edit the page type. //... "page": { "types": [ { "name": "blog", "displayName": "Blog", "description": "This is a blog page type", "baseUrlPath": "blog", "settingsRecord": "custrec_page_type_test" }, { "name": "other-page-type", "displayName": "My other page type", "description": "This is another page type", } ] } //... Troubleshoot Activation Errors Applies to: SuiteCommerce | SuiteCommerce Advanced If you experience any errors during activation, you can use the Extension Manager to troubleshoot. If an activation fails, the Status column displays Error (view log) and provides a log to help with your investigation. To troubleshoot errors: 1. In NetSuite, go to Setup > SuiteCommerce Advanced > Extension Manager. SuiteCommerce Site Development Troubleshoot Activation Errors 269 2. Click the view log link next to the error in the Status column to open a popup and display the Activation Log. The Activation Log provides expandable information to help you troubleshoot the error. 3. On the Activation Log popup, do one of the following: a. Click (more) next to Extensions to view a list of the theme and extensions that are part of the failed activation. b. Click (more) next to the failed process to expand the error log and troubleshoot the cause. c. Click (less) to collapse. Commerce Custom Fields Applies to: SuiteCommerce | SuiteCommerce Advanced Commerce websites let you access core and custom field values through the Commerce API, Items API, and SuiteScript. You can add custom fields to your site in two ways: ■ Create Custom Fields Using an Extension – When you install and activate the SuiteCommerce Custom Fields extension, you add a subtab to your SuiteCommerce Configuration record where you specify the custom fields you want to add, the location, and the order in which the fields appear. The SuiteCommerce Custom Fields extension lets you add fields to Checkout and Product Detail Pages of your website. Custom Checkout fields only support the custom transaction body field type. ■ Create Custom Fields by Customizing Templates – Alternatively you can configure your site and customize template files as part of a theme to render information or ask for information stored in these fields on your web store’s Shopping, Checkout, and My Account pages. Note: If you are using SuiteCommerce Advanced Aconcagua or later, you implement custom fields as part of a theme or using an extension. If you are using SuiteCommerce Advanced Kilimanjaro or earlier, you implement custom fields by customizing the core SCA source code. Commerce websites support the following kinds of custom field records: SuiteCommerce Site Development Commerce Custom Fields 270 ■ Custom Item Fields – add custom item field data associated with an item. These fields apply to the Product Details Page (PDP), Checkout, and My Account. ■ Custom Transaction Body Fields – add custom transaction fields to the body of a web store transaction (order as a whole). You can also include some field metadata (such as the field label or item options). These fields apply to Checkout and My Account. ■ Custom Transaction Line Fields – add a custom transaction field to the column of a transaction record (across multiple transaction lines in an order). These fields apply to the PDP, Cart, Checkout, and My Account. ■ Custom Transaction Item Options – add a custom transaction field that applies to a transaction line (one line item within an order). These fields apply to the PDP, Cart, Checkout, and My Account. Note: Site Builder Reference implementations support custom fields appearing in Checkout and My Account only. Create Custom Fields Using an Extension Applies to: SuiteCommerce | SuiteCommerce Advanced The SuiteCommerce Custom Fields extension lets you add custom fields to the Checkout application and Product Detail Pages (PDP) of your website without customizing any source code or themes. Important: Commerce extensions are only available if provisioned, installed, and activated for a selected domain in your account. For more information, see the help topic Commerce Extensions. Note: If you are a SuiteCommerce Advanced customer, you must be implementing the Aconcagua release or later to take advantage of extensions. You can use custom fields to add more information about items in your web store or add and request additional information about the checkout process. Custom fields are grouped together in a separate block, which you can set off by adding a header. This topic includes information on the following custom field types: ■ Custom Fields for Checkout ■ Custom Fields for the PDP Custom Fields for Checkout Applies to: SuiteCommerce | SuiteCommerce Advanced The SC Custom Fields extension lets you add custom transaction body fields to the checkout application in Commerce websites. You can use these fields to request or provide additional information, such as shipping instructions, special order requests, and delivery time slots. SC Custom Fields lets you add text, check box, and date-type transaction body fields to Commerce websites. You can add custom fields before or after existing checkout modules. For example, you can include fields before shipping method, billing address, or payment method blocks in the standard checkout flow. SuiteCommerce Site Development Commerce Custom Fields 271 To display custom transaction body fields in the Checkout application of your site, perform the following steps: 1. Create Custom Fields for Checkout 2. Configure Custom Fields for Checkout Create Custom Fields for Checkout To add new fields to Checkout, you must create custom transaction body fields in your NetSuite account. For more information on how to create custom fields in NetSuite, see the help topic Custom Transaction Body Fields. Note: The SC Custom Fields extension only supports transaction body fields. To implement custom item, custom transaction line, and custom transaction item option fields, see Create Custom Fields by Customizing Templates. The SC Custom Fields extension allows the following transaction body field types: ■ Check Box ■ Date ■ Text Area ■ Long Text ■ Free-Form Text When you create a transaction body field for the SC Custom Fields extension, be aware of the following: ■ The Field Type must match the field type you want to include in the checkout application. ■ The Web Store and Sale fields must be checked in the Applies To subtab. ■ If you select the Mandatory box in the Validation & Defaulting subtab, the field is mandatory for all domains and you must mark it as required in the SuiteCommerce Configuration record for all the domains of your website. If you want the new transaction body field to be required in only one domain, you should mark the field as required in the configuration of that domain only. You do not need to mark it as mandatory during creation. ■ The subtab where you want to display the custom field on the Sales Order record should be selected in the Display subtab. Otherwise, the field is shown in the Custom subtab of the Sales Order record. Note: The character limitation for the custom fields in Commerce websites is set by the field type in NetSuite. For more information on the limits, see the help topic Table of Custom Field Type Descriptions. When you have created your custom transaction body fields, you are ready to Configure Custom Fields for Checkout. Configure Custom Fields for Checkout Use the SC Configuration record to choose which fields to add to Checkout and how they display. You can also set feedback messages that display to users on your site. Consider the following points when determining the order and positioning of your custom fields: SuiteCommerce Site Development Commerce Custom Fields 272 ■ You can add a custom field before or after a standard checkout module. For example, if your SC site uses the standard checkout flow, you can add custom fields before or after the shipping method block in the Shipping Address page. ■ If you want to change the order of existing modules in the checkout application, you should do this before adding new custom fields. For more information, see Reorder Checkout Modules. ■ The order in which you list custom checkout fields in the Custom Fields subtab of the SC Configuration record determines the order of the custom fields in Checkout. Important: Only custom transaction body fields are supported by the SC Custom Fields extension for the Checkout Application. Standard NetSuite transaction body fields cannot be used. To configure Custom Fields for Checkout: 1. In NetSuite, go to Setup > SuiteCommerce Advanced > Configuration. 2. Select the website and domain where the Custom Fields extension is activated and click Configure. 3. Navigate to the Extensions tab. 4. In the Custom Fields subtab, set the following fields: Messaging Fields: Field Description Required Field Warning Message Sets the message to display when the user leaves a required field blank. Required Fields General Warning Sets the message to display at the top of the page when the user leaves a required field blank. Loading Message Sets the message to display when the custom fields are loading. Loading Error Message Sets the message to display when an error occurs while loading. Saving Error Message Sets the message to display when an error occurs while saving. The placeholder [[field]] is replaced by the field name automatically. Checkout Custom Fields: For each custom field you want to include in Checkout, insert a row in the Checkout Custom Fields table, and complete the following fields as needed. Field Description Field ID Links the field ID of the custom field you want to employ with a Checkout field. To find the field ID, go to Customization > Lists, Records & Fields > Transaction Body Fields and open the Transaction Body Field record. Position Determines the position in Checkout where the custom field appears. Module Determines the module in Checkout on which the custom field’s position is based. You can choose from the following Checkout modules: ■ Shipping Address ■ Shipping Method ■ Gift Certificate ■ Payment Method ■ Review Shipping ■ Review Payment ■ Terms and Conditions SuiteCommerce Site Development Commerce Custom Fields Field Description Field Type Determines the type of the custom field. 273 The Field Type must be identical to the Field Type selected in the Transaction Body Field record. Label Sets the label for the custom field to display to users. Placeholder Sets the placeholder text to display in the custom field. Required If checked, makes the custom field required for a user in Checkout. You must check this box if the Mandatory field is checked on the Transaction Body Field record. 5. Click Save. Custom Fields for the PDP Applies to: SuiteCommerce | SuiteCommerce Advanced Using the SC Custom Fields extension, you can choose to display any standard or custom item field on the Product Details Page (PDP) and Quick View window. Additionally, experienced customers can add Schema.org item properties to the fields to improve search engine optimization. Activating the Custom Fields extension adds several native NetSuite fields to the Custom Fields section of the SC Configuration record, which you can use to display additional item details. You can also create your own custom fields to include on the PDP. Standard or custom item fields display on the PDP in the SKU label format. To make native NS or custom fields available for use on the PDP, you must: 1. Update Field Sets 2. Configure Custom Fields for the PDP Update Field Sets The field sets for a website determine the data that is exposed to site templates. To employ custom fields on the PDP, you must add several fields to the details field set for the site. In addition, to display the custom fields on the PDP of a matrix subitem, you must also add the fields to the matrixchilditems field set. For more information on field sets, see the help topic Define Field Sets. These instructions include the fields added automatically with the extension, but you must also add any additional fields you want to display on the PDP. To add custom fields to the Web Site Setup Record: 1. Go to Setup > SuiteCommerce Advanced > Set Up Web Site. 2. Click Edit next to the website to which you are adding custom fields. 3. Navigate to the Field Sets subtab. 4. Add the following fields to the details and matrixchilditems field sets: ■ UPC Code ■ Manufacturer ■ MPN SuiteCommerce Site Development Commerce Custom Fields 274 ■ Manufacturer Country ■ Item Weight To add each field to each field set, perform the following steps: a. Locate the Fields Included in Field Set column and click the Set button. b. Select the fields from the Field Name list and click Add. c. In the Field Set window, click Submit. d. In the Field Set row, click OK. 5. After adding all of the fields to both field sets, click Save. Configure Custom Fields for the PDP Use the SC Configuration record to choose which fields to add to the PDP and Quick View window. You can also associate each field with a schema property to improve search engine optimization. To configure Custom Fields for the PDP: 1. In NetSuite, go to Setup > SuiteCommerce Advanced > Configuration. 2. Select the website and domain where the Custom Fields extension is activated and click Configure. 3. Navigate to the Extensions tab. 4. In the Custom Fields subtab, PDP Fields section, set the following fields for each custom field you want to include on the PDP: Field Description Label and Field ID Links to the label and field ID of the field to include on the PDP. The item field ID is listed as [[fieldid]] to automatically display the value. If an item does not have a value for a field, the field does not display for that item. You can use more than one field within the same line to display the fields in conjunction. For example, if the Label and Field ID field is set to Item Weight: [[weight]] [[weightunit]], the line displays as Item Weight: 7 lb. Basic HTML formatting tags are supported. Enable If checked, displays this field on the PDP and Quick View window. Hide from Quick View If checked, hides this field from the Quick View window. Schema.org Property Links to a schema property tag to improve search engine optimization. If unchecked, this field still appears on the PDP if the Enable field is checked. You can find a list of suggested schema properties and more information at Schema.org. This feature is for experienced users; NetSuite does not verify if the schema property is correct. 5. Click Save. Create Custom Fields by Customizing Templates Applies to: SuiteCommerce | SuiteCommerce Advanced You can configure your site and customize template files as part of a theme to render information or ask for information stored in these fields on your web store’s Shopping, Checkout, and My Account pages. SuiteCommerce Site Development Commerce Custom Fields 275 Important: If you are using SuiteCommerce or the Aconcagua release of SCA or later, you implement custom fields as part of a theme. See Themes for details on creating themes. If you are implementing the Kilimanjaro release of SCA and earlier, you implement custom fields by customizing the core SCA source code. See Customize and Extend Core SuiteCommerce Advanced Modules for details. You can set up custom item, custom transaction body, and custom transaction column and transaction item option fields in SuiteCommerce and SCA by customizing the template files: ■ Set Up Custom Item Fields ■ Set Up Custom Transaction Body Fields ■ Set Up Custom Transaction Line and Transaction Item Option Fields Set Up Custom Item Fields Set up custom item fields to appear in the PDP, Checkout, and My Account. This requires setting up the custom item field in NetSuite and overriding the correct template to render the information in your web store. To set up a custom item field in NetSuite: Note: The custom item field information rendered to your web store is read-only. 1. In NetSuite, create the custom item field. See the help topic Custom Item Fields for details. For a custom item field to render in your Commerce website, observe the following: ■ Enter a Label and ID for your custom item. If you do not specify an ID, NetSuite will create one for you. Use these when adding field sets and customizing templates. ■ Set the Subtype (Applies To subtab) to either Both or Sale. 2. In NetSuite, navigate to Setup > SuiteCommerce Advanced > Set Up Web Site and click edit next to your site. 3. In the Web Site record, click Actions > Rebuild Search Index and wait for the index to build. 4. On the Field Sets tab, perform the following as applicable: ■ If adding the field to the PDP, locate the Details field set name and add the custom field ID to the Fields Included in Field Set column. ■ If adding the field to Checkout or the Purchase History page of My Account, add the field ID to the Order field set name and add the custom field ID to the Fields Included in Field Set column. Note: The order field set is the default for the Review Order page, but you can change this by editing the fieldKeys.itemsFieldsAdvancedName property in the SuiteCommerce Configuration Record. See Backend Subtab for details. To display the custom item field in the PDP or in Checkout: 1. As part of your theme, update the appropriate template: SuiteCommerce Site Development Commerce Custom Fields 276 ■ product_details_full.tpl – exposes the field as read-only information to the PDP. ■ transaction_line_views_cell_navigable.tpl – exposes the field as read-only information to the Review Your Order page and in the Order Summary information displayed throughout Checkout. See Themes for details on creating themes. Note: If you implementing a SuiteCommerce Advanced site using the Kilimanjaro release or earlier, you must override the appropriate template. See Customize and Extend Core SuiteCommerce Advanced Modules for details. 2. Add the following code to any HTML tag within the template that does not have the data-view attribute: {{model.item.custitem_my_custom_field_id}} In this example, custitem_my_custom_field_id is the ID of your custom item field Note: If the custom field record’s Type is set to Multiple Select, the values render on your site separated by commas. 3. Save your code and test on a local server or deploy to NetSuite and activate as required. To display the custom item field in My Account: 1. As part of your theme, update the transaction_line_views_cell_actionable.tpl template. See Themes for details on creating themes. Note: If you implementing a SuiteCommerce Advanced site using the Kilimanjaro release or earlier, you must override the appropriate template. See Customize and Extend Core SuiteCommerce Advanced Modules for details. 2. Add the following code to the template wherever you want the field to appear: {{model.item.custitem_my_custom_field_id}} In this example, custitem_my_custom_field_id is the ID of your custom item field 3. Save your code and test on a local server or deploy to NetSuite and activate as required. Set Up Custom Transaction Body Fields Set up custom transaction body fields to appear in Checkout and My Account. This requires setting up the custom transaction body field in NetSuite and overriding the correct template to render the information in your web store. To set up a custom transaction body field: 1. In NetSuite, set up the custom transaction body field. See the help topic Custom Transaction Body Fields for details. For a custom transaction body field to render in your Commerce website, observe the following: ■ Create a Label and ID for your custom item. If you do not specify an ID, NetSuite will create one for you. Use these when configuring your site and customizing templates. SuiteCommerce Site Development Commerce Custom Fields 277 ■ Check Sale and Web Store (Applies To subtab). ■ SCA supports the Mandatory option in the Validation & Defaulting subtab, but as information only. Transaction body fields are not validated in the frontend (client side). If a custom transaction body field is setup as mandatory, the field will be mandatory for Quotes as well. 2. In NetSuite, go to Setup > SuiteCommerce Advanced > Configuration. 3. In the Advanced tab and Custom Fields subtab, add your transaction body field ID to the Sales Order property. See Custom Fields Subtab for more information on this configuration property. Note: If any transaction body fields where available in the Vinson release of SCA or earlier, you must expose them in the configuration as well. To display the custom transaction body field: 1. You can add a custom transaction body field to any module template linked to a checkout wizard step or in the Purchase History pages of My Account. See Supported Field Types for a list of supported field types. As part of your theme, update the appropriate template: ■ To render information in Checkout, override any applicable checkout wizard template. ■ To render the information in My Account, override the order_history_details.tpl or the order_history_summary.tpl, as required. See Themes for details on creating themes. Note: If you implementing a SuiteCommerce Advanced site using the Kilimanjaro release or earlier, you must override the appropriate template. See Customize and Extend Core SuiteCommerce Advanced Modules for details. 2. In your template, you can include the custom field’s metadata as an option. This is important for rendering the label of a field, for example. The label, type, and mandatory metadata components apply to all supported transaction body field types. The options metadata component applies to List/Record types only. Note: After changing the type, label, or mandatory attributes of a transaction body field, your site uses the metadata values for up two hours. If you configure a new transaction body field, and that field’s attribute is not in the cache, the cache reloads, attempting to get the requested metadata. If the Sales Order Field ID property does not belong to any transaction body field, the application does not render that field. To display metadata for the custom field, include the following helpers (where custbody_my_transaction_body_field is the ID of your custom transaction body field): Note: The metadata is available in the Sales Order object as part of the __customFieldsMetadata attribute. In your template override, access custom field metadata by introducing the following script (where custbody_my_transaction_body_field is the ID of your custom transaction body field). Metadata Fields Information Script Label Display the label of the field model.__customFieldsMetadata.custbody_my_ transaction_body_field.label Type Display the type of the field model.__customFieldsMetadata.custbody_my_ transaction_body_field.type SuiteCommerce Site Development Commerce Custom Fields Metadata Fields Information Script Mandatory Display the Mandatory field. This is model.__customFieldsMetadata.custbody_my_ information only and is not validated in transaction_body_field.mandatory the frontend (client side). Options Display the options for a List/Record field. model.__customFieldsMetadata.custbody_my_ transaction_body_field.options 3. To display the value of a transaction body field, include the following helper (where custbody_my_transaction_body_field is the ID of your custom transaction body field): {{model.options.custbody_my_transaction_body_field}} 4. To request information from a user, include an input, textarea, or select component (where the name property is the custom field ID). Whenever the Change event is triggered on the field, the value of the HTML component is set in the model associated with the template. The following examples use the Label metadata to display the label of the custom TBF: <div> {{model.__customFieldsMetadata.custbody_my_transaction_body_field.label}}: <input type="text" name="custbody_my_transaction_body_field" value="{{model.options.custbody_my_transac tion_body_field}}"> </div> <div> {{model.__customFieldsMetadata.custbody_my_transaction_body_field_sel.label}} <select name="custbody_my_transaction_body_field_sel"> {{#each model.__customFieldsMetadata.custbody_my_transaction_body_field_sel.options}} <option value="{{id}}" {{#ifEquals id ../model.options.custbody_my_transaction_body_field_sel}}select ed="true"{{/ifEquals}}> {{text}} </option> {{/each}} </select> </div> <div> </div> {{model.__customFieldsMetadata.custbody_my_transaction_body_field_2.label}} <textarea name="custbody_my_transaction_body_field_2"> {{model.options.custbody_my_transaction_body_field_2}} </textarea> Supported Field Types Commerce websites support custom transaction body fields of the following Type: Type Example HTML5 Elements Used to Render the Field Check Box text, checkbox Currency text Date text, date Date/Time text, datetime Decimal Number text, number Document select SuiteCommerce Site Development 278 Commerce Custom Fields Type Example HTML5 Elements Used to Render the Field Email Address text, email Free Form Text text Hyperlink url Inline HTML text Integer Number text, number List/Record input, select Long Text text Multiple Select select Password text, password Percent text Phone Number text, tel Rich Text text Text Area text, textarea Time of Day text, time 279 Set Up Custom Transaction Line and Transaction Item Option Fields Set up custom transaction line fields to appear in your PDP, Cart, Checkout, and My Account. This requires setting up the custom fields in NetSuite. Commerce websites include a set of default templates (listed below) to render these fields, but you can override these as required. ■ product_views_option_color.tpl ■ product_views_option_dropdown.tpl ■ product_views_option_radio.tpl ■ product_views_option_text.tpl ■ product_views_option_textarea.tpl ■ product_views_option_email.tpl ■ product_views_option_phone.tpl ■ product_views_option_currency.tpl ■ product_views_option_float.tpl ■ product_views_option_integer.tpl ■ product_views_option_percent.tpl ■ product_views_option_password.tpl ■ product_views_option_url.tpl ■ product_views_option_timeofday.tpl ■ product_views_option_datetimetz.tpl ■ product_views_option_tile.tpl SuiteCommerce Site Development Commerce Custom Fields 280 ■ product_views_option_checkbox.tpl ■ product_views_option_date.tpl Note: Transaction line fields and transaction item options render in the same locations on your site. To set up these fields, follow the same set up and configuration procedures and customize the same template file. To set up a Custom Transaction Line and Transaction Item Option: 1. In NetSuite, set up the transaction line field or transaction item option. See the help topics Custom Transaction Line Fields and Custom Transaction Item Options for details. For a custom transaction line or transaction item option to render in your Commerce website, observe the following: ■ Enter a label and ID for your custom item. If you do not specify an ID, NetSuite will create one for you. Use these when customizing templates to render the field. ■ To enable a custom transaction line field to render in the PDP, check Sale Item and Store Item (Applies To subtab). ■ To enable a custom transaction item option to render in the PDP, check Sale and Web Store (Applies To subtab). ■ SCA supports the Mandatory option in the Validation & Defaulting subtab. Some of these fields are validated in the frontend (client side). Others are validated in the backend. ■ SCA does not support all transaction item option types. ■ All the transaction line fields and item options are displayed automatically if the Show Only Items Listed in: ItemOptions and Custom Transaction Line fields property is unchecked. Enabling this property only displays fields with the ID specified in the item options and custom transaction line field’s Item options and custom transaction line fields property. 2. In NetSuite, navigate to Setup > SuiteCommerce Advanced > Configuration. 3. In the Shopping Catalog tab and Item Options subtab, check the Show Only Items Listed in: Item Options and Custom Transaction Line Fields property and set up your item options fields to display. See Item Options Subtab for more information. Supported Field Types Commerce websites support transaction line fields and transaction item options of the following Type: Note: Some of these fields are validated on the frontend (client side). Others are validated on the backend (NetSuite). Invalid fields in the frontend result in error messages displayed at the field where the error occurred. Invalid fields in the backend result in error messages at the top of the page. Type Validation Example HTML5 Elements Used to Render the Field Check Box Backend checkbox Currency Frontend text Date Backend date, datepicker (Bootstrap) Date/Time Backend text Decimal Number Frontend number SuiteCommerce Site Development Commerce Custom Fields Type Validation Example HTML5 Elements Used to Render the Field Email Address Frontend email Free Form Text Frontend text Hyperlink Frontend url Integer Number Frontend number List/Record Frontend input, select Password Backend password Percent Frontend text Phone Number Frontend tel Text Area Frontend textarea Time of Day Backend text SuiteCommerce Site Development 281 Theme and Extension SuiteApps 282 Theme and Extension SuiteApps Applies to: SuiteCommerce | SuiteCommerce Advanced Commerce websites let you bundle themes and extensions as SuiteApps, making them available for distribution to other NetSuite accounts. Although some steps to bundle a SuiteApp are already documented in the help topics, you need to be aware of some settings and processes specific to bundling Commerce themes and extensions. Before You Begin Before you bundle a Commerce theme or extension, be aware of the following: ■ These procedures assume that you have created or updated a theme or extension, thoroughly tested it on a local server or on a test domain, and that you have deployed the files to a NetSuite account. Refer to the following help topics for more information on building themes and extensions: □ Themes – explains how to create themes. □ Extensions – explains how to create extensions. ■ You must deploy themes and extensions to the NetSuite Account where you are creating the SuiteApp. ■ The SuiteCommerce Extensions Management SuiteApp provides a default installation script. Use this baseline file to create unique installation scripts for each SuiteApp you build. ■ You must designate a version when creating a theme or extension. This allows SuiteApps to be updated over time. The developer tools prompt you for this information when you deploy your files. Theme and extension version numbers should follow this format, where d is a single digit: dd.dd.dd Bundle Themes and Extensions as SuiteApps Applies to: SuiteCommerce | SuiteCommerce Advanced To bundle Commerce themes and extensions, follow these steps: ■ Step 1: Prepare Themes and Extensions for Bundling ■ Step 2: Create a Unique Installation Script for Your Theme or Extension SuiteApp ■ Step 3: Create the SuiteApp for Your Themes or Extensions Step 1: Prepare Themes and Extensions for Bundling The first step is to prepare any folders containing your themes or extensions to enable bundling. To prepare your theme or extension for bundling: 1. In your NetSuite File Cabinet, navigate to the folder containing your theme or extension. This folder is the one containing your theme and extension files, including the manifest.json file. For example: SuiteScript/Deploy_Extensions/<VendorName>/<ThemeOrExtensionName>@<Version>/ SuiteCommerce Site Development Bundle Themes and Extensions as SuiteApps 283 2. Click edit next to the extension folder you are including in the bundle. 3. In the Document Folder record, check the Available for SuiteBundles option. 4. Click Save. 5. Repeat this for every theme and extension you want to include in a SuiteApp. You are now ready to create an installation script. Step 2: Create a Unique Installation Script for Your Theme or Extension SuiteApp Before bundling your themes or extensions as a SuiteApp, you must complete the following steps: 1. Create an installation scrip file. 2. Create an Installation Script record. 3. Deploy your installation script. A bundle installation script is essential to allow SuiteApp installation, update, and uninstallation processes to run properly. The SuiteCommerce Extension Management SuiteApp comes with a default bundle installation script that you can use, titled: ExtensionBundle.js. As a best practice, copy the default file to create a unique script for each SuiteApp you want to build. Important: Never edit the default ExtensionBundle.js file directly. As a best practice, create a unique installation script file for each theme or extension SuiteApp you want to build, even if you do not include any customizations. Store your installation scripts in a location associated with your theme and extension files. This default script includes the necessary functions to install, update, or uninstall the SuiteApp and its contents. This includes the following trigger functions: ■ beforeInstall ■ afterInstall ■ afterUpdate ■ beforeUninstall Note: You only need one installation script per SuiteApp. The script applies to any included themes and extensions. To create an installation script file: 1. In the NetSuite File Cabinet, browse to SuiteBundles/Bundle xxxxxx, where xxxxxx equals the Bundle ID of the SuiteCommerce Extension Management SuiteApp. See Install Your SuiteCommerce Application for the latest Bundle ID of the SuiteCommerce Extension Management SuiteApp. 2. Make a copy of the default ExtensionBundle.js file: a. Click Copy Files. b. Expand the Filters area. c. In the Copy To list, select a location in the File Cabinet to store your copy. d. Check the box next to ExtensionBundle.js. SuiteCommerce Site Development Bundle Themes and Extensions as SuiteApps e. Click Copy. f. Rename your new file as needed. (Optional) 284 To rename a file, navigate to its location and edit the file record. 3. Edit your new installation script file to meet your needs (optional). The default script can handle most requirements. However, if you have custom needs or want to make special validations or operations in NetSuite records, you can edit the script to meet your needs. For specific information and instructions regarding installation script files, see the help topic SuiteScript 2.0 Bundle Installation Script Type. Important: If you need to edit ExtensionBundle.js, maintain the validations and operations that came with default file. Note: The ExtensionBundle.js file that comes with the 18.2 release of the SuiteCommerce Extension Management SuiteApp support updates. However, if you previously created an extension as a SuiteApp prior to the 18.2 release, we recommend recreating the SuiteApp with the latest update to take advantage of the version management functionality. This includes creating a new installation script with SuiteScript 2.0. To create an Installation Script record: 1. Go to Customization > Scripting > Scripts > New. 2. In the Script File field, click List. 3. In the -All- list, scroll to select the location of your installation script (this is your copy of ExtensionBundle.js). 4. Select your installation script from the list. 5. Click Create Script Record. 6. From the Select Script Type list, select Bundle Installation. 7. In the new Script record, name your bundle and provide a description (optional). 8. In the Scripts tab, confirm that the following script fields populated correctly. ■ Before Install Function: beforeInstall ■ After Install Function: afterInstall ■ After Update Function: afterUpdate ■ Before Uninstall Function: beforeUninstall 9. Click Save. To deploy your installation script: 1. Create a Script Deployment. See the help topic Steps for Defining a Script Deployment. 2. Name your script and provide an ID, beginning with underscore (_). 3. Set the Status field to Released. Important: Failure to set this field to Released results in a failed installation. 4. Choose the Log Level to meet your needs. 5. When you have finished, click Save. You are now ready to create your SuiteApp. SuiteCommerce Site Development Bundle Themes and Extensions as SuiteApps 285 Step 3: Create the SuiteApp for Your Themes or Extensions After you have successfully created and deployed your installation script, you are ready to build your SuiteApp. Follow the instructions detailed in Creating a Bundle with the Bundle Builder. Observe the following information when building a SuiteApp for Commerce themes and extensions: ■ When choosing the installation script, select the script you created earlier. ■ You cannot use the same Installation Script record across multiple SuiteApps when bundling Commerce themes or extensions. You must select a unique Installation Script record for each SuiteApp. ■ When prompted to select objects for the SuiteApp, browse to File Cabinet/Folders and choose the objects associated with each theme or extension you are including in your SuiteApp. Look for the objects that match your deployed themes and extensions. ■ You can create theme and extension SuiteApps as managed or unmanaged bundles. ■ You can bundle any number of themes and extensions within one SuiteApp. Declare Target Versions Applies to: SuiteCommerce | SuiteCommerce Advanced When you run the theme or extension developer tools, you specify the Commerce product for which your theme or extension applies. However, you must also specify which releases of those products are compatible with your theme or extension. You do this by declaring a target version. Target versions are required when creating themes or extensions for the following Commerce products: ■ Commerce Web Stores– Includes SuiteCommerce (SC) and SuiteCommerce Advanced (SCA). The theme and extension developer tools both refer to this combination as SuiteCommerce Online. ■ SuiteCommerce InStore (SCIS) (Extensions only) Target versions prevent site managers from activating or updating incompatible themes and extensions on their site because the Extension Manager: ■ Only lists themes and extensions that are compatible with the declared target version of the associated Commerce product. ■ Excludes incompatible updates to active themes and extensions. To declare a target version: 1. Access the theme or extension developer tools, depending on what you are creating. For details, see Theme Developer Tools and Extension Developer Tools. 2. Follow the on-screen prompts. The developer tools prompt you for a target version when using the following commands: ■ gulp theme:deploy ■ gulp extension:create ■ gulp extension:deploy 3. When prompted to enter a target version, enter a string to declare compatible versions. This string requires a three-part version number scheme, as described in How Releases and Patches Work. The developer tools prompt you for a target version for each product specified earlier. SuiteCommerce Site Development Declare Target Versions 286 Leaving these prompts blank results in compatibility with all versions of the associated Commerce products. You can set the range of compatible versions using standard SEMVER range specifiers, such as the tilde (~), greater-than and equal (>=), and carat (^). Note: For more information on SEMVER schema, see https://semver.org/. 4. Leave this prompt empty to specify that the theme or extension is available for all versions of the associated Commerce product. This applies for legacy and new themes and extensions, where the target version was not provided. The following table highlights a few useful examples. Prefix String Example Description Compatibility Examples None None Leaving the target version prompt blank results in compatibility with all versions of the associated product. All releases None 19.1.0 Listing the version with no symbol prefix results in compatibility with the specified release only. 2019.1.0 >= >=19.1.0 Greater Than and Equal 2019.1.0 This prefix results in compatibility with the specified release and all future releases. 2019.1.1 2019.2.0 2020.1.0 ^ ~ ^19.1.0 ~19.1.0 Caret 2019.1.0 This prefix results in compatibility with the specified SC/ SCA/SCIS release and all future releases within a given year, both major and minor. 2019.1.1 Tilde 2019.1.0 This prefix results in compatibility with the specified major release including all future minor releases. 2019.1.1 2019.2.0 Update Themes and Extensions Applies to: SuiteCommerce | SuiteCommerce Advanced This topic explains how to update Commerce themes and extensions that are part of a SuiteApp. Before You Begin Before releasing an updated Commerce theme or extension, be aware of the following best practices: ■ Business users can choose whether or not to activate an updated theme or extension. Therefore, always develop your theme and extension updates to be backwards compatible with previous versions. For example: NetSuite records are maintained within a NetSuite account. If your extension update requires altering a custom record, you could break backwards compatibility with previous versions of the extension. SuiteCommerce Site Development Update Themes and Extensions 287 ■ Always test theme and extension functionality and backwards compatibility on a development or sandbox account before releasing the bundle. ■ If you bundled a theme or extension prior to the 18.2 release of the SuiteCommerce Extensions Management SuiteApp, we recommend rebuilding the installation script using SuiteScript 2.0 the next time you update a theme or extension included in the bundle. ■ You must increment the version of at least one theme or extension when updating a SuiteApp. If the SuiteApp does not include a theme or extension with a later version, the update fails. ■ The SuiteApp version has no programmatic connection with the versioning system of themes and extensions. ■ If your theme or extension update requires customizing the installation script, you can edit the existing script. You do not need to build a new script. ■ These procedures only apply to themes and extensions that are being released as part of a bundled SuiteApp. Updates to custom themes or extensions (as developed by internal site developers) are made using the developer tools. Update Themes and Extensions Within a SuiteApp To update a theme or extension that is part of a SuiteApp: 1. Update your theme or extension as required. See Customization for more information. 2. Deploy your updated theme or extension to the NetSuite account used to create the original SuiteApp. Increment each version using a Major.Minor.Patch numbering scheme. Theme and extension version numbers should follow this format, where d is a single digit: dd.dd.dd. Failure to use this format results in failed SuiteApp updates. 3. Confirm that the manifest.json file associated with the updated theme or extension reflects the correct version. a. In NetSuite, navigate to the location where you deployed your theme or extension update. For example: SuiteScript/Deploy_Extensions/<VendorName>/<ThemeOrExtensionName>@<Version>/ b. Open the associated manifest.json file and confirm the version. The manifest.json file should reflect the latest version in SemVer notation. For example, if you deployed an update to MyCoolExtension 1.0.0 to version 2.0.0, your manifest.json file should look similar to the following example: { "fantasyName": "My Cool Extension!", "name": "MyCoolExtension", "vendor": "Acme", "type": "extension", "target": "SuiteCommerce", "version": "2.0.0", "description": "This is my cool update!", //... c. If the manifest does not reflect the correct version, redploy or edit the manifest file in your file cabinet. 4. If your theme or extension update requires changes to the installation script, edit the installation script as needed. See the help topic SuiteScript 2.0 Bundle Installation Script Type for details. SuiteCommerce Site Development Update Themes and Extensions 5. Edit the SuiteApp using SuiteBundler in NetSuite. See the help topic Creating a Bundle with the Bundle Builder for details. SuiteCommerce Site Development 288 Core SCA Source Code 289 Core SCA Source Code Applies to: SuiteCommerce Advanced If you are customizing Javascript, SuiteScript or Configuration objects that are not available using the Extensibility API, you need the to use the core SCA developer tools and customization procedures described in this section. More specifically, you must read and understand this section if: ■ You are customizing a site that implements the Kilimanjaro release of SCA or earlier. ■ You are customizing a site that implements the Aconcagua release of SCA or later and need to access JavaScript, SuiteScript, or configuration objects that are not available using the Extensibility API. See the help topic Extensibility Component Classes for a list of components exposed using the Extensibility API. Important: If you are implementing the Aconcagua Release of SCA or later, the best practice is to use themes and extensions to customize your site. To customize HTML or Sass files for these implementations, you must use the theme developer tools. See Theme Developer Tools and Extension Developer Tools for details on using these tools. Core SuiteCommerce Advanced Developer Tools Applies to: SuiteCommerce Advanced This section outlines the process for using the core SuiteCommerce Advanced (SCA) developer tools. Follow the procedures outlined in this section if: ■ You are developing an SCA site using the Kilimanjaro release or earlier. ■ You are developing an SCA site using the Aconcagua release or later and you are not using extensions to interact with the Extensibility API. Important: If you are implementing the Aconcagua Release of SCA or later, the best practice is to use themes and extensions to customize your site. However, if your customizations require access to objects not available using the Extensibility API, use the procedures outlined in this section to extend code using custom modules. These tools can be run in parallel with the theme and extension developer tools. The core SCA developer tools let you customize the application from your local development environment, then deploy your customized application to NetSuite or a local environment for testing. You can also create new features that extend the functionality of existing modules or create your own custom features in SuiteCommerce Advanced. The SCA developer tools are based on open-source software and are integrated within your existing development environment. These tools enable you to do the following: ■ Store code locally within a version control system. ■ Create and edit code locally in your preferred text editor or IDE. ■ Compile the application locally. ■ Deploy the application to NetSuite or a local server environment for testing. You can also deploy directly to your production or sandbox accounts in NetSuite. SuiteCommerce Site Development Core SuiteCommerce Advanced Developer Tools 290 This section assumes that the SCA SuiteApp is installed into your account and that you have already followed the instructions to download and set up Node.js and Gulp.js. If you have not already done so, perform the steps outlined in the following topics: Note: SuiteApp installation is generally performed by your system or NetSuite administrator. This process installs all of the required application files in NetSuite. It also installs a downloadable zip file containing the source code for SCA. After the applicable SuiteApp is installed, the source files are available in the file cabinet. You can download this zip file to your local environment. ■ Install Node.js ■ Install Gulp.js Note: See The Build Process for more information about how Gulp.js performs these tasks. Permissions To use Gulp.js to deploy source files to NetSuite, you must use either the System Administrator role, the Store Manager role, or a custom role with the following permissions set to Full: ■ Documents and Files ■ Website (External) publisher ■ Web Services Set Up Your Development Environment Applies to: SuiteCommerce Advanced View a Related Video To set up your development environment you must install Gulp.js and download the SuiteCommerce Advance source files from NetSuite. You must also install Node.js which is a JavaScript development platform required by Gulp.js. Download the Source Files Applies to: SuiteCommerce Advanced After installing Node.js and Gulp.js, you have completed the basic installation requirements for the developer tools. To begin locally editing and customizing SuiteCommerce Advanced, you must first download the source files from the NetSuite file cabinet. Note: The following information and steps are valid for SuiteCommerce Advanced release 2019.1 and later. If you have SuiteCommerce Advanced release 2018.2 or earlier installed, refer to Download Source Files for Release 2018.2 and Earlier for instructions specific to your release. Your File Cabinet includes the following implementations: ■ Source – This implementation contains all of the original installation files. It is locked to prevent changes. The Source implementation can be used for creating diffs against your customizations to troubleshoot issues. ■ Development – The Development implementation is where you begin your work. SuiteCommerce Site Development Core SuiteCommerce Advanced Developer Tools 291 In the _Sources directory of the Development implementation, there is a zipped source file available. Download this file to your local development environment to begin working on your customizations and to create distribution files. When you install the SuiteCommerce Advanced SuiteApp, appropriate default touch points are automatically deployed to this implementation. After deployment to a website, your site is available at the domain defined for that site. Refer to Deploy to NetSuite for details. ■ Source2 – This implementation contains the original installation files for the SCA source modules that have been migrated to SuiteScript 2.0. For more information, see Commerce Migration to SuiteScript 2.0. ■ Development2 – The Development2 implementation is where touch points for customizations to SuiteScript 2.0 modules are automatically deployed. For more information, see Commerce Migration to SuiteScript 2.0. Important: With the Aconcagua release of SuiteCommerce Advanced, these implementations no longer contain HTML and Sass files. To customize the look and feel of your site, you must use the theme developer tools. See Theme Developer Tools for details. These tools can be used simultaneously with the SCA developer tools. To download the SuiteCommerce Advanced source files: 1. Login to your NetSuite account where SuiteCommerce Advanced is installed. 2. Access the File Cabinet at Documents > Files > File Cabinet. 3. In the File Cabinet, go to Web Site Hosting Files > Live Hosting Files > SSP Applications > [SSP Application] > Development > _Sources. The SSP Application for SCA is named: NetSuite Inc. - SCA <release_name>. 4. Click the name of the .zip file to download it. 5. Extract the .zip file to the directory where you want to store your source files. Rename the top-level directory or accept the default name. However, do not change the names of subfolders, files, or their structure within this directory. 6. To complete your development environment set up, follow the procedure in Install Additional Files in the Source Directory. After completing these steps, you can begin editing or customizing SuiteCommerce Advanced. If necessary, you can add these files to a version control system. Note the following: ■ The source files for SuiteCommerce Advanced 2019.1 and earlier are JavaScript files with .js filename extensions. The source files for SuiteCommerce Advanced 2019.2 and later are TypeScript files with .ts filename extensions. For more information about TypeScript, see TypeScript. ■ Generally, you only need to download the source files the first time you set up your local development environment. You may also need to download the source files to ensure you have the correct base version or the most recent version after a bundle update. Download Source Files for Release 2018.2 and Earlier The following information and steps are valid for SuiteCommerce Advanced release 2018.2 and earlier. Your File Cabinet includes the following implementations: ■ Source – This implementation contains all of the original installation files. It is locked to prevent changes. In the _Sources directory of the Source implementation, there is a zipped source file available. Download this file to your local development environment to begin working on your customizations and to create distribution files. The Source implementation can also be used in the future for creating diffs against your customizations to troubleshoot issues. SuiteCommerce Site Development Core SuiteCommerce Advanced Developer Tools 292 ■ Development – The Development implementation is where you deploy your customizations. When you install the SuiteCommerce Advanced SuiteApp, appropriate default touch points are automatically deployed to this implementation. Refer to Deploy to NetSuite for details. Important: With the Aconcagua release of SuiteCommerce Advanced, these implementations no longer contain HTML and Sass files. To customize the look and feel of your site, you must use the theme developer tools. See Theme Developer Tools for details. These tools can be used simultaneously with the SCA developer tools. To download the source files for release 2018.2 and earlier: 1. Login to your NetSuite account where SuiteCommerce Advanced is installed. 2. Access the File Cabinet at Documents > Files > File Cabinet. 3. In the File Cabinet, go to Web Site Hosting Files > Live Hosting Files > SSP Applications > [SSP Application] > Source > _Sources. The SSP Application for SCA is named: NetSuite Inc. - SCA <release_name>. 4. Click the name of the .zip file to download it. 5. Extract the .zip file to the directory where you want to store your source files. Rename the top-level directory or accept the default name. However, do not change the names of subfolders, files, or their structure within this directory. 6. Install additional files to complete your development environment set up as described in Install Additional Files in the Source Directory. After completing these steps, you can begin editing or customizing SuiteCommerce Advanced. If necessary, you can add these files to a version control system. Install Additional Files in the Source Directory Applies to: SuiteCommerce Advanced After downloading and extracting the SuiteCommerce Advanced source directory, complete the following steps to finish installing the developer tools. Note: You must run all commands in the SuiteCommerce Advanced directory where the package.json file is located. ■ If implementing the 2020.1 release or later, this directory is the SC_xxx directory within your root source directory. For example: SC_20.1 ■ If implementing the 2019.2 release, this directory is the *_Live directory within your root source directory. For example: SC_19.2_Live ■ If implementing the 2019.1 release or earlier, this directory is the top-level root directory. For example: SuiteCommerce Advanced <release_name> To install additional required files: 1. Open a command line or terminal window. SuiteCommerce Site Development Core SuiteCommerce Advanced Developer Tools 293 2. Access the SuiteCommerce Advanced source directory that contains the package.json file. 3. Install additional Node.js packages using the following command: npm install This command may take several minutes to install the dependencies required by the developer tools. 4. Run Gulp.js using the following command: gulp Running Gulp.js creates the local distribution directory and compiles SCA source modules into a deployable application. Note the following: ■ If you encounter Sass Compilation Errors when running Gulp.js, you need to manually correct the compilation errors. For more information, see Troubleshooting the Developer Tools. ■ The first time you run the gulp command, the developer tools create a local distribution folder that contains the combined SuiteCommerce Advanced application. After the command completes successfully, you see the new folder at the following location: □ If implementing the 2020.1 release or later, the LocalDistributionAdvanced folder is created in the SC_xxx directory within your root source directory. For example: SC_20.1/ LocalDistributionAdvanced □ If implementing the 2019.2 release, the LocalDistributionAdvanced folder is created in the *_Live directory. For example: SC_19.2_Live/LocalDistributionAdvanced □ If implementing the 2019.1 release or earlier, the LocalDistribution folder is created at the top level of the SuiteCommerce Advanced source directory. For example: SuiteCommerce Advanced <release_name>/LocalDistribution ■ Each time you download a new version of the SuiteCommerce Advanced source files, you must perform this procedure in each new source directory. ■ If you have multiple copies of the SuiteCommerce Advanced source directory in your development or test environment, you must run this procedure in each of those directories. ■ If you notice any NPM Vulnerabilities related to an NPM Audit, these vulnerabilities will not impact output source code in the SCA Application. Set Up SCA 2019.1 for Theme and Extension Developer Tools Applies to: SuiteCommerce Advanced This topic applies to developers implementing the 2019.1 release of SuiteCommerce Advanced who have not been updated to the 2019.1 release of the SuiteCommerce Extensions Management bundle. Until such time that your account is updated to the 2019.1 release of the SuiteCommerce Extensions Management bundle, you must use the developer tools provided with the 2018.2.1 release to create themes and extensions for the 2019.1 release of SuiteCommerce Advanced. Before doing so, however, you must customize your developer environment as described in this section. The customization you create depends on the developer tools you intend to use (theme or extension developer tools). This customization alters the whoService() method in the gulp/tasks/local.js file. The whoService() method returns information used by the application’s local.ssp file to know the resources and location that must be loaded. You must edit the url for the css, templates, and js_extensions objects to use the correct tools. The URL you specify depends on the tools you intend to use. Refer to the following table for port designations based on the developer tools you intend to use: SuiteCommerce Site Development Core SuiteCommerce Advanced Developer Tools 2018.2.1 Developer Tools Local Host Port Theme Developer Tools 7778 Extension Developer Tools 7779 294 To customize your developer environment for SCA 2019.1: 1. If you have not yet done so, complete set up of your SCA developer environment. See Download the Source Files and Install Additional Files in the Source Directory for details. 2. Access your root source directory and open the following file: gulp/tasks/local.js 3. Customize the css object: a. Locate the following lines within the whoServices() method: var css = { tag: 'link' , resource: 'css' , url: `${protocol}://${host}/css/${app}.css` } b. Replace , url: `${protocol}://${host}/css/${app}.css` with the following. In the following code, replace [PORT] with the local host port for the tools you intend to use. , url: `http://localhost:[PORT]/tmp/css/${app}.css` For example, to use the theme developer tools, your code should look like this: var css = { tag: 'link' , resource: 'css' , url: `http://localhost:7778/tmp/css/${app}.css` } 4. Customize the template object: a. Locate the following lines within the whoServices() method: , b. templates = { tag: 'script' , resource: 'templates' , url: null } Replace , url: null with the following. In the following code, replace [PORT] with the local host port for the tools you intend to use. , url: `http://localhost:[PORT]/tmp/${app}-templates.js` 5. If you are using the extension developer tools, customize the js_extensions object: a. Locate the following lines within the whoServices() method: , js_extensions = { tag: 'script' , resource: 'js_extensions' , url: null }; SuiteCommerce Site Development Core SuiteCommerce Advanced Developer Tools b. 295 Replace , url: null with the following. , url: 'http://localhost:7779/tmp/extensions/${app}_ext.js' Note: If you are using the theme developer tools, keep the url property set to null. 6. Find the following lines: var response; if(process.is_SCA_devTools) { css.url = null; } response = [ css , require_patch , requirejs , templates , js_core , js_extensions ]; 7. Comment out the following line: css.url = null; Your resulting code should look like this snippet: var response; if(process.is_SCA_devTools) { //css.url = null; } response = [ css , require_patch , requirejs , templates , js_core , js_extensions ]; 8. Save the file. You should now be able to use the 2018.2.1 theme and extension developer tools to create themes and extensions on your SCA site. SCA on a Local Server Applies to: SuiteCommerce Advanced In addition to deploying to NetSuite, you can also run SuiteCommerce Advanced on a local server to quickly test changes you make to the application. The local server is installed as part of the Node.js installation and uses the Express web framework. When you enter the gulp local command, the server starts automatically. When the server starts, Gulp.js initializes watch tasks that listen for changes to files in the JavaScript, Templates, or Sass directories. When you save changes to a file, gulp automatically recompiles the source SuiteCommerce Site Development Core SuiteCommerce Advanced Developer Tools 296 files and updates the local distribution directory. Gulp also outputs a message to the console when an update occurs. The local server is primarily used to test frontend changes. When accessing the SuiteCommerce Advanced application on the local server, backend services used by the application are run on NetSuite. Therefore, any local changes you make to services or backend models must be deployed to NetSuite before they are accessible to the local server. Also, you must deploy any changes to services or backend models to NetSuite in order for them to work on the local server. Note: If you modify the distro.json file to add additional files or modules, you must restart your local server to see changes. To deploy to the local server: 1. Go to your command line or terminal window. 2. Access the SuiteCommerce Advanced source directory containing the package.json file. ■ If implementing the 2020.1 release or later, this directory is the SC_xxx directory within your root source directory. For example: SC_20.1 ■ If implementing 2019.2, this directory is the *_Live directory within your root source directory. For example: SC_19.2_Live/. ■ If implementing 2019.1 or earlier, this directory is the top-level root directory. 3. Enter the following command: gulp local Note: If this is the first time you are running gulp local in this directory, this command creates a local distribution directory. 4. Navigate to the local version of the application using one of the following URLs: ■ Shopping: http://<DOMAIN_NAME>/c.<ACCOUNT_ID>/<SSP_APPLICATION>/shopping-local.ssp ■ My Account: http://<DOMAIN_NAME>/c.<ACCOUNT_ID>/SSP_APPLICATION/my_account-local.ssp ■ Checkout: http://<DOMAIN_NAME>/c.<ACCOUNT_ID>/SSP_APPLICATION/checkout-local.ssp In the above URL patterns, you must replace the following variables with values for your specific environment: ■ DOMAIN_NAME — replace this value with the domain name configured for your NetSuite website record. ■ ACCOUNT_ID — replace this value with your NetSuite account ID. ■ SSP_APPLICATION — replace this value with the URL root that you are accessing. The URLs you use should be similar to the following examples: http://www.mysite.com/c.123456/my-sca-ssp/shopping-local.ssp http://www.mysite.com/c.123456/my-sca-ssp/my_account-local.ssp http://www.mysite.com/c.123456/my-sca-ssp/checkout-local.ssp Note: When accessing the secure checkout domain using HTTPS on the local server, you must use a different URL. See Secure HTTP (HTTPS) with the Local Server for more information. When the local server is running, Gulp.js automatically compiles the application when you save any changes. You can refresh your browser to see the changes. SuiteCommerce Site Development Core SuiteCommerce Advanced Developer Tools 297 Deploy to NetSuite Applies to: SuiteCommerce Advanced After installing and configuring Node.js and Gulp.js in your local developer environment as described in the section Developer Environment, you must configure your environment to connect with and deploy to a NetSuite SSP Application. To configure deployment to NetSuite, you must perform the following: ■ Deploy Local Source Files to an SSP Application in NetSuite ■ Deploy the SSP Application to Your Site Deploy Local Source Files to an SSP Application in NetSuite SuiteCommerce Advanced enables you to deploy directly to an SSP application in NetSuite. When the SuiteCommerce Advanced bundle is installed in your NetSuite account, the following SuiteCommerce Advanced distributions are created in Web Site Hosting Files > Live Hosting Files > SSP Applications > NetSuite Inc. - SCA <version>: ■ Source – This folder includes all of the original SSP applications and supporting files and the sources.zip file to be downloaded and used for local development. All files in this distribution are locked. Do not deploy customizations to this folder. ■ Development – This folder maintains your customizations after you deploy. When the developer tools prompt you for a location to deploy your code, choose this folder from the list of options. Use Gulp.js commands to deploy the files generated earlier in the local distribution folder. Note: When working with static assets, such as static images, videos PDFs, etc. (not related to the source code), we recommend uploading these files to the filecabinet, stored in a dedicated folder. In general, deployed folders cannot contain more than 100 direct child files. To deploy local source files to a NetSuite SSP application: 1. Go to your command line or terminal window. 2. Access the SuiteCommerce Advanced source directory containing the package.json file. ■ If implementing the 2020.1 release or later, this directory is the SC_xxx directory within your root source directory. For example: SC_20.1 ■ If implementing 2019.2, this directory is the *_Live directory within your root source directory. For example: SC_19.2_Live/. ■ If implementing 2019.1 or earlier, this directory is the top-level root directory. 3. Enter the following command: gulp deploy Note: If this is the first time you are running gulp deploy in this directory, this command creates one or more deploy distribution directories depending on your implementation. 4. When prompted, enter your NetSuite email and password. Note: The developer tools do not support emails or passwords containing special characters such as + and %. 5. When prompted, select the NetSuite account where SuiteCommerce Advanced is installed. SuiteCommerce Site Development Core SuiteCommerce Advanced Developer Tools 298 Important: You must log in using the SCDeployer role to access your NetSuite account. Failure to use this role may result in an error. See Developer Tools Roles and Permissions for instructions on setting up this role. 6. When prompted to choose your Hosting Files folder, select the Live Hosting Files option. 7. When prompted to choose your Application Publisher, select the NetSuite Inc. - SCA <version> option. 8. When prompted to choose your SSP Application, select the Development option. After entering your connection settings, the contents of the deploy distribution folders on your local system are uploaded to the NetSuite file cabinet. This process may take a few minutes. Wait for the process to complete before proceeding. Note: The first time you run the gulp deploy command, the connection settings are stored in the .nsdeploy file in the SC_xxx directory within your root source directory (for example: SC_20.1/). During subsequent deployments only the login credentials are required. If you need to change the SSP application you are deploying to, you can manually edit the .nsdeploy file with the updated information. For details, see Changing Your Connection Information. Also, during the initial deployment to NetSuite, the Gulp.js commands create a manifest file within the NetSuite file cabinet. This file contains the list of files uploaded and a hash of its content. On subsequent deployments, the Gulp.js commands use the manifest file to determine new or changed files. Only those files are updated during deployment to the NetSuite file cabinet. For more information on the structure of the SCA source directory, see The SuiteCommerce Advanced Source Directory. Deploy the SSP Application to Your Site After installing the SuiteCommerce Advanced SuiteApp, the Development SSP application is automatically configured with all of the required scripts and appropriate touch points. You must deploy the SSP application to the web site configured within NetSuite. To deploy the Development SSP application to your site: 1. Go to Setup > SuiteCommerce Advanced > SSP Applications and then click View next to the SuiteCommerce Advanced - Dev <version> application. 2. In the Site field, select the site you want to deploy this application to. Note: Only sites already set up are available for selection. If you have not set up a web site record go to Setup > SuiteCommerce Advanced > Web Site Set Up > New. For detailed instructions, see . 3. Click Save. After the SSP application has been deployed to your site you can view the site by navigating to the domain defined for that site. Gulp Command Reference for SCA Developer Tools Applies to: SuiteCommerce Advanced You must run gulp commands at the level of the folder containing the package.json file. SuiteCommerce Site Development Core SuiteCommerce Advanced Developer Tools 299 The following table lists the most commonly used gulp commands: Command gulp gulp deploy Description Creates the local distribution directory if it does not exist. This command also compiles the source modules into a deployable application. Compiles the application and deploys it to NetSuite. As part of the compilation process, gulp deploy minimizes the application by removing all white space. This command also creates one or more deploy distribution directories, depending on your implementation, if they do not exist. See Contents of the Deploy and Local Distribution Directories for information on the output of this command. In addition to compiling the application, this command creates the .nsdeploy file if it does not exist. gulp deploy --no-backup gulp deploy --nouglify gulp deploy --source <source_type> If you are using 2019.2 release of SCA or later, running gulp deploy also compiles all project TypeScript files to JavaScript. TypeScript files have a .ts filename extension. Compiles and deploys the application, but does not upload a backup of the source files. Compiles and deploys the application like gulp deploy, but does not compress the source files. This command is useful for debugging because it produces output files that are easier to read. Compiles and deploys only the type of source files specified. Possible options are: ■ javascript ■ ssp-libraries ■ ssp-files gulp deploy --to gulp jshint gulp local SuiteCommerce Site Development ■ services Enables you to deploy to a different NetSuite account by overriding the settings defined in the .nsdeploy file. Runs the JSHint utility on the SuiteCommerce Advanced source files. This utility verifies and validates JavaScript files to help detect possible errors. Compiles the Sass and template files into a functional application, but does not compile the JavaScript files of the application. After compilation, this command starts a local server. This server watches for changes to the SuiteCommerce Advanced source files. After the server starts, any changes you make to a JavaScript file are automatically recompiled and visible in the browser. The server also watches for changes to the Sass and template files. Core SuiteCommerce Advanced Developer Tools 300 If you are using the 2019.2 release of SCA or later, running gulp local also compiles all project TypeScript files to JavaScript. TypeScript files have a .ts filename extension. See SCA on a Local Server for more information. gulp clean gulp configuration gulp copy gulp javascript gulp javascript --nouglify gulp ssp-files gulp ssp-libraries This command outputs files to the local distribution directory. See Contents of the Deploy and Local Distribution Directories for information on the output of this command. Removes the deploy and local distribution directories and the .nsdeploy file. Compiles the configuration properties of each source module to generate the configurationManifest.json file in your local distribution folder. Configuration properties for source modules are declared using the configuration property in a module’s ns.package.json file. Copies any files declared using the copy property in a source module’s ns.package.json file. For example, if a source module requires specific static files be available in the NetSuite File Cabinet, you can use the copy property in the ns.package.json file to declare the folder that contains those files. This ensures the contents of the declared folder are copied to the output with the internal folder structure maintained. Compiles the project’s JavaScript output. The JavaScript files compiled are the ones specified using the javascript property in each source module’s ns.package.json file. This command compiles the JavaScript output so that it is suitable for production. Compiles the project’s JavaScript output like gulp javascript, but does not compress the source files. This command is useful for debugging because it produces output files that are easier to read. Compiles and copies the .ssp files declared using the ssp-files property in each source module’s ns.package.json file. (Handlebar syntax can be used in the .ssp files.) Compiles the JavaScript files declared using the ssp-libraries property in each backend module’s ns.package.json file. The ssp-libraries section of the distro.json file includes a reference to a list of all backend modules. SuiteCommerce Site Development Core SuiteCommerce Advanced Developer Tools 301 The Build Process Applies to: SuiteCommerce Advanced To understand how the developer tools work and why they are necessary, it is important to understand how the SuiteCommerce Advanced source files are organized and how the application is compiled. For details on the SCA source directory structure, see The SuiteCommerce Advanced Source Directory. The distro.json and ns.package.json Files Applies to: SuiteCommerce Advanced To determine which files to include with the Distribution folder of SuiteCommerce Advanced, Gulp.js uses two types of configuration files. These files are: ■ distro.json ■ ns.package.json The distro.json file exists in the following location depending on your implementation: ■ If implementing the 2020.1 release and later, this file is located within the SC_xxx/Advanced directory within your root source directory. For example: SC_20.1/Advanced ■ If implementing 2019.2, this file is located within the *_Live/Advanced/ directory within your root source directory. For example: SC_19.2_Live/Advanced/ ■ If implementing 2019.1 and earlier, this file is located within the top level of the SCA directory. The distro.json file defines which modules are included within SuiteCommerce Advanced. It also specifies additional configuration information. Gulp.js parses this file to determine which files within the Modules directory to combine or copy into the Distribution folder. The distro.json file contains the following parameters: ■ name: specifies the name of the application. By default this value is SuiteCommerce Advanced <version>. ■ version: specifies the application version. ■ modules: lists the modules SuiteCommerce Advanced uses. Each module is listed on a separate line and uses the following format: "<module_name>": "<module_version>" By default the SuiteCommerce Advanced modules are listed in alphabetical order because there are no dependencies between modules. However, when customizing SuiteCommerce Advanced, your modules may have dependencies on other modules. In that case, you must ensure that any required modules are listed before other modules. ■ taskConfig: defines the gulp tasks required by the build process. In general, you do not need to edit these tasks.. ■ copy: specifies the source and target paths when copying files to the Distribution directory. While the distro.json file defines the modules that are included in SuiteCommerce Advanced, the ns.package.json file determines which files within an individual module are included. Each module included in the distro.json must have a corrsponding ns.package.json file. This file must be at the top level of the module folder. The ns.package.json file uses the following structure: JavaScript example { SuiteCommerce Site Development Core SuiteCommerce Advanced Developer Tools } 302 "gulp": { "javascript": [ "JavaScript/*.js" ] , "templates": [ "Templates/*.txt" ] , "ssp-libraries": [ "SuiteScript/*.js" ] , "services.new": [ "SuiteScript/*.Service.ss" ] } TypeScript example { } "gulp": { "javascript": [ "JavaScript/*.js" "JavaScript/*.ts ] , "templates": [ "Templates/*.txt" ] , "ssp-libraries": [ "SuiteScript/*.js" ] , "services.new": [ "SuiteScript/*.Service.ss" ] } In the above JavaScript example, there is a mapping between file types and partial paths to the location of the files. In general, Gulp.js uses wildcards to specify the contents of a directory. For example, ”JavaScript/ *.js" includes all files with the ”.js" extension that are in the JavaScript folder. However, when creating your own modules, you can point to specific files within a directory, for example: ... "javascript": [ "JavaScript/MyJavaScriptFile.js" ] ... The types shown in the above examples (javascript, templates, services, etc.) correspond to a specific Gulp task. Gulp tasks determine how certain file types are handled. For example, the javascript Gulp task causes all JavaScript files within a distribution to be compiled into a single file. Other Gulp tasks are responsible for copying files from the Modules directory to the Distribution directory. If you are using the 2019.2 release of SCA or later, many of the source files are written in TypeScript with .ts filename extensions. In this case, the ns.package.json file will include “JavaScript/*.ts” to include .ts files as JavaScript. For example: ... "javascript": [ "JavaScript/*.js", "JavaScript/*.ts" ] ... NetSuite recommends that you use only the default Gulp tasks when creating or editing a module. To use a custom file type within ns.package.json, you must create your own custom Gulp task. SuiteCommerce Site Development Core SuiteCommerce Advanced Developer Tools 303 Gulp tasks are stored in the following location: SCA/gulp/tasks Note: This directory is created when you install Gulp.js. It is not included in the downloaded version of the SuiteCommerce Advanced source directory. See Developer Environment for more information. How Files Are Combined Applies to: SuiteCommerce Advanced The SuiteCommerce Advanced source code is divided into multiple modules. These modules contain multiple subdirectories which, in turn, contain individual files, including JavaScript and Sass files. If you are implementing SuiteCommerce Advanced 2019.2 or later, there will also be TypeScript files which are identified with a .ts filename extension. The contents of each of these files contains a logical structure where each element is separated by white space. While this organization makes the source files easy to read and understand, it is inefficient when passing these files across a network to a web browser. Most modern web applications use some method of combining multiipl files spread across multiple directories into a smaller number of combined files. These files are more efficient for a web browser to load because of the fewer number of requests required and smaller total number of bytes transferred. To combine these files, SuiteCommerce Advanced uses Gulp.js to perform the following tasks: ■ Determine which files need to be included in the web application. ■ Combine all of the JavaScript, Sass, and SSP library files into single files. ■ Copy any additional resources required by the application. For example, Gulp.js copies any image files, SSP files or services. All resources required by SuiteCommerce Advanced, including combined and copied files, are stored in the Distribution directory. This directory is deployed to NetSuite. See Contents of the Deploy and Local Distribution Directories for information on the output of the gulp tasks. Contents of the Deploy and Local Distribution Directories Applies to: SuiteCommerce Advanced ■ gulp deploy: creates one or more deploy distribution directories depending on your implementation. □ If you are implementing SCA 2019.2 or later, this command creates the DeployDistributionAdvanced and DeployDistributionAdvancedSS2 directories. The DeployDistributionAdvanced directory contains the combined source files that are deployed to NetSuite. The DeployDistributionAdvancedSS2 directory contains the SuiteScript 2.0 services for deployment. □ If you are implementing SCA 2019.1 or earlier, this command creates the DeployDistribution directory. This directory contains the combined source files that are deployed to NetSuite. ■ gulp local: creates a local distribution directory. □ If you are implementing SCA 2019.2 or later, this command creates the LocalDistibutionAdvanced directory. This directory contains files that are used by the local server. □ If you are implementing SCA 2019.1 or earlier, this command creates the LocalDistribution directory. This directory contains files that are used by the local server. SuiteCommerce Site Development Core SuiteCommerce Advanced Developer Tools 304 The files in the output directories are automatically generated. You should not directly edit any of the files in the deploy or local distribution directories. However, you may need to view the contents of these directories when troubleshooting. The ssp_libraries.js File Applies to: SuiteCommerce Advanced The ssp_libraries.js file contains the server-side JavaScript code used by SuiteCommerce Advanced. When you deploy SuiteCommerce Advanced to NetSuite, the gulp task installs this file in the SSP Application. When compiling the application, the gulp tasks generate the ssp_libraries.js file by combining all of the following: ■ Backend models — includes all of the backend models defined in the application modules. ■ SspLibraries module — contains JavaScript files that provide server-side methods and utilities used by the backend models. This module includes the following files: □ Application.js — defines functions for interacting with SuiteScript and the Commerce API. These functions obtain context and environment information from NetSuite. This file also provides methods for sending HTTP responses and errors and methods for returning paginated results. □ Configuration.js — defines backend configuration for SuiteCommerce Advanced. For more information, see Backend Configuration. □ Console.js — creates the server-side console used to access to the SSP application. □ Events.js — defines the core utilities and base classes to create high-level back-end entity models used by services. □ Models.Init.js — defines global variables available to all backend models. □ SC.Models.js — defines the base class used by backend models. □ Utils.js — defines global utility methods that perform server-side tasks, including searching records and formatting currencies. Changing Your Connection Information Applies to: SuiteCommerce Advanced When deploying to NetSuite using the gulp deploy command, Gulp.js uses the .nsdeploy file to determine how to connect to NetSuite. When you run gulp deploy, the script automatically configures the .nsdeploy file based on the information you provide when running gulp deploy. However, if there are changes to your account information or target folder, you may need to edit this file. To customize the .nsdeploy file: 1. Open the .nsdeploy file in a text editor. 2. Edit the following parameters to reflect your account and system information: ■ email: the email address of the account where you want to deploy. ■ account: the account number where you want to deploy. ■ role: the role of the user for this account. ■ hostname: the hostname where your account is located. ■ target_folder: the ID of the SSP application folder. SuiteCommerce Site Development Customize and Extend Core SuiteCommerce Advanced Modules 305 Customize and Extend Core SuiteCommerce Advanced Modules Applies to: SuiteCommerce Advanced Extend CSS in SCA SuiteCommerce Advanced (SCA) provides a fully functional application that you can use to implement your ecommerce solutions. The Kilimanjaro release of SCA and earlier were designed to give you access to all SCA source code and to let you customize the application to fit your specific business. The source code for the SCA application is organized into modules. You can make changes to existing modules or add new modules to modify or enhance the functionality of a SCA web store. You can change everything from the interface of your site to adding your own custom logic and functionality. This section outlines the process for using the core SCA developer tools. Follow the procedures outlined in this section if: ■ You are developing a SCA site using the Kilimanjaro release or earlier. ■ You are developing a SCA site using the Aconcagua release or later and you are not using extensions to interact with the Extensibility API. Important: If you are implementing the Aconcagua Release of SCA or later, the best practice is to use themes and extensions to customize your site. However, if your customizations require access to objects not available using the Extensibility API, use the procedures outlined in this section to extend code using custom modules. Important: To make changes to SCA, you must have experience working with JavaScript, TypeScript, HTML, and CSS. The level of experience required depends on the types of changes you want to make. The core functionality of SCA can be augmented or modified, but advanced JavaScript programming skills, including knowledge of Backbone.js and jQuery, are required. Note: The module source files for SuiteCommerce Advanced 2019.1 and earlier are JavaScript files with .js filename extensions. The module source files for SuiteCommerce Advanced 2019.2 and later are TypeScript files with .ts filename extensions. For more information about TypeScript, see TypeScript. Before making changes to SCA, you must read and understand Best Practices for Customizing SuiteCommerce Advanced. When reviewing these best practices, it is important to understand the following concepts: ■ Customize – refers to all changes you make to SCA. Customizations can include new features and modules that you create, extensions to JavaScript functionality, and overrides to JSON or template files. ■ Extend – refers to customizations you make to JavaScript code or style sheets. In the case of JavaScript, this refers to changes that alter or enhance the behavior of properties and methods. This involves using the JavaScript prototype of an object or using a helper method like Backbone.extend. ■ Override – refers to changes where you replace the functionality of an entire property, method, or file with your own custom version. In some contexts, customizing a template, override is the only option. In general, however, you should not use this process when making changes to JavaScript source files, TypeScript source files, or style sheets. ■ Configuration Modification – refers to changes you make to the SuiteCommerce Configuration record user interface by modifying the configurationManifest.json file. This involves creating custom JSON configuration modification files. This method requires the Vinson release of SCA or later. Before customizing modules, read and understand the following topics: SuiteCommerce Site Development Customize and Extend Core SuiteCommerce Advanced Modules 306 ■ Core SuiteCommerce Advanced Developer Tools – describes how to setup your local development environment. ■ Architecture – describes how source code and modules are structured. ■ Item Search API – describes how to construct queries for product search results. ■ Configuration File Types – describes how JSON configuration files impact the SuiteCommerce Configuration record user interface. Best Practices for Customizing SuiteCommerce Advanced Applies to: SuiteCommerce Advanced This section explains how to customize the Kilimanjaro release of SCA and earlier. If implementing the Aconcagua release of SCA or later, the best practice is to use themes and extensions to customize your web store. See Themes and Extensions for more information. Important: To make changes to SCA source code, you must have experience working with JavaScript, TypeScript, HTML, and CSS. The level of experience required depends on the types of changes you want to make. The core functionality of SCA can be augmented or modified, but advanced JavaScript programming skills, including knowledge of Backbone.js and jQuery are required. Note: The module source files for SuiteCommerce Advanced 2019.1 and earlier are JavaScript files with .js filename extensions. The module source files for SuiteCommerce Advanced 2019.2 and later are TypeScript files with .ts filename extensions. These implementations require experience working with TypeScript. For more information about TypeScript, see TypeScript. Follow these best practices when customizing or extending SuiteCommerce Advanced (SCA) without themes and extensions. These best practices are designed to provide an easier path for migration when you have changed or added features to the application. Following these best practices enables you to install new versions of a bundle more quickly to take advantage of new features and issue fixes. Different types of files and resources in SCA have different recommended best practices. These are described in the following sections: ■ Organize Source Code for Custom Modules ■ Extend JavaScript ■ Customize the Configuration Manifest ■ Extend JavaScript Configuration Files ■ Override Template Files ■ Extend Style Sheets ■ Override Language Files, Images, and Resource Files Organize Source Code for Custom Modules Before making changes to SCA, you must decide on the conventions you want to use to organize your custom modules. ■ If implementing 2020.1 and later, create a directory named extensions within the SC_<version> directory. Place all of your customizations in the extensions directory. For example: SC_20.1 Advanced SuiteCommerce Site Development Customize and Extend Core SuiteCommerce Advanced Modules 307 Backend Commons extensions gulp ... ■ If implementing 2019.2, create a directory named extensions within the SC_<version>_Live directory. Place all of your customizations in the extensions directory. For example: SC_19.2_Live Advanced Backend Commons extensions gulp ... ■ If implementing 2019.1 and earlier, place all customizations in an extensions directory within the Modules directory. For example: SuiteCommerce Advanced ... Modules extensions suitecommerce third_parties ... In these example hierarchies, your custom modules are stored in the extensions directory. Within your custom directory, name your modules using a version naming convention such as: module_name@x.y.z NetSuite recommends that you use this convention when organizing your modules. For example, if you were creating a new module, your module may be named: MyCustomModule@1.0.0 This naming convention should also apply when extending an existing module. For example, if you are customizing the Case module, your custom module may be named: CaseExtension@1.0.0. Another consideration when determining how to organize your customization source code is to determine how to organize template overrides. As mentioned in Override Template Files, you must override the entire template file, and each template file can only be overridden once. However, the view that uses the template file may be extended in multiple modules. Therefore, you may want to have a convention where template overrides are always performed in their own custom module. The module containing the template override could then be used by other modules that extend the functionality of the view. Extend JavaScript When customizing a property, object, or method within JavaScript, you should use the JavaScript prototype object. By calling the JavaScript prototype function, you can extend a specific property, object, or method without having to extend or override an entire model or view. The primary advantage of using the JavaScript prototype method is that it improves the chances that your customizations continue to work when migrating to a newer version of SCA. When using JavaScript prototypes, the original version of the method or property, is still present along with your customizations. If a new version of SCA contains any issues fixes or enhanced features that are related to that method or property, both the new functionality and your changes are still in place. See Add a Child View to a Composite View for an example of how to implement prototyping. For best results, do not use the override feature of the developer tools when customizing JavaScript files. When overriding a file, all the functionality of a method or property is replaced. When a new version of SuiteCommerce Site Development Customize and Extend Core SuiteCommerce Advanced Modules 308 SCA is installed, any fixes and enhancements are overridden. This can cause problems in both the core SCA functionality and in your customizations. Customize the Configuration Manifest This section applies to Vinson implementations of SCA and later. For details on how to configure properties using pre-Vinson release of SCA or later, see Extend JavaScript Configuration Files. SCA uses the configurationManifest.json to build the SuiteCommerce Configuration record’s user interface and display configurable properties. You can customize the metadata stored in the individual JSON files used to generate this manifest. For example, you can create custom modules to introduce new properties to the manifest or customize existing JSON files to change default values, modify the appearance or location of a property in the user interface, or change property options, etc. Important: Never alter or delete the configurationManifest.json file. To make changes to property metadata, customize the individual JSON files only. When you deploy your site using the developer tools, these individual files and customizations concatenate into and update the configurationManifest.json file. For detailed information on how JSON configuration files affect the configurationManifest.json and the SuiteCommerce Configuration record, see Configure Properties. You have two options for customizing the configurationManifest.json file: ■ Create a new property using a custom module ■ Customize existing property metadata Create a New Property When creating a new property, you must create a custom module and include your changes in JSON format using the JSON Schema V4. You use this custom file to create new properties and any metadata determining their location and behavior in the SuiteCommerce Configuration record. The following steps are required to create a new property: 1. Create a custom module and any required files and subdirectories. 2. Use JSON Schema V4 to declare any new properties and metadata to appear in the manifest. 3. Deploy your changes to NetSuite. See Create JSON Configuration Files for details. Customize Existing Properties To customize existing properties and their associated metadata, you must customize the individual source JSON configuration files using the Configuration Modification method. This allows any module to push changes to properties defined in the Configuration subdirectory of other modules. You can use this method to modify any existing JSON configuration file and add, replace, or remove metadata associated with any existing property. You can do so over any elements within in one JSON configuration file or organize changes across multiple custom modules. See Modify JSON Configuration Files for specific information and examples of the Configuration Modification method. Extend JavaScript Configuration Files This section applies to pre-Vinson implementations of SCA only. For details on how to configure properties using Vinson release of SCA or later, see Configure Properties. SCA uses multiple configuration files to define configuration properties in pre-Vinson implementations of SCA. These properties are defined within JavaScript files as objects and properties. See Configure SuiteCommerce Site Development Customize and Extend Core SuiteCommerce Advanced Modules 309 Properties for specific information on the configuration differences between implementations and the properties they define. In general, you must modify the configuration files to change configuration properties of a module or to include new custom module dependencies within the application. When customizing configuration files, you must create a custom module that redefines the configuration properties you want to change. However, unlike other custom modules, you do not need to use the JavaScript prototype method to extend configuration properties. In general, the following steps are required to customize configuration files: 1. Create a custom module. 2. Include the JSON configuration file as a dependency. 3. Redefine the configuration properties. See Extend Frontend Configuration Files and Extend the Backend Configuration File for more specific information on how to perform these steps. In situations where a configuration file defines an object containing properties, you should only redefine the specific property you want to change. You should avoid redefining the entire object. This helps ensure that there are no conflicts between your customizations and newer versions of SCA. For example, a newer version of SuiteCommerce Advanced may add additional properties that would be overwritten if you redefine the entire object. Before customizing configuration files, you should create a convention for customizing configuration files that makes sense for your development environment. For example, you may want to create a custom module for each configuration file. In this scenario, you extend all configuration properties of the SC.MyAccount.Configuration module within a single custom module. In some situations, you may want to define a custom module for each individual configuration property you override. In this scenario, for example, you may have a module called PaymentWizardCustomConfiguration@1.0.0 where you define an override for the payment wizard configuration object of the SC.MyAccount.Configuration module. Override Template Files Define a Template File Override When extending a template file, you must use the file override method provided by the developer tools. The primary reason for this requirement is that you cannot extend specific parts of a template. This means that all changes you make to a template file must be made in the same custom file that you create. See Override a Template File for an example of how to use the override method. When making changes to a template, you must be aware of the properties and objects that are returned by the getContext() method of the template's view. The getContext() method can be seen as a contract that ensures that when migrating to a new version of SCA the same data is available to the template in the new version. For compatibility with previous versions, a new release of SCA includes the same properties and objects returned by the getContext() method. New properties or objects may be included in new versions of SCA, but the existing properties and objects continue to available. This helps ensures that your template customizations work after migration because they will have access to the same data as the previous version. If you need to expose your own properties or objects to the template, add them to the getContext() method by extending that method using the best practices outlined in Extend JavaScript. Extend Style Sheets SCA uses the Sass scripting language, which is transformed into CSS when you use the developer tools to compile and deploy the application. Sass files have a built-in mechanism for extending style definitions, SuiteCommerce Site Development Customize and Extend Core SuiteCommerce Advanced Modules 310 by using the @extend keyword. This keyword enables you to add the styles of one selector to another one. This enables you to extend only a specific part of a style definition. See Design Hierarchy for information on working with Sass in SCA. To extend a Sass file, you should create a custom module containing a Sass file. This file should only contain the style elements you want to extend as well as any new style elements you define. Nesting Although not a design pattern, keep the following in mind when reading and customizing Sass. SCA uses the ampersand symbol (&) as a nesting technique for classes. This can be handy to simplify your Sass. For example, use the following Sass: .my-class { &.my-other-class {} } This results in the following CSS: .my-class.my-other-class {} Developing Sass in a Local Environment When you run the gulp local command, the Sass preprocessor compiles the CSS for your local site, certain naming conventions affect the various application style sheet files (shopping.css, myaccount.css, and checkout.css). Using the source map, the browser understands and relates your classes to the DOM with the classes defined at the file level during development. This means that, when using the browser developer tools in a local environment, you can easily search for classes the same way you would at the file level during development. Override Language Files, Images, and Resource Files When extending the following resources, you must use the file override method provided by the developer tools: ■ Languages files ■ Images ■ Resource files The primary reason for this requirement is that these resources can only be customized at the file level. Each of these resources can only be overridden once. Therefore, make all changes to these resources within the same file. Customization Examples Applies to: SuiteCommerce Advanced This topic provides basic examples for extending SuiteCommerce Advanced (SCA) and creating your own custom modules. Note the following information about the provided examples: ■ The module source files for SuiteCommerce Advanced 2019.1 and earlier are JavaScript files with .js filename extensions. The module source files for SuiteCommerce Advanced 2019.2 and later are TypeScript files with .ts filename extensions. For more information about TypeScript, see TypeScript. SuiteCommerce Site Development Customize and Extend Core SuiteCommerce Advanced Modules 311 ■ Sample scripts included in the customization examples use SuiteScript 1.0 functions and objects only. These examples do not include SuiteScript 2.0 capabilities. Important: If you are developing the Aconcagua release of SCA or later, the best practice is to implement your changes as themes and extensions. See Customization for more details. Create a Custom Module Applies to: SuiteCommerce Advanced Note: The module source files for SuiteCommerce Advanced 2019.1 and earlier are JavaScript files with .js filename extensions. The module source files for SuiteCommerce Advanced 2019.2 and later are TypeScript files with .ts filename extensions. For more information about TypeScript, see TypeScript. SuiteCommerce Advanced (SCA) is designed so that you can extend it by creating new modules to add functionality specific to your web store. When creating a new module, be aware of the following requirements: ■ The top level directory of your module should have a directory of the format: module_name@x.y.z where module_name is the name of the module and x.y.z is the version number. See Organize Source Code for Custom Modules ■ The directory containing your custom module must be in the correct directory. Examples in this document name this directory extensions; however, you can name this directory any intuitive name as required. □ For 2019.2 and later, SCA source code modules are stored in three sub-directories: Advanced, Backend, and Commons. Create another sub-directory at the same directory level to store all custom module code. Examples: SC_20.1/extensions, SC_19.2_Live/extensions. □ For 2019.1 and earlier, the directory containing your custom module must be in the Modules directory. Modules shipped with SCA are stored in two sub-directories, suitecommerce and third_parties. Create a third sub-directory to store all custom module code. Example: Modules/ extensions. ■ Your new modules directory must have an ns.package.json file to define all of the module dependencies required by the developer tools. For more information, see Core SuiteCommerce Advanced Developer Tools for more information. ■ The module name must be unique. You cannot have duplicate module names, even when they reside in different folders. ■ You must update the distro.json file to ensure that your custom module is loaded into the application. To add a custom module: 1. Create a custom module directory within your custom directory with the format of ModuleName@version. Examples: ■ If implementing 2020.1 and later, create this directory in the extensions directory. For example: SC_20.1/extensions/MyCustomModule@1.0.0. ■ If implementing 2019.2, create this directory in the extensions directory. For example: SC_19.2_Live/extensions/MyCustomModule@1.0.0. ■ If implementing 2019.1 and earlier, create this directory in the Modules/extensions directory. For example: Modules/extensions/MyCustomModule@1.0.0. SuiteCommerce Site Development Customize and Extend Core SuiteCommerce Advanced Modules 312 Important: You cannot use existing module names, even when those modules reside in different folders. 2. Create the subdirectories within the module. The exact subdirectory structure depends on the requirements of your module and your implementation of SCA. NetSuite recommends that you use the same directory structure as existing application modules. Typically, you will need JavaScript, Sass, SuiteScript, and Templates subdirectories. 3. Create the necessary files for your module. This is where all of your modules logic is contained. These files are either JavaScript (.js) or TypeScript (.ts) depending on your implementation of SCA. At a minimum, you will need something like the following: Note: This procedure does not include examples of backend models or services files which are often necessary for backend integration with NetSuite. ■ Entry point – this file acts as an entry point to the module and must return an object containing the mountToApp property that receives the application as a parameter. JavaScript example: //MyNewModule.js define('MyNewModule' , [ 'MyNewModule.Router' ] , function ( Router ) { 'use strict'; return { mountToApp: function (application) { // Initializes the router return new Router(application); } }; }); TypeScript example: /// import Router = require('./Router'); export function mountToApp(application) { new Router(application); } ■ Router – if you are on SuiteCommerce 2019.1 or later, use extensions or a page type component. If you are on SuiteCommerce 2018.2 or earlier, this JavaScript file extends the Backbone router to map URL patterns to the views defined within the module. //MyNewModule.Router.js define('MyNewModule.Router' , [ 'MyNewModule.View' , 'Backbone' SuiteCommerce Site Development Customize and Extend Core SuiteCommerce Advanced Modules , { ] ) function ( MyNewModuleView , Backbone 'use strict'; //@class Address.Router @extend Backbone.Router return Backbone.Router.extend({ routes: { 'my-new-module': 'MyNewModuleRouter' } , initialize: function (application) { this.application = application; } // list myNewRouter output MyNewModuleRouter: function () { var view = new MyNewModuleView({ application: this.application }) view.showContent(); } , }); }); ■ View – this view is called from the router. Often, a view contains a getContext function that describes all of the variables that are passed from the view to the template. JavaScript example: //MyNewModule.View.js define( 'MyNewModule.View' , [ 'my_new_module.tpl' , 'Backbone' , 'jQuery' ] , function ( MyNewModuleTemplate , Backbone , jQuery ) { 'use strict'; //@class Address.List.View List profile's addresses @extend Backbone.View return Backbone.View.extend({ template: MyNewModuleTemplate , events: { 'click [data-action="test"]': 'testAction' } , testAction: function () { alert("This is a test action") } , getContext: function () { return { //@property {String} myNewModuleContextVar myNewModuleContextVar: 'myVariable' }; SuiteCommerce Site Development 313 Customize and Extend Core SuiteCommerce Advanced Modules 314 } }); }); TypeScript example: /// import my_new_module.tpl = require('.//../my_new_module.tpl'); import Backbone = require('../../../Commons/Utilities/JavaScript/backbone.custom'); import jQuery = require('../../../Commons/Utilities/JavaScript/jQuery'); //@class Address.List.View List profile's addresses @extend Backbone.View let BackboneViewExtend: any = Backbone.View.extend({ template: MyNewModuleTemplate, events: { 'click [data-action="test"]': 'testAction' }, testAction: function () { alert("This is a test action") }, getContext: function () { return { //@property {String} myNewModuleContextVar myNewModuleContextVar: 'myVariable' }; } }); export = BackboneViewExtend; ■ Template – this file contains the markup used in combination with the views. Note that the SCA implementation leverages the Handlebars templating engine. <h2>This is my template file for my new module. It takes variables, {{myNewModuleContextVar}}, passed from the View.</ h2> Important: Template file names must be unique. You cannot have duplicate template file names even when they belong to different modules. 4. If your custom module contains any configurable properties, you must include a Configuration subdirectory and place your Configuration Modifications here. See Modify JSON Configuration Files for details. Note: This step only applies to Vinson implementations of SCA and later. 5. Create a new ns.package.json file within the new custom modules directory. ■ If implementing 2020.1 and later, consider this example: SC_20.1/extensions/ MyCustomModule@1.0.0/ns.package.json ■ If implementing 2019.2, consider this example: SC_19.2_Live/extensions/ MyCustomModule@1.0.0/ns.package.json ■ If implementing 2019.1 and earlier, consider this example: Modules/extensions/ MyCustomModule@1.0.0/ns.package.json This file must contain entries for all of the directories required by the module. Use the following example as a template: SuiteCommerce Site Development Customize and Extend Core SuiteCommerce Advanced Modules 315 This file must contain entries for all of the directories required by the module. This file is either JavaScript (.js) or TypeScript (.ts) depending on your implementation of SCA. JavaScript example: { } "gulp": { "javascript": [ "JavaScript/*.js" ] , "templates": [ "Templates/*.tpl" ] , "ssp-libraries": [ "SuiteScript/*.js" ] , "services.new": [ "SuiteScript/*.Service.ss" ] , "sass": [ "Sass/**/*.scss" ] } TypeScript example: { } "gulp": { "javascript": [ "JavaScript/*.js", "JavaScript/*.ts" ] , "templates": [ "Templates/*.tpl" ] , "ssp-libraries": [ "SuiteScript/*.js" ] , "services.new": [ "SuiteScript/*.Service.ss" ] , "sass": [ "Sass/**/*.scss" ] } For Vinson implementations of SCA and later, you must also include the following lines someplace within the gulp object of the ns.package.json file: , "configuration": [ "Configuration/*.json" ] 6. Update the distro.json file. ■ If implementing 2019.2 and later, this file is in the Advanced directory. Examples: SC_20.1/ Advanced/distro.json, SC_19.2_Live/Advanced/distro.json. ■ If implementing 2019.1 and earlier, this file is in the root directory of the SCA source code. Update this file with the following two changes: ■ Add an entry for the new module in the modules object. □ Example if implementing 2019.2 and later: SuiteCommerce Site Development Customize and Extend Core SuiteCommerce Advanced Modules { } 316 "name": "SuiteCommerce Advanced", "version": "2.0", "modules": { "../extensions/myNewModule": 1.0.0", "../Commons/Address", "../AjaxRequestKiller", "../Commons/ApplicationSkeleton", ... □ Example if implementing 2019.1 and earlier: { } "name": "SuiteCommerce Advanced 1.0.0", "version": "1.0.0", "modules": { "suitecommerce/Account": "1.0.0", "extensions/myNewModule": "1.0.0", "suitecommerce/AjaxRequestsKiller": "1.0.0", "suitecommerce/ApplicationSkeleton": "1.0.0", ... ■ Define any application dependencies in the javascript object. For example, if the module is required in the Shop Flow application, add the module to the SC.Shopping.Starter entrypoint. "javascript": [ { "entryPoint": "SC.Shopping.Starter", "exportFile": "shopping.js", "dependencies": [ "Backbone.View.Plugins", "jQuery.html", "ItemDetails", "myNewModule", ... "UrlHelper", "CMSadapter" ], 7. View your changes. Important: If you are on SuiteCommerce 2019.2 or later, all TypeScript (.ts) files are compiled to JavaScript (.js) files when executing the gulp local and gulp deploy commands. After creating your new module, you can test it by viewing your changes in the application. If you are running a local server, you can view your changes by reloading your website. See SCA on a Local Server for more information. If you are viewing your site in NetSuite, you can deploy your changes using the developer tools. See Deploy to NetSuite for more information. SuiteCommerce Site Development Customize and Extend Core SuiteCommerce Advanced Modules 317 Modify JSON Configuration Files Applies to: SuiteCommerce Advanced Note: The module source files for SuiteCommerce Advanced 2019.1 and earlier are JavaScript files with .js filename extensions. The module source files for SuiteCommerce Advanced 2019.2 and later are TypeScript files with .ts filename extensions. For more information about TypeScript, see TypeScript. This section applies to Vinson implementations for SuiteCommerce Advanced (SCA) and later. For details on configuring SCA for pre-Vinson release and earlier, see Extend JavaScript Configuration Files. Important: Never alter or delete the configurationManifest.json file. To make changes to property metadata, customize the individual JSON files only. When you deploy your site using the developer tools, these individual files and customizations concatenate into and update the configurationManifest.json file. For detailed information on how JSON configuration files affect the configurationManifest.json and the SuiteCommerce Configuration record, see Configure Properties. This section explains how to use the Configuration Modification method to change existing configurable properties and associated metadata. When you deploy this modification to NetSuite, the SuiteCommerce Configuration record’s user interface will reflect any changes specified. Configuration Modification requires knowledge of JSONPath query schema, see https://github.com/s3u/JSONPath for more information. Important: Making changes to core source files or changing any vital functionality of the application can make migrating to future releases difficult. Before making changes to SCA, see Best Practices for Customizing SuiteCommerce Advanced. To modify the SuiteCommerce Configuration record’s user interface: 1. Create the directory structure for a custom module. In this example, the name of the module being customized is the RecentlyViewedItems module. Following best practices, the example custom directory is titled RecentlyViewedItemsExtension@1.0.0. 2. Create a Configuration subdirectory in your new module directory. 3. Create a new JSON file in the Configuration subdirectory. In this example, the name of the JSON file being customized is SearchResultsPerPage.json. Following best practices, the custom JSON file is titled SearchResultsPerPageModification.json. 4. Add modification code to your custom JSON file. See Configuration Modification Schema and Use Case Examples for specific information and examples on how to structure this file. 5. Create and edit an ns.package.json file in the root directory of your custom module. Add the following code to this file: { "gulp": { "configuration": [ SuiteCommerce Site Development Customize and Extend Core SuiteCommerce Advanced Modules } } ] 318 "Configuration/*.json" 6. Update the distro.json file. ■ If implementing 2019.2 and later, this file is in the Advanced directory. Examples: SC_20.1/ Advanced/distro.json, SC_19.2_Live/Advanced/distro.json. ■ If implementing 2019.1 and earlier, this file is in the root directory of the SCA source code. Add the name of your custom module to the list of modules defined in the modules object. ... "modules": { "extensions/RecentlyViewedItemsExtension": "1.0.0", "suitecommerce/Account": "2.2.0", ... 7. Deploy your changes to NetSuite and access the SuiteCommerce Configuration record in NetSuite to view your changes. See Deploy to NetSuite for details Note: You must deploy your customizations to NetSuite using the developer tools to apply any modifications to the SuiteCommerce Configuration record. You can confirm changes to the configurationManifest.json code on a local server, but modifications will not take effect until you deploy to NetSuite. Extend Frontend Configuration Files Applies to: SuiteCommerce Advanced This section applies to pre-Vinson implementations for SuiteCommerce Advanced (SCA) only. For details on configuring SCA for Vinson release or later, see Modify JSON Configuration Files. Important: Making changes to core source files or changing any vital functionality of the application can make migrating to future releases difficult. Before making changes to SCA, see Best Practices for Customizing SuiteCommerce Advanced. SCA enables you to configure the behavior of the frontend application by modifying configuration properties and objects. These are properties are contained in configuration files that define objects that are loaded when the application starts. These properties are accessible to all modules within the application. See Configure Properties for more information about these files and the properties they contain. To redefine these properties for your installation you must create a custom module that includes the original configuration file as a dependency. To extend a frontend configuration file: 1. Create the directory structure for your custom module. In this example, the name of the custom module is Configuration, so the module directory would be Configurator@1.0.0. 2. Create the JavaScript subdirectory in your new module directory. SuiteCommerce Site Development Customize and Extend Core SuiteCommerce Advanced Modules 319 3. Create a new JavaScript file in the JavaScript directory of your custom module. In this example, the name of the JavaScript file is Configurator.js 4. Add the mountToApp method to your custom JavaScript file. For example, the code you add should look similar to the following: define('Configurator' , [ 'SC.Configuration' ] , function ( Configuration ) { 'use strict'; return { mountToApp: function () { //Add your custom properties here. } }; }); This code performs the following tasks: ■ Lists the dependencies required. When customizing a configuration file, you must include the object it returns as a dependency. ■ Defines the mountToApp method. This method is required to load your custom module into the application. This method also contains the custom properties you are configuring. 5. Add your custom properties to the block within the mountToApp method as shown in the example above. The following example shows how to redefine different configuration properties: Configuration.imageNotAvailable = 'http://www.tnstate.edu/sociology/images/Image%20Not%20Available.jpg'; Configuration.addToCartBehavior = 'goToCart'; Configuration.facetDelimiters.betweenFacetNameAndValue = '%'; Configuration.productReviews.loginRequired = true; Configuration.typeahead.maxResults = 4; 6. Create and edit the ns.package.json in the root directory of your custom module. For example, the code you add should look similar to the following: { } "gulp": { "javascript": [ "JavaScript/*.js" ] } 7. Update the distro.json file in the root directory of the SCA source directory. You must update this file in two places: ■ Add the name of your custom module to the list of modules defined in the modules object. ■ Add the name of your custom module to the dependencies array of the application whose configuration file you are customizing. To ensure that your customized configuration properties are available to all modules, place your module at the top of this list. 8. View your changes. SuiteCommerce Site Development Customize and Extend Core SuiteCommerce Advanced Modules 320 If you are running a local server, you can view your changes by reloading your website. See SCA on a Local Server for more information. If you are viewing your site in NetSuite, you can deploy your changes using the developer tools. See Deploy to NetSuite for more information. Configure Facet Fields Applies to: SuiteCommerce Advanced This section applies to pre-Vinson implementations for SuiteCommerce Advanced (SCA) only. For details on configuring SCA for Vinson release or later, see Modify JSON Configuration Files. To configure facet fields: You can customize facets by extending a frontend configuration file. Specifically, the SC.Shopping.Configuration.js file contains the facets array, which contains an object for each facet field. You can customize these objects to determine how each associated facet field displays and behaves on your website. 1. Configure how facet fields display on your site. For example, suppose you want to configure the color facet field to display on your website in the following ways: ■ Display the facet title as Item Color ■ Appear expanded when loaded ■ Be collapsible ■ Appear first in the list of facets on your website Your customized object might look like this: , , , , , , , , , , facets: [ { id: 'color' name: _('Item Color').translate() priority: 1 behavior: 'multi' template: facets_faceted_navigation_item_color_tpl collapsed: false uncollapsible: false showHeading: true colors: colors titleSeparator: ', ' } 2. Configure how facet fields display on your site. a. Find the URL Component of the facet field you want to define. ■ In NetSuite, click Setup > SuiteCommerce Advanced > URL Components for Facets. ■ Note the URL Component of each facet you want to configure. See the help topic URL Components for Facets for detailed information. After indexing Facet Fields in your Commerce site record, you can modify the URL components for each facet field. b. Create a custom module that includes the SC.Shopping.Configuration object as a dependency. SuiteCommerce Site Development Customize and Extend Core SuiteCommerce Advanced Modules 321 Note: Do not edit the original SC.Shopping.Configuration.js source file directly. See Extend Frontend Configuration Files for information and best practices on customizing JavaScript within frontend configuration files. c. Extend the facets array, creating an object for each facet field you want to configure. Set the configuration properties as necessary. See Facets Subtab for detailed information on each property. 3. Customize Facet Color Palettes. The SC.Shopping.Configuration.js file contains the colors object. This object maps a color label to its hexadecimal value. You can customize these color values by extending the colors object. a. Extend the colors object within item options or facet object’s colors property. b. Add any hexadecimal color values. The property’s name must match the corresponding color in the colors object. For example, the colors object lists default name/value pairs: var colors = { 'black': '#212121' , 'gray': '#9c9c9c' , 'grey': '#9c9c9c' , 'white': '#fff' , 'brown': '#804d3b' , 'beige': '#eedcbe' , 'blue': '#0f5da3' , 'light-blue': '#8fdeec' , 'purple': '#9b4a97 ' , 'lilac': '#ceadd0' , 'red': '#f63440' , 'pink': '#ffa5c1' , 'orange': '#ff5200' , 'peach': '#ffcc8c' , 'yellow': '#ffde00' , 'light-yellow': '#ffee7a' , 'green': '#00af43' , 'lime': '#c3d600' , 'teal': '#00ab95' , 'aqua': '#28e1c5' , 'burgandy': '#9c0633' , 'navy': '#002d5d' } For example, you want to use a different color for blue and red in your site’s faceted navigation, swapping #0000FF for blue and #f63440 for red. As a best practice, do not edit the default colors object. Instead, extend the object in the colors property of the facet as shown: , { , , , , , , , , , } id: 'color' name: _('Item Color').translate() priority: 1 behavior: 'multi' template: facets_faceted_navigation_item_color_tpl collapsed: false uncollapsible: false showHeading: true colors: _.extend(colors,{'blue':'#0000FF', 'red':'#f63440'}) titleSeparator: ', ' 4. Configure Facet Delimiters. SuiteCommerce Site Development Customize and Extend Core SuiteCommerce Advanced Modules 322 The facetDelimiters object is defined in the global SC.Configuration.js file. This object specifies the characters within the URL that appear between facets, facet names, and their values. To configure facet delimiters: a. Create a custom module that includes the SC.Shopping.Configuration object as a dependency. Note: Do not edit the original SC.Shopping.Configuration.js source file directly. See Extend Frontend Configuration Files for information and best practices on customizing JavaScript within frontend configuration files. b. Extend the facetDelimiters object and set the configuration properties as necessary. See Facets Delimiters Subtab for detailed information on each property. Extend the Backend Configuration File Applies to: SuiteCommerce Advanced This section applies to pre-Vinson implementations for SuiteCommerce Advanced (SCA) only. For details on configuring SCA for Vinson release or later, see Configure Properties. Important: Making changes to core JavaScript source files or changing any vital functionality of the application can make migrating to future releases difficult. Before making changes to SCA, see Best Practices for Customizing SuiteCommerce Advanced. SCA uses a backend configuration file to modify the behavior of NetSuite features. See Backend Configuration for more information. During deployment, the backend configuration file is combined and deployed as a SuiteScript library in NetSuite. Like other JavaScript customizations, the recommended best practice is to create a custom module that redefines the configuration properties that you want to modify. However, since this file is deployed as a SuiteScript library, you only add your custom module to the distro.json file as a dependency. You do not need to define the mountToApp method. To extend the backend configuration file: 1. Create the directory structure for your custom module. In this example, the name of the custom module is BackendConfigurator, so the module directory would be BackendConfigurator@1.0.0. 2. Create the SuiteScript subdirectory in your new module directory. Since the backend configuration file is a SuiteScript file, this directory is required. 3. Create a new JavaScript file in the SuiteScript directory of your custom module. In this example, this file is BackendConfigurator.js 4. Add code to redefine the backend configuration properties you want to change. For example, the code you add should look similar to the following: define('BackendConfigurator' , [ 'Configuration' ] , function ( config ) { 'use strict'; //disable CMS SuiteCommerce Site Development Customize and Extend Core SuiteCommerce Advanced Modules 323 config.useCMS = false; }); This example performs the following: ■ Lists the dependencies required by the custom module. When customizing the backend configuration file, the only required dependency is the Configuration object. This object is defined in the Configuration.js file located in the Modules/Ssplibraries directory of the SCA source directory. ■ Redefines a single configuration property. In this case, the custom module is setting the useCMS property to false. 5. Create and edit the ns.package.json in the root directory of your custom module. Your file should contain code similar to the following: { } "gulp": { "ssp-libraries": [ "SuiteScript/*.js" ] } 6. Edit the distro.json file. You must add your custom module to the distro.json file for it to be loaded into the application. Since this module is extending an SSP library, you must add it to the following locations: ■ Add the name of your custom module to the modules array. To ensure that your customizations are not overwritten by other modules, add the custom module to the top of the array. ■ Add the name of your custom module to the dependencies array of the ssp-libraries object. 7. View your changes. Since the backend configuration file is a SuiteScript file and stored as an SSP library, you must deploy your custom module directly to NetSuite to view your changes. See Deploy to NetSuite for more information. Add a Child View to a Composite View Applies to: SuiteCommerce Advanced Note: The module source files for SuiteCommerce Advanced 2019.1 and earlier are JavaScript files with .js filename extensions. The module source files for SuiteCommerce Advanced 2019.2 and later are TypeScript files with .ts filename extensions. For more information about TypeScript, see TypeScript. Important: Making changes to core JavaScript and TypeScript source files or changing any vital functionality of the application can make migrating to future releases difficult. Before making changes to SuiteCommerce Advanced (SCA), see Best Practices for Customizing SuiteCommerce Advanced. Adding a child view to a parent view is a common way of extending the functionality of SCA. For example, you can easily add a message to a page by adding a GlobalViews.Message.View view as a child view. Adding a child view requires making two types of changes to the SCA source code: ■ Extend the childViews object of a view. Since this requires a change to a JavaScript or TypeScript source file, you should create a custom module that uses prototyping to add the child view. ■ Override the template file. In addition to adding the view to the childViews object, you must also edit the HTML template to implement the child view in a page. SuiteCommerce Site Development Customize and Extend Core SuiteCommerce Advanced Modules Note: Since a template file can only be overridden once, you may want to define the override in a different custom module created specifically for template overrides when making your own customizations. See Override a Template File for more information. To extend the childViews object of a view: 1. Create the directory structure for your custom module. a. Create a directory called extensions. ■ If implementing 2019.2 and later, create this directory in the Advanced directory. Examples: SC_20.1/Advanced/extensions, SC_19.2_Live/Advanced/extensions. ■ If implementing 2019.1 and earlier, create this directory in the Modules directory. For example: Modules/extensions b. In the extensions directory, create a subdirectory called HeaderExtension@1.0.0. c. In the HeaderExtension directory, create a subdirectory called JavaScript. d. Also in the HeaderExtension directory, create another subdirectory called Templates. In general, when performing your own customizations you should create a directory structure similar to the above procedure. See Organize Source Code for Custom Modules for more information. 2. Create a new file. ■ If implementing 2019.2 or later, name this file HeaderExtension.ts. ■ If implementing 2019.1 or earlier, name this file HeaderExtension.js. 3. Define your custom module and dependencies by adding the following code to this file. This code defines the dependencies required by your custom module. If implementing SuiteCommerce 2019.1 or earlier, see Asynchronous Module Definitions (AMD) and RequireJS for information on defining dependencies within a module. This module includes the following views as dependencies: ■ Header.View – is required to extend the childViews object. ■ GlobalViews.Message.View – is required to add a message view to the application header. JavaScript example: define('HeaderExtension' , [ 'underscore' , 'Header.View' , 'GlobalViews.Message.View' ] , function ( _ , HeaderView , GlobalViewsMessageView ) { 'use strict'; //Additional code goes here. }); TypeScript example: /// /// SuiteCommerce Site Development 324 Customize and Extend Core SuiteCommerce Advanced Modules 325 import * as _ from 'underscore'; import HeaderView = require('../../Header/JavaScript/Header.View'); import GlobalViewsMessagesView = require ('../../GlobalViews.Messages.View'); //Additional code goes here.; 4. Add the mountToApp method to Header.Extension.js (or Header.Extension.ts) as shown in the following: return { { } } mountToApp: function (application) HeaderView.prototype.childViews.HeaderExtension = function() { return new GlobalViewsMessageView({ message: 'Hello World! - This is an Example of a GlobalMessageView!' , type: 'success' , closable: true }); } This code performs the following: ■ Specifies a return statement that returns the mountToApp method. This method is required to load a module into the application. ■ Extends the childViews object of the Header.View module using JavaScript prototyping. 5. Copy the original template file to your custom module. a. Copy the header.tpl file to the Templates directory of your custom module. ■ If implementing 2019.2 and later, copy the header.tpl file from the Advanced/Header/ Templates directory. ■ If implementing 2019.1 and earlier, copy the header.tpl file from the Modules/ suitecommerce/Header/Templates directory. b. Edit the custom template file by adding the following HTML code: <div data-view="HeaderExtension"</div> Add the HTML code at a place in the template where it will be displayed in the Header view. For example, you can add it directly above the <div class="header-menu-cart"> tag. 6. Create the ns.package.json file a. Create a file called ns.package.json in the HeaderExtension directory. b. Add the following to the ns.package.json file. ■ If implementing 2019.2 and later: { "gulp": { "javascript": [ "JavaScript/*" ] , "templates": [ "Templates/*" ] }, "overrides": { "../Header/Templates/header.tpl": "Templates/header.tpl" } SuiteCommerce Site Development Customize and Extend Core SuiteCommerce Advanced Modules 326 } ■ If implementing 2019.1 and earlier: { } "gulp": { "javascript": [ "JavaScript/*" ] , "templates": [ "Templates/*" ] }, "overrides": { "suitecommerce/Header@1.1.0/Templates/header.tpl": "Templates/header.tpl" } 7. Add an entry for your module to the distro.json file. This file is located in a different location, depending on your implementation: ■ If implementing 2019.2 and later, the distro.json file is located in the Advanced directory of the SCA source code. Examples: SC_20.1/Advanced/distro.json, SC_19.2_Live/Advanced/distro.json ■ If implementing 2019.1 and earlier, the distro.json file is located in the root directory of the SCA source code. You must add your custom view to the javascript object within the distro.json file. Your code should look similar to the following: "javascript": [ { "entryPoint": "SC.Shopping.Starter", "exportFile": "shopping.js", "dependencies": [ "Header.Extension.View", "Backbone.View.Plugins", "jQuery.html", "ItemDetails", ... In this example, we are only customizing a single file, so we only add the Header.Extension module to the javascript object. In cases where you are customizing or overriding an entire application module, you may need to add the application module name here. 8. View your changes. Note: The module source files for SuiteCommerce Advanced 2019.1 and earlier are JavaScript files with .js filename extensions. The module source files for SuiteCommerce Advanced 2019.2 and later are TypeScript files with .ts filename extensions. For more information about TypeScript, see TypeScript. If you are running a local server, you can view your changes by reloading your website. See SCA on a Local Server for more information. If you are viewing your site in NetSuite, you can deploy your changes using the developer tools. See Deploy to NetSuite for more information. Override a Template File Applies to: SuiteCommerce Advanced Define a Template File Override SuiteCommerce Site Development Customize and Extend Core SuiteCommerce Advanced Modules 327 Important: Making changes to core JavaScript source files or changing any vital functionality of the application can make migrating to future releases difficult. Before making changes to SuiteCommerce Advanced (SCA), see Best Practices for Customizing SuiteCommerce Advanced. This section explains how to override a template file if you are on the Kilimanjaro release of SCA or earlier. If implementing the Aconcagua release of SCA or later, the best practice is to use themes and extensions to customize your web store. See Themes and Extensions for more information. When customizing SCA, you may need to change the HTML code of the application. To add, remove, or change the HTML, you must customize the template file for the module that corresponds to the feature you want to change. To customize a template, you must use the override method provided by the developer tools. Since there is no mechanism for overriding or extending a specific part of a template, you must override the entire file. This example describes how to override a template file to add additional text to the product description page. You can use this example as a guide when customizing your own templates. To override a template: 1. Create a directory to store your template. Where you place this depends on your implementation. ■ If implementing 2019.2 and later, create this directory within the SCA source code root directory. Examples: SC_20.1/extensions, SC_19.2_Live/extensions. ■ If implementing 2019.1 and earlier, create this directory within the Modules directory. For example: Modules/extensions. a. In the extensions directory, create a subdirectory called ItemDetailsExtension@1.0.0. When creating a new custom module, the module name must be unique. You must not have duplicate module names, even if those modules reside in different folders. b. In the ItemDetailsExtension@1.0.0 directory, create a subdirectory called Templates. c. If required, create another subdirectory called Sass. In general, when creating custom modules, you should create a directory structure similar to that described in the procedure above. See Organize Source Code for Custom Modules for more information. 2. Copy the original template file to your custom directory. The string x.y.z corresponds to the version of ItemDetails module in your version of SCA. ■ If implementing 2019.2 and later, copy the item_detail.tpl file from /ItemDetails@x.y.z/ Templates to the Templates directory of your custom application module. ■ If implementing 2019.1 and earlier, copy the item_detail.tpl file from Modules/ suite_commerce/ItemDetails@x.y.z/Templates to the Templates directory of your custom application module. 3. Create the ns.package.json file. You must create this file in the ItemDetailsExtension@1.0.0 directory. 4. Add the required code to the ns.package.json file. ■ If implementing 2019.2 and later, the contents of your ns.package.json file should be similar to the following: { "gulp": { "templates": [ "Templates/*" ] , "sass": [ "Sass/**/*.scss" SuiteCommerce Site Development Customize and Extend Core SuiteCommerce Advanced Modules } 328 ] }, "overrides": { "Advanced/ItemDetails@x.y.z/Templates/item_details.tpl": "Templates/item_details.tpl" } ■ If implementing 2019.1 and earlier, the contents of your ns.package.json file should be similar to the following: { } "gulp": { "templates": [ "Templates/*" ] , "sass": [ "Sass/**/*.scss" ] }, "overrides": { "suitecommerce/ItemDetails@x.y.z/Templates/item_details.tpl": "Templates/item_details.tpl" } Note: You must replace the string x.y.z in the above examples with the version of the ItemDetails module in your version of SCA. SutieCommerce 2019.2 and later do not include the @x.y.z directory name suffix. The first section of these examples defines the required objects used by gulp to include your customized template and Sass files when combining the application. The second section contains the override directive which maps the original file in the SCA source distribution directory to your custom template file. In this example, this mapping tells the gulp.js combiner to override a specific file. 5. Edit your custom template. This procedure shows the basic steps required to modify a template. However, you can fully customize your templates as required. See Design Architecture for more information. 1. Open the item_details.tpl file you copied above. 2. In your editor, search for the string Add to Cart. This string defines the label for the add to cart button. 3. Replace this string with the string ’Add to Your Cart.' 6. Create a custom Sass file, if required. See Extend a Sass File for more information. 7. Update the distro.json file. You must add your custom module to the distro.json file to ensure that the gulp tasks include your custom template. If you are customizing Sass files, you must also add a reference to them in the appropriate location in the distro.json file. See Extend a Sass File for more information. In the examples below, the ItemDetailsExtension module is added at the beginning of the list of modules. However, you can add the module anywhere in the modules object. If a module contains only customized template or Sass files, the order of precedence in this list does not matter. ■ If implementing 2019.2 and later, add an entry for the new module in the list of modules in the modules object as shown below: { "name": "SuiteCommerce Advanced Live", "version": "2.0", SuiteCommerce Site Development Customize and Extend Core SuiteCommerce Advanced Modules 329 "isSCA": true, "buildToolsVersion": "Live", "folders": { "thirdPartyModules": "../../third_parties", "distribution": "../LocalDistribution", "deploy": "../DeployDistribution" }, "modules": { "../extensions/ItemDetailsExtension": "1.0.0", "../Commons/Address", "../Commons/AjaxRequestsKiller", ... ■ If implementing 2019.1 and earlier, add an entry for the new module in the list of modules in the modules object as shown below: { "name": "SuiteCommerce Advanced Mont Blanc", "version": "2.0", "buildToolsVersion": "1.1.0", "folders": { "modules": "Modules", "suitecommerceModules": "Modules/suitecommerce", "thirdPartyModules": "Modules/third_parties", "distribution": "LocalDistribution", "deploy": "DeployDistribution" }, "modules": { "extensions/ItemDetailsExtension": "1.0.0", "suitecommerce/Account": "2.1.0", ... 8. View your changes. If you are running a local server, you can view your changes by reloading your website. See SCA on a Local Server for more information. If you are viewing your site in NetSuite, you can deploy your changes using the developer tools. See Deploy to NetSuite for more information. When viewing your changes, you should see new button label and the item details and item image should be reversed. Extend a Sass File Applies to: SuiteCommerce Advanced Important: Making changes to core JavaScript source files or changing any vital functionality of the application can make migrating to future releases difficult. Before making changes to SuiteCommerce Advanced (SCA), see Best Practices for Customizing SuiteCommerce Advanced. SCA enables you to customize your web store to easily apply global style changes while supporting migration to later versions. When customizing styles, you create a custom module that overrides specific Sass variables already defined in the BaseSassStyles module. You then redefine application dependencies so that base Sass styles import your customizations in the correct order. This example shows how to create a custom module to change the default background and foreground colors. To extend a Sass file: 1. Create the directory structure to store your custom module. a. Create a directory called extensions. Where you place this depends on your implementation. SuiteCommerce Site Development Customize and Extend Core SuiteCommerce Advanced Modules 330 ■ If implementing 2019.2 and later, create the extensions directory within the SC_xxx directory within your root source directory. Examples: SC_20.1/extensions, SC_19.2_Live/ extensions. ■ If implementing 2019.1 and earlier, create the extensions directory within the Modules directory. For example: Modules/extensions. b. In the extensions directory, create a subdirectory called CustomSass@1.0.0. When creating a new custom module, the module name must be unique. You must not have duplicate module names, even if those modules reside in different folders. c. In the CustomSass@1.0.0 directory, create a subdirectory called Sass. In general, when creating custom modules, you should create a directory structure similar to that described in the procedure above. See Organize Source Code for Custom Modules for more information. 2. Create a Sass file. a. In the Sass directory, create a new file called _custom-sass.scss. b. Add Sass variable definitions to this file. These variable definitions override the base Sass variables defined in the BaseSassStyles module. See Design Hierarchy for more information. $sc-color-primary: #0000ff; // originally #f15c28; $sc-color-secondary: #00ff00; //originally #5B7F8C; $sc-color-theme: #00ff00; //originally #5B7F8C; $sc-color-link: #00ff00; //originally #2f9ac3; $sc-color-theme-light: #00aa00; // originally #9cb6bf $sc-color-theme-background: #000000; $sc-color-dark-copy: #e7d13b; // originally #1f2223; $sc-color-copy: #ede39f; //originally #404040; body { background-color: $sc-color-theme-background; } 3. Create the ns.package.json file. a. Create a file called ns.package.json in the CustomSass@1.0.0 directory. b. Add the following to the ns.package.json file. { } "gulp": { "sass": [ "Sass/**/*.scss" ] } 4. Update the distro.json file. a. Add an entry for your CustomSass@1.0.0 module to the distro.json file. ■ If implementing 2019.2 and later, the distro.json file is located in the Advanced directory of the SCA source code. Examples: SC_20.1/Advanced/distro.json, SC_19.2_Live/ Advanced/distro.json { "name": "SuiteCommerce Advanced Live", "version": "2.0", "isSCA": true, "buildToolsVersion": "Live", "folders": { "thirdPartyModules": "../../third_parties", SuiteCommerce Site Development Customize and Extend Core SuiteCommerce Advanced Modules 331 "distribution": "../LocalDistribution", "deploy": "../DeployDistribution" }, "modules": { "extensions/CustomSass": "1.0.0", "Account", "Balance", ... ■ If implementing 2019.1 and earlier, the distro.json flie is located in the root directory of your SCA source code. { b. "name": "SuiteCommerce Advanced Mont Blanc", "version": "2.0", "buildToolsVersion": "1.1.0", "folders": { "modules": "Modules", "suitecommerceModules": "Modules/suitecommerce", "thirdPartyModules": "Modules/third_parties", "distribution": "LocalDistribution", "deploy": "DeployDistribution" }, "modules": { "extensions/CustomSass": "1.0.0", "suitecommerce/Account": "2.1.0", ... Split the BaseSassStyle entry in the sass object and add your custom module between them. This ensures that the Sass variables are loaded in the correct order as follows: 1. The main-variables Sass file. 2. The custom Sass variables defined in the CustomSass module. 3. Additional Sass files of the BaseSassStyles module. Including these last ensures that the additional Sass files import the custom variable definitions. { }, "module": "BaseSassStyles", "include": [ "main-variables" ] "CustomSass", { "module": "BaseSassStyles", "include": [ "main-atoms", "main-molecules", "bootstrap-overrides" ] }, Note: You must define these dependencies for each application whose Sass variable you want to change. 5. View your changes. If you are running a local server, you can view your changes by reloading your website. See SCA on a Local Server for more information. If you are viewing your site in NetSuite, you can deploy your changes using the developer tools. See Deploy to NetSuite for more information. SuiteCommerce Site Development Customize and Extend Core SuiteCommerce Advanced Modules 332 Create a CCT Module Applies to: SuiteCommerce Advanced A custom content type (CCT) lets you create custom functionality as content that you can dynamically manage using Site Management Tools. Implementing CCTs for SuiteCommerce Advanced (SCA) requires two separate, but related activities. If you are implementing the Kilimanjaro release of SCA, you must first create a custom SCA module to contain the JavaScript, HTML, Sass, and resources required for your CCT. This topic explains how to accomplish this. The second activity involves setting up custom records in NetSuite for your custom content type using Site Management Tools. See Custom Content Type for details on setting up your CCT using Site Management Tools. Important: If you are developing SuiteCommerce or the Aconcagua release of SCA or later, you must create CCTs using extensions. See the help topic Create a Custom Content Type. Note: You must have Site Management Tools enabled in your NetSuite account to implement CCTs on your SCA site. See the help topic Site Management Tools for information on how to set up SMT. This procedure explains how to do the following: 1. Create a Custom Module for Your CCT. 2. Create an Entry Point JavaScript File. 3. Create a View File. 4. Create a Template File. 5. Set Up Your ns.package.json and distro.json Files 6. Deploy your code to your NetSuite account. Create a Custom Module for Your CCT Applies to: SuiteCommerce Advanced Your CCT module must include the following files at a minimum: ■ Entry point – this JavaScript file includes the mountToApp() method, which links your custom module to a CMS Content Type record, making it available for inclusion in your website. If you are on SuiteCommerce Advanced 2019.2 or later, this will be a TypeScript (.ts) file. ■ View – this JavaScript file listens for and interprets events and defines the variables for use by the template. These variables are the various fields within your CMS Content Type record. If you are on SuiteCommerce Advanced 2019.2 or later, this will be a TypeScript (.ts) file. ■ HTML template – this file uses Handlebars.js helpers and HTML to render the content to your site. The following procedures use a fictitious CCT named SC.CCT.ImageViewer as an example. This CCT introduces a simple image viewer that gets data from either a custom record (as set up in Site Management Tools) or from certain data previously made available in the browser. You can download the code samples described in these examples here: Example ImageViewer CCT. SuiteCommerce Site Development Customize and Extend Core SuiteCommerce Advanced Modules 333 Note: You can create a custom CCT module to retrieve, create, and update data stored in NetSuite records using services and models. To do this, you must implement these files as you would any custom module. See Module Architecture for details. To create a CCT Module: 1. Create a custom module to contain your CCT files. As a best practice, use the following format when naming your CCT Module: SC.CCT.cctName@x.y.z, where cctName is the name of your CCT and x.y.z is the version number. For example: SC.CCT.ImageViewer@0.0.1 2. In your new module, create the following subdirectories at a minimum: ■ JavaScript – contains the entry point JavaScript or TypeScript file and all views. ■ Templates – contains the HTML template that will render your CCT. Note: If your CCT introduces any new Sass, SuiteScript, or Configuration files, add subdirectories for these files as well. Create an Entry Point JavaScript File Applies to: SuiteCommerce Advanced Note: The module source files for SuiteCommerce Advanced 2019.1 and earlier are JavaScript files with .js filename extensions. The module source files for SuiteCommerce Advanced 2019.2 and later are TypeScript files with .ts filename extensions. For more information about TypeScript, see TypeScript. The entry point file is necessary to mount your module to the application. This provides the connection between SuiteCommerce Advanced (SCA) and Site Management Tools. For more information on the architecture and purpose of this file, see Entry Point. To create the entry point: 1. In your CCT module’s JavaScript directory, create a new .js file. 2. Name this file to intuitively relate to your module. JavaScript example: ../SC.CCT.ImageViewer@0.0.1/JavaScript/SC.CCT.ImageViewer.js TypeScript example: ../SC.CCT.ImageViewer@0.0.1/JavaScript/SC.CCT.ImageViewer.ts 3. Define your entry point dependencies. This includes the view that you create later. JavaScript example: define( 'SC.CCT.ImageViewer' SuiteCommerce Site Development Customize and Extend Core SuiteCommerce Advanced Modules , , [ ] ) 'SC.CCT.ImageViewer.View' function ( SCCCTImageViewerView TypeScript example: /// import SCCCTImageViewerView = require('./SC.CCT.ImageViewer.View'); 4. Create the mountToApp() method. This method is required to initialize your CCT module, making it available to the application. Wrapped inside the mountToApp method is getComponent(‘CMS’).registerCustomContentType(), which passes the id and view variables to SMT: ■ The id variable loads the CMS Content Type record, connecting your module to the CCT and making your CCT available in Site Management Tools. Important: The value of the id variable must match the Name field of the CMS Content Type record, and it must be all lowercase. See CMS Content Type Record for details. ■ The view variable initializes the view. In the following examples, the id variable is ‘sc_cct_imgageviewer’, which matches the CMS Content Type record’s Name field. JavaScript example: { 'use strict'; //@class SC.CCT.ImageViewer return { mountToApp: function mountToApp (application) { application.getComponent('CMS').registerCustomContentType({ id: 'sc_cct_imgageviewer' , view: SCCCTImageViewerView }); } }; }); TypeScript example: { 'use strict'; //@class SC.CCT.ImageViewer export function mountToApp(application){ application.getComponent('CMS').registerCustomContentType({ id: 'sc_cct_imgageviewer' , view: SCCCTImageViewerView }); } }; 5. Save the file. SuiteCommerce Site Development 334 Customize and Extend Core SuiteCommerce Advanced Modules 335 Important: Your SCA source code includes a module named SC.CCT.Html. This module connects your SCA application to the four core CCTs that come with the Site Management Tools SuiteApp. Do not customize or alter the contents of this module. Create a View File Applies to: SuiteCommerce Advanced Note: The module source files for SuiteCommerce Advanced 2019.1 and earlier are JavaScript files with .js filename extensions. The module source files for SuiteCommerce Advanced 2019.2 and later are TypeScript files with .ts filename extensions. For more information about TypeScript, see TypeScript. Although the entry point loads your custom module as a CCT in Site Management tools, your CCT still has no data to work with. The view file is necessary to access data, listen to and interpret user events, and specify the context for the template to render the data. Included with your SuiteCommerce Advanced (SCA) source files, the CustomContentType module introduces the CustomContentType.Base.View.js. This file extends BackboneView.js, initializes the CCT settings, and includes the base CCT class from which all custom CCT modules extend. You create your custom view to extend CustomContentType.Base.View.js. Accessing Data Each view can access SCA data about an item, itemlist, product, or category (available to the DOM via certain SCA modules). Your view can also return the values for Custom Record fields linked to the CMS Content Type record. Important: Each view requires the getContext() method to expose this data to your templates. Accessing SCA Data If your CCT requires access to data not associated with a custom record’s fields, you can use the contextDataRequest array property to access some SCA objects. If your CCT requires access to this data, you can set up your view to consume the information that the following contextData objects provide, assuming the information is previously provided in the DOM at the location that you place the CCT. SuiteCommerce Site Development Customize and Extend Core SuiteCommerce Advanced Modules contextData Object View 336 Information Returned JavaScript File (SCA 2019.1 and TyeScript File (SCA 2019.2 and Earlier) Later) category Facets.Browse.View.js Facets.Browse.View.ts Returns the data of the category you are navigating item ProductDetails.Base.View.js ProductDetails.Base.View.ts Returns the data of the item in the product details page itemlist Facets.Browse.View.js Facets.Browse.View.ts Returns the current list of items in the search page product ProductDetails.Base.View.js ProductDetails.Base.View.ts Returns the data of the product in the product details page Note: By default, when you add SCA content into an area using the SMT Admin, the application runs the validateContextDataRequest method to check that you have all the requested contexts. In some cases, the contextData object might request information that is optional, and the data might not exist. In these cases, the validateContextDataRequest method fails because the data request comes back empty. To account for this, set up your view to override the validateContextDataRequest method to always return true. Example: The example ImageViewer CCT requests the name of the item object. Your code might look similar to the following: //... , , { } , //... contextDataRequest: ['item'] validateContextDataRequest: function() return true; getContext: function getContext() { } //... if (this.contextData.item) { var item = this.contextData.item(); //... } //... Accessing Custom Record Fields By default, the template receives a context object for each property defined in each associated Custom Record within a settings object. This is where you define the fields, by Field ID. Example: The example ImageViewer CCT uses a custom record with the following fields: ■ custrecord_sc_cct_iv_valign – sets the vertical alignment of a text object. ■ custrecord_sc_cct_iv_text – declares some text to display. ■ custrecord_sc_cct_iv_imageurl – declares the URL to an image. SuiteCommerce Site Development Customize and Extend Core SuiteCommerce Advanced Modules Within the getContext() method, you declare specific fields associated with your Custom Record as settings. Assuming the custrecord_sc_cct_iv_valign field requires a custom list of options, your code might look similar to the following. //... , getContext: function() { var texts = [] , imageUrl = '' , valign = this.valign[this.settings.custrecord_sc_cct_iv_valign] || this.valign['3']; var set_text = Utils.trim(this.settings.custrecord_sc_cct_iv_text) , set_texts = set_text ? set_text.split('\n') : [] , set_imageUrl = Utils.trim(this.settings.custrecord_sc_cct_iv_imageurl); //... texts = set_texts.length ? set_texts : texts; imageUrl = set_imageUrl ? set_imageUrl : imageUrl; To create the View: 1. In your CCT module’s JavaScript directory, create a new .js or .ts file (depending on your implementation). 2. Name this file to intuitively relate to your module as a view. This will be a TypeScript (.ts) file if you are on SuiteCommerce 2019.2 or later). Example: ../SC.CCT.ImageViewer@0.0.1/JavaScript/SC.CCT.ImageViewer.View.js 3. Define the view’s dependencies. For the example ImageViewer CCT, your code might look like this: JavaScript example: define( 'SC.CCT.ImageViewer.View' , [ 'CustomContentType.Base.View' , 'SC.Configuration' , { , 'sc_cct_imageviewer.tpl' , , ] 'Utils' 'jQuery' , sc_cct_imageviewer_tpl , , ) Utils jQuery function ( CustomContentTypeBaseView , Configuration TypeScript example: /// amd-module name="SC.CCT.ImageViewer.View"/> import import import import import CustomContentTypeBaseView = require('../../CustomContentType.Base.View'); Configuration = require('../../Configuration'); sc_cct_imageviewer_tpl = require('../Templates/sc_cct_imageviewer.tpl'); Utils = require('../../../Commons/Utilities/Utils') jQuery = require('../../../Commons/Utilities/jQuery') SuiteCommerce Site Development 337 Customize and Extend Core SuiteCommerce Advanced Modules 338 4. Build your view according to your CCT’s requirements. 5. Save the view file. If you are on SuiteCommerce Advanced 2019.2 or later and using TypeScript, your example ImageViewer CCT file might look similar to the following: /// amd-module name="SC.CCT.ImageViewer.View"/> import import import import import CustomContentTypeBaseView = require('../../CustomContentType.Base.View'); Configuration = require('../../SC.Configuration'); sc_cct_imageviewer_tpl = require('../Templates/sc_cct_imageviewer.tpl'); Utils = require('../../Commons/Utilities/Utils.ts') jQuery = require('../../Commons/Utilities/jQuery') const cctImageViewerView: any = CustomContentTypeBaseView.extend({ template: sc_cct_imageviewer_tpl , install: function (settings, context_data) { this._install(settings, context_data); var promise = jQuery.Deferred(); // The setTimeout method emulates an ajax call when the CCT is executed for the first time. setTimeout(function() { promise.resolve(); }, 4000); } return promise; , contextDataRequest: ['item'] , validateContextDataRequest: function() { return true; } , valign: { '1': 'top' , '2': 'center' , '3': 'bottom' } , getContext: function() { var texts = [] , imageUrl = '' , valign = this.valign[this.settings.custrecord_sc_cct_iv_valign] || this.valign['3']; if (this.contextData.item) { var item = this.contextData.item(); texts = [item.get('_name')]; var thumbnail = item.get('_thumbnail'); imageUrl = thumbnail.url ? thumbnail.url : thumbnail; } var set_text = Utils.trim(this.settings.custrecord_sc_cct_iv_text) , set_texts = set_text ? set_text.split('\n') : [] , set_imageUrl = Utils.trim(this.settings.custrecord_sc_cct_iv_imageurl); texts = set_texts.length ? set_texts : texts; imageUrl = set_imageUrl ? set_imageUrl : imageUrl; return { hasText: !!texts.length , texts: texts , hasImage: !!imageUrl , imageUrl: imageUrl , valign: valign SuiteCommerce Site Development Customize and Extend Core SuiteCommerce Advanced Modules } 339 }; }); export = cctImageViewerView; If you are on SuiteCommerce Advanced 2019.1 or earlier, your example ImageViewer CCT file might look similar to the following: define( 'SC.CCT.ImageViewer.View' , [ 'CustomContentType.Base.View' , 'SC.Configuration' , { , 'sc_cct_imageviewer.tpl' , , ] 'Utils' 'jQuery' , sc_cct_imageviewer_tpl , , ) Utils jQuery function ( CustomContentTypeBaseView , Configuration 'use strict'; return CustomContentTypeBaseView.extend({ template: sc_cct_imageviewer_tpl , install: function (settings, context_data) { this._install(settings, context_data); var promise = jQuery.Deferred(); // The setTimeout method emulates an ajax call when the CCT is executed for the first time. setTimeout(function() { promise.resolve(); }, 4000); return promise; } , , contextDataRequest: ['item'] validateContextDataRequest: function() { return true; } , , valign: { '1': 'top' , '2': 'center' , '3': 'bottom' } getContext: function() { var texts = [] , imageUrl = '' , valign = this.valign[this.settings.custrecord_sc_cct_iv_valign] || this.valign['3']; if (this.contextData.item) { var item = this.contextData.item(); SuiteCommerce Site Development Customize and Extend Core SuiteCommerce Advanced Modules texts = [item.get('_name')]; } var thumbnail = item.get('_thumbnail'); imageUrl = thumbnail.url ? thumbnail.url : thumbnail; var set_text = Utils.trim(this.settings.custrecord_sc_cct_iv_text) , set_texts = set_text ? set_text.split('\n') : [] , set_imageUrl = Utils.trim(this.settings.custrecord_sc_cct_iv_imageurl); texts = set_texts.length ? set_texts : texts; imageUrl = set_imageUrl ? set_imageUrl : imageUrl; } }); return { hasText: !!texts.length , texts: texts , hasImage: !!imageUrl , imageUrl: imageUrl , valign: valign }; }); Create a Template File Applies to: SuiteCommerce Advanced The template is necessary to render the data defined by the view. To create a template: 1. In your CCT module’s Templates directory, create a new .tpl file. 2. Name this file to intuitively relate to your module as a template. For example: ../SC.CCT.ImageViewer@0.0.1/Templates/sc_cct_imageviewer.tpl 3. Create the HTML required to render the data defined by the view. For the example ImageViewer CCT, your template might look similar to the following: <div class="sc-cct-imageviewer"> <div class="sc-cct-imageviewer-slider-container"> <div class="sc-cct-imageviewer-image-slider"> <ul data-sc-cct-imageviewer class="sc-cct-imageviewer-image-slider-list"> <li> <div class="sc-cct-imageviewer-slide-main-container"> {{#if hasImage}} <img src="{{resizeImage imageUrl 'main'}}" alt="{{imageAlt}}" /> {{/if}} {{#if hasText}} <div class="sc-cct-imageviewer-slide-caption sc-cct-imageviewer-slide-caption-{{valign}}"> {{#each texts}} <h2 class="sc-cct-imageviewer-slide-caption-title">{{this}}</h2> {{/each}} </div> {{/if}} </div> </li> </ul> </div> </div> </div> 4. Save the template. SuiteCommerce Site Development 340 Customize and Extend Core SuiteCommerce Advanced Modules 341 Set Up Your ns.package.json and distro.json Files Applies to: SuiteCommerce Advanced To set up your ns.package.json file: 1. Open your root CCT module directory. 2. Create a new file in the custom module and name it ns.package.json. For example: ../SC.CCT.ImageViewer@0.0.1/ns.package.json 3. Build the ns.package.json file using the following code: { } "gulp": { "javascript": [ "JavaScript/*" ] , "templates": [ "Templates/*" ] } Note: If your CCT includes any custom Sass, SuiteScript, auto-generated services, or configuration files, you must account for this here as well. To set up your distro.json file: 1. Open the distro.json file. ■ If implementing 2019.2 and later, the distro.json file is located in the Advanced directory of the SCA source code. Examples: SC_20.1/Advanced/distro.json, SC_19.2_Live/Advanced/distro.json ■ If implementing 20191 and earlier, this file is located in the top-level directory of your SCA development directory. 2. Add an entry for the new CCT module in the modules object to ensure that the Gulp tasks include your code when you deploy to NetSuite. It should look similar to the following: ■ If implementing 2019.2 and later, it should look similar to the following: { } "name": "SuiteCommerce Advanced Live", "version": "2.0", "modules": { //... "../Advanced/SC.CCT.Html": "1.0.0", "../Advanced/SC.CCT.ImageViewer": "0.0.1", //... ■ If implementing 2019.1 and earlier, it should look similar to the following: { } "name": "SuiteCommerce Advanced 1.0.0", "version": "1.0.0", "modules": { //... "suitecommerce/SC.CCT.Html": "1.0.0", "suitecommerce/SC.CCT.ImageViewer": "0.0.1", //... SuiteCommerce Site Development Customize and Extend Core SuiteCommerce Advanced Modules 342 3. Define any application dependencies for the desired application (Shopping, My Account, or Checkout), within the javascript object. For the example ImageViewer CCT, you add the module to the SC.Shopping.Starter entry point. //... "javascript": [ { "entryPoint": "SC.Shopping.Starter", "exportFile": "shopping.js", "dependencies": [ "Backbone.View.Plugins", "jQuery.html", "ItemDetails", //... "SC.CCT.Html", "SC.CCT.ImageViwer" ], //... 4. If your CCT includes any Sass, include the module definition in the dependencies array of the desired application (Shopping, My Account, or Checkout) within the sass object. For the example ImageViewer CCT, your code might look similar to the following: //... //... "sass": { //... "applications": [ { "name": "Shopping", "exportFile": "shopping.css", "dependencies": [ { //... "PickupInStore", "Location.SCA", "SC.CCT.ImageViewer" ] 5. Save the distro.json file. 6. If you have not already set your NetSuite records, complete the tasks as defined in Custom Content Type. Important: Creating a custom module is only one step in the process. You must still perform the steps necessary to set up your custom module for use in SMT. 7. Test your custom module in your local environment or deploy to your NetSuite account. See Core SuiteCommerce Advanced Developer Tools for details. Customize the Checkout Application Applies to: SuiteCommerce Advanced Note: The module source files for SuiteCommerce Advanced 2019.1 and earlier are JavaScript files with .js filename extensions. The module source files for SuiteCommerce Advanced 2019.2 and later are TypeScript files with .ts filename extensions. For more information about TypeScript, see TypeScript. Much of the Commerce Checkout application can be customized or configured by editing standard configuration properties and by using existing extensions or creating new extensions. See the help topic Checkout for detailed information and procedures on how to do this. SuiteCommerce Site Development Customize and Extend Core SuiteCommerce Advanced Modules 343 If, however, you need to implement an advanced customization for a SuiteCommerce Advanced solution, you can create custom modules and, using best practices, modify the checkout experience as described in this section of the documentation. See Best Practices for Customizing SuiteCommerce Advanced. Important: Whenever possible, advanced customization should be accomplished by creating new extensions. This allows for easier maintenance, portability, and release independence. Only implement advanced customizations by creating custom modules when the exposed extensibility APIs are not sufficient for your business use case. For details on the extensibility API see the help topic Extensions API, Frontend Extensibility API, and Extensions. By default, several modules are included in each checkout configuration file. Available modules include: ■ OrderWizard.Module.Address.Billing: lets the user add, edit, remove, or choose a billing address. ■ OrderWizard.Module.Address.Shipping: lets the user add, edit, remove, or choose a shipping address. ■ OrderWizard.Module.Confirmation: provides a confirmation message after an order is submitted. ■ OrderWizard.Module.PaymentMethod.Creditcard: lets the user add, edit, remove, or choose a credit card as a payment method. ■ OrderWizard.Module.PaymentMethod.GiftCertificates: lets the user add a gift certificate code as a payment method. ■ OrderWizard.Module.PaymentMethod.Invoice: lets the user select an invoice option as a payment method. ■ OrderWizard.Module.PaymentMethod.PayPal: lets the user select a PayPal account as a payment method. ■ OrderWizard.Module.PaymentMethod.Selector: lets the user select from a list of payment methods. ■ OrderWizard.Module.PaymentMethod.PurchaseNumber: displays a Purchase Order Number field to allow users to search by PO Number. This field will appear independently of the Payment Method selected by the user. ■ OrderWizard.Module.RegisterEmail: gives guests the option of registering an email address. ■ OrderWizard.Module.RegisterGuest: lets the user register with the site as a customer. ■ OrderWizard.Module.Shipmethod: lets the user select a delivery method. ■ OrderWizard.Module.ShowPayments: displays the payment type selected. This is typical of a review page. ■ OrderWizard.Module.ShowShipments: displays the shipment method selected if MultiShipTo is enabled. This is typical of a review page. ■ OrderWizard.Module.TermsAndConditions: creates a Terms and Conditions checkbox during the Review step. If this property is not set, the default is false. To customize the checkout flow: 1. Create a custom module that includes the SC.Checkout.Configuration object as a dependency. Note: Do not edit the SC.Checkout.Configuration.js file directly. See Customize and Extend Core SuiteCommerce Advanced Modules for information and best practices on customizing JavaScript. Note: Do not edit the SC.Checkout.Configuration.js file (or SC.Checkout.Configuration.ts file if you are on SuiteCommerce Advanced 2019.2 or later) directly. See Customize and Extend Core SuiteCommerce Advanced Modules for information and best practices on customizing JavaScript. 2. Redefine the dependency SC.Checkout.Configuration.Steps.Standard to the desired checkout flow as defined below: SuiteCommerce Site Development Customize and Extend Core SuiteCommerce Advanced Modules Checkout Flow Dependency Associated File JavaScript (SCA 2019.1 and Earlier TypeScript (SCA 2019.2 and Later) SC.Checkout.Configuration. Steps.Standard SC.Checkout.Configuration. Steps.Standard.js SC.Checkout.Configuration. Steps.Standard.ts One Page Checkout SC.Checkout.Configuration. Steps.OPC SC.Checkout.Configuration. Steps.OPC.js SC.Checkout.Configuration. Steps.OPC.ts Billing First SC.Checkout.Configuration. Steps.BillingFirst.js SC.Checkout.Configuration. Steps.BillingFirst.ts Standard (Default) SC.Checkout.Configuration. Steps.BillingFirst 3. Extend the checkout flow’s associated .js file to customize the checkout configuration. You can customize checkout in following ways: ■ Reorder Checkout Modules ■ Add Checkout Modules ■ Add or Remove Checkout Steps ■ Configure Checkout Step Properties ■ Define Checkout Step URLs Note: The three checkout configurations shipped with SuiteCommerce Advanced are fully supported by NetSuite. You can create completely customized experiences, but note that advanced customization can create flows that do not make intuitive sense to the user. NetSuite cannot guarantee the outcome of advanced customizations. Reorder Checkout Modules Applies to: SuiteCommerce Advanced You can reorder modules within a checkout step by repositioning the module within the code. SuiteCommerce Site Development 344 Customize and Extend Core SuiteCommerce Advanced Modules 345 Important: If reordering modules, ensure that you do not disrupt any flow between modules. For example, you want to place both the shipping address and delivery method modules within the same step (Shipping Address). However, the delivery methods available depend on the shipping address. This creates a flow issue. To maintain flow consistency in this case, the shipping address module must always precede the delivery method module in a separate step. Be aware of flow inconsistencies that may exist within step or groups when customizing modules. Add Checkout Modules Applies to: SuiteCommerce Advanced You can add modules to steps in multiple-step groups. For example, a guest shopper is prompted to register in the final confirmation step by default. By placing the OrderWizard.Module.RegisterGuest module in multiple steps, you can offer the registration at many points during the checkout process. Each module is designed to use components and naming conventions consistent between the modules. When creating custom modules, we suggest that you follow similar conventions. For example, the RegisterEmail module contains the following components that are common among most other modules: ■ Module definition: named from the most generic component (OrderWizard) to the most specific component (RegisterEmail). define('OrderWizard.Module.RegisterEmail', ['Wizard.Module'], function (WizardModule) ■ Associated Template: this defines the HTML layout for the rendered output. Templates are found in the templates folder of each specific module. template: 'order_wizard_registeremail_module' ■ Render function: the wizard object renders each step sequentially as it is defined in the code. The _render(); function is responsible for displaying the template in the layout. , render: function() { this.profile = this.wizard.options.profile; } // if the user is logged we dont render the module if (this.profile.get('isGuest') !== 'T') { this.trigger('ready', true); } else { this._render(); if (this.profile.get('email') && this.wizard.isPaypalComplete()) { this.trigger('ready', true); } } ■ Submit function: defines the logic performed when the Continue button is clicked. submit: function() { var email = this.$('input[name=email]').val() , newsletter = this.$('input[name=sign-up-newsletter]').is(':checked') , self = this; SuiteCommerce Site Development Customize and Extend Core SuiteCommerce Advanced Modules 346 // if the user is not guest or not change the current values we just resolve the promise if (this.profile.get('isGuest') !== 'T' || (email === this.profile.get('email') && this.profile.get('emailsub scribe') === (newsletter ? 'T' : 'F') )) { return this.isValid(); } this.profile.set('email', email); this.profile.set('confirm_email', email); return this.isValid().then(function() { self.profile.set('emailsubscribe', newsletter); return self.profile.save(); }); } ■ isValid function: defines error checking for entries. isValid: function() { var promise = jQuery.Deferred(); if (this.wizard.options.profile.get('isGuest') !== 'T') { return promise.resolve(); } if (!Backbone.Validation.patterns.email.test(this.wizard.options.profile.get('email'))) { return promise.reject(_('Email is required').translate()); } } return promise.resolve(); Add or Remove Checkout Steps Applies to: SuiteCommerce Advanced Each checkout flow configuration file corresponds to a configured Checkout Flow Option. Each of these files contain multiple groups to achieve a specific task for that flow, such as adding shipping information. These groups contain one or more checkout steps to achieve that task. Each checkout step provides one or more wizard modules to guide the user through the checkout process. Groups define the breadcrumbs available at the top of the page. Checkout steps then provide the modules that guide the shopper through the checkout process. You can add or remove checkout steps to any named group array by adding or removing steps as objects. You can also customize each step by editing properties. For example, the following code snippet in the SC.Checkout.Configuration.Steps.Standard.js file defines the Shipping Address group. This group contains two checkout steps: Choose Shipping Address and Enter Shipping Address. Each checkout step contains three modules. You can customize the Shipping Address group by modifying each step’s code. { , name: _('Shipping Address').translate() steps: [ { , , name: _('Choose Shipping Address').translate() url: 'shipping/address' isActive: function () { return !this.wizard.isMultiShipTo(); SuiteCommerce Site Development Customize and Extend Core SuiteCommerce Advanced Modules } , , 347 } modules: [ OrderWizardModuleMultiShipToEnableLink , OrderWizardModuleAddressShipping , [OrderWizardModuleCartSummary, cart_summary_options] ] { name: _('Enter Shipping Address').translate() url: 'shipping/selectAddress' isActive: function () { return this.wizard.isMultiShipTo(); } , modules: [ [OrderWizardModuleMultiShipToEnableLink, {exclude_on_skip_step: true}] , [OrderWizardModuleMultiShipToSelectAddressesShipping, {edit_addresses_url: 'shipping/selectAddress' }] , [OrderWizardModuleCartSummary, cart_summary_options] ] } , , } ] Configure Checkout Step Properties Applies to: SuiteCommerce Advanced Use the following properties when configuring each checkout step. Set these properties in the applicable Checkout Steps configuration file. ■ name (string): specifies the literal name for the step as it appears in the breadcrumb. ■ getName (function): specifies the dynamic name for the step as it appears in the breadcrumb. If this property is not defined, the default is the name property. ■ url (string): specifies the url for the step. This property is required and must be unique among all steps. ■ continueButtonLabel (string): specifies the label of the Continue button for the step. If not specified, the default is Continue. ■ hideBackButton (boolean): specifies if the Back button appears on the site or not. If set to true, the button is hidden for this step. If not specified, the default is false. ■ hideContinueButton (boolean): specifies if the Continue button appears on the site or not. If set to true, the button is hidden for this step. If not specified, the default is false. ■ hideSecondContinueButtonOnPhone (boolean): specifies if the second Continue button displays on a smart phone or not. If set to true, the button is hidden for this step. If not specified, the default is false. Use this if there are too many Continue buttons in a step, such as the top, bottom and summary buttons). ■ hideSummaryItems (boolean): specifies if the cart summary’s items are shown on this step or not. If set to true, the item is hidden for this step. If not specified, the default is false. ■ hideBreadcrumb (boolean): specifies if the page’s breadcrumb is shown on this step or not. If set to true, the button is breadcrumb for this step. If not specified, the default is false. ■ headerView (string): specifies the main site header defined for the step. If not defined, the simplified header is used. You can define the normal 'header' or a custom one. ■ footerView (string): specifies the main site footer defined for the step. If not defined, the simplified footer is used. You can define the normal ‘footer’ or a custom one. ■ bottomMessage (string): defines a message to display at the bottom of the step above the Continue and Back buttons. If not specified, the default is no message. SuiteCommerce Site Development Customize and Extend Core SuiteCommerce Advanced Modules ■ isActive (function): specifies if the entire step is active (shown) or not, based on one or more conditions. The default implementation returns true. It is not required that all modules are active. ■ save (function): is a custom save function that finishes the wizard and saves the configuration. When used within this module, this property calls the submit function. ■ present (function): lets you customize the step to perform some action, such as trigger Google Analytics tracking. ■ modules (array): defines an array of modules used for the step. Define Checkout Step URLs Applies to: SuiteCommerce Advanced Important: Each step must have a unique URL. This is important for maintaining site navigation, code statelessness, and for effective use of reporting, so you can perform analytics based off of URLs using tools such as Google Analytics. You set each step’s URL property to define the step’s unique URL. SuiteCommerce Site Development 348 Overview 349 Overview Applies to: SuiteCommerce Advanced This section describes the architecture of the Commerce web store framework. You should have a solid understanding of the architecture if you intend to create extensions or introduce other advanced customization for your site. ■ Core Framework Technologies – Commerce web stores use several 3rd party technologies to build the front-end framework. This section provides a general introduction to what is used. ■ Commerce Modules – All of the front-end code is delivered in a collection of modules. This section describes the various types of modules and how they are structured. ■ Product Details Page Architecture – The display of products in your web store is controlled by the product details page. This section provides detailed information on how this page is created and rendered. SuiteCommerce Site Development Core Framework Technologies 350 Core Framework Technologies Applies to: SuiteCommerce Advanced SuiteCommerce Advanced source files are organized in modules. How these modules work together to create Commerce web store applications, you must understand the underlying technologies that the application is built on. To implement these technologies, SuiteCommerce and SuiteCommerce Advanced use several 3rd-party libraries that are common in web-based e-Commerce applications. Note: These topics refer to SuiteCommerce Advanced implementations. SuiteCommerce source also follows this framework; however, customization of SuiteCommerce is accomplished using themes and extensions. Extensions interact with the Extensibility API, and are handled using specific developer tools and practices. For information, see Themes and Extensions. Depending on your implementation of SuiteCommerce Advanced, the application relies on either JavaScript or TypeScript to enhance large project development efficiency and scalability. The 2019.2 release of SCA and later uses TypeScript. To discover more about these technologies, review the following sections: ■ Model View Controller (MVC) and Backbone.js ■ TypeScript ■ Asynchronous Module Definitions (AMD) and RequireJS ■ Logic-less Templates and Handlebars.js Model View Controller (MVC) and Backbone.js Applies to: SuiteCommerce Advanced Source files of each module follow the MVC architectural pattern. One of the core principles of the MVC pattern is to separate the presentation layer (view) of an application from the data (model) used by the application. All interaction between views and models are handled by the controller. To implement the MVC pattern, SuiteCommerce Advanced uses the Backbone.js libraries. Backbone.js is an open source JavaScript library that provides a framework for developing web applications. Structure of a Backbone.js Application Backbone.js is based on the MVC pattern. Modules that define interfaces or handle data use Backbone.js to define routers, views, and models/collections. The Case module, for example, implements each of these: ■ Routers: map URLs to client-side pages to methods that define actions and events. In feature modules, these methods initialize the views, models, and collections that handle the user interface and create frontend objects to handle data. Each router contains a routes object that defines the mapping between URLs and methods. SuiteCommerce Site Development Model View Controller (MVC) and Backbone.js 351 ■ Views: contain methods that define the behavior of the user interface. Views are commonly associated with a model or collection. When a view is initialized, its corresponding model is usually passed. This ensures that the view has access to the data within the model. Most views define listeners that notify the view when an element within the model is modified. This enables a specific part of the application to be updated independently without having to reload the page. With the Elbrus release of SuiteCommerce Advanced and later, all views are composite views by default and extend Backbone.CompositeView.js. Views do not define the HTML or CSS of a feature or component. Instead, they specify the template that defines the HTML code for the component or feature. The templating engine handles the rendering and updating of the HTML. ■ Models and Collections: define objects that contain data used by the application. They also define the methods that create, update, or delete data. Backbone.js Module Example For example, the Case module defines a router (Case.Router.js) that contains the following: routes: { 'cases': 'showCasesList' , 'cases?:options': 'showCasesList' , 'cases/:id': 'showCase' , 'newcase': 'createNewCase' } When a user clicks on an individual case from the list of support cases, instead of sending an HTTP request back to the server, the router calls the showCaseList method based on the value of the partial URL (cases). This method performs two main tasks: ■ Initializes the model that contains data for a specific support case (Case.Model). ■ Initializes the view that displays the data (Case.Detail.View) The Case.Model model defines the data object that contains information about an individual support case. Case.Model extends the Backbone.Model by defining additional methods for performing frontend validation. When the router initializes Case.Detail.View, it passes the instance of Case.Model. SuiteCommerce Advanced Backbone.js Implementation The Backbone.js libraries provide a general framework for how a web application is structured and its general functionality. However, much of the specific functionality of the application must be implemented. SuiteCommerce Advanced stores Backbone.js files in the following directories: ■ Modules/third_parties/backbone.js: contains the core Backbone.js libraries. In general, you should not modify the files in this directory. ■ Modules/suitecommerce/BackboneExtras: contains extensions of core Backbone.js functionality, including Backbone.View and Backbone.Model. If you need to make changes to the Backbone.js framework, you may need to modify the files in this directory. SuiteCommerce Site Development Model View Controller (MVC) and Backbone.js 352 Note: In SuiteCommerce 2020.1 and later, you should use the SuiteCommerce SCCollection and SCModel components instead of the native Backbone.Collection and Backbone.Model. SCCollection and SCModel are components of the SuiteCommerce extensibility API, which extend Backbone.Collection and Backbone.Model respectively. See the extensibility API reference for more information. TypeScript Applies to: SuiteCommerce Advanced SuiteCommerce Advanced core source code continues to transition to TypeScript using a phased migration schedule. TypeScript is an open source superset of JavaScript designed to optimize development efficiency. To learn more about TypeScript, see Typescriptlang.org. Important: Core SuiteCommerce Advanced code is only for core SuiteCommerce Advanced customization. You should continue to use extensions for your code customizations. See Customize and Extend Core SuiteCommerce Advanced Modules. The code migration to TypeScript spans several releases. See the table below for a high-level summary of completed migration tasks. SuiteCommerce Advanced Release TypeScript Migration Phase Tasks 2019.2 ■ Change filename extension from .js to .ts. ■ Transform module system from Asynchronous Module Definition (AMD) to a TypeScript compatible (common JavaScript) system. 2020.1 ■ Implement base class for Models ■ Implement base class for Collection ■ Migrate Utils.ts ■ Migrate Case.Model ■ Migrate Case.Collection TypeScript code compiles to common JavaScript. Gulp tasks performed when running gulp local and gulp deploy commands automatically compile all SuiteCommerce Advanced TypeScript files to JavaScript. JavaScript files ultimately deploy to your NetSuite account. Asynchronous Module Definitions (AMD) and RequireJS Applies to: SuiteCommerce Advanced Although Backbone.js provides a general framework for web applications, it does not specify how application code should be organized. To organize code into modules, SuiteCommerce Advanced implements another design pattern called Asynchronous Module Definitions (AMD). ■ SuiteCommerce Advanced 2019.2 and later uses ECMAScript 2015 standard JavaScript in TypeScript files to define modules and dependencies. These TypeScript files are compiled to JavaScript when SuiteCommerce Site Development Asynchronous Module Definitions (AMD) and RequireJS 353 executing gulp local and gulp deploy commands. During this compile, Asynchronous Module Definitions (AMD) design pattern code is produced. ■ SuiteCommerce Advanced 2019.1 and earlier source code is provided as JavaScript files and implements the Asynchronous Module Definitions (AMD) design pattern. See Dependencies for more information on how modules implement the AMD design pattern. Logic-less Templates and Handlebars.js Applies to: SuiteCommerce Advanced Another advantage of the Backbone.js libraries is that it provides open support for web templates and templating engines. Web templates contain the raw HTML of the user interface. Each module that contains Backbone.js views uses a template to define the corresponding HTML. These files are stored in the Templates directory. Templates define the HTML for discrete areas or features of the user interface. The template engine combines all of the template files into a single, finished web page. SuiteCommerce Advanced uses the Handlebars.js library to implement templates and the template engine. One advantage of Handlebars.js is that it provides logic-less templates. This means that most of the business logic of the application is handled outside of the template. Within the Backbone.js framework, this logic is handled by the view. Using logic-less templates means that the HTML within the template is much easier to understand. Although Handlebars.js is considered a logic-less template it does provide basic logical constructs. These are defined by Handlebars.js helpers. Helpers are primarily used to evaluate values of placeholders and display the appropriate HTML. Placeholders are like variables that contain information that is added to the HTML when the template is generated. This information is passed to the template by the getContext method of a view. The following code snippet from the case_list.tpl template file shows how these are used to display the user interface according to the current state of the application. <div class="case-list-results-container"> {{#if hasCases}} <table class="recordviews-table"> ... ... ... </table> {{else}} {{#if isLoading}} <p class="case-list-empty">{{translate 'Loading...'}}</p> {{else}} <p class="case-list-empty">{{translate 'No cases were found'}}</p> {{/if}} {{/if}} In this example, the Handlebars.js engine evaluates the hasCases placeholder. This place holder corresponds to a property in the object passed to the template engine from the getContext method of the view. hasCases is a boolean property. If its value is true, the template engine outputs a table. If its value is false, the template engines checks the value of the isLoading property which is also passed from the getContext method. The template engine displays a message based on the value of this property. In the above example, the if statement is an example of a default Handlebars.js helper. SuiteCommerce Advanced provides additional helpers that you can use in your templates. See Custom Helpers. SuiteCommerce Site Development Logic-less Templates and Handlebars.js 354 Templates and the Template Context Applies to: SuiteCommerce Advanced SuiteCommerce Advanced uses templates to define the HTML code used to display features of the application. Templates perform the following primary tasks: ■ Define the raw HTML code that displays the user interface of a browser-based application. ■ Contain place holders that are replaced with data passed to the template. Templates are compiled into functional JavaScript and HTML by a templating engine. SuiteCommerce Advanced uses the Handlebars.js library to define templates and the template engine. The template engine performs the following: ■ Transforms the raw template file into a JavaScript function. ■ Replaces place holders based on data passed to the template Logic-less Templates Logic-less templates ensure that the HTML code is separated from Application code. All application logic is handled in the view. For example, when the application needs to access data stored in a model, a view handles this interaction. Logic-less templates make the application more modular and ensure that the source code easier to maintain. More importantly, they ensure that when upgrading to a new version, any template customizations are not broken. Template Compilation The source files for each template contain the raw HTML code as well as Handlebars place holders. When you compile the application, one of the tasks the gulp template command performs is to pre-compile each of the template source files into a JavaScript function. The gulp deploy and gulp local commands call the gulp template command which in turn calls the Handlebars compiler. The result of the gulp template command is that the template is transformed into a JavaScript function that can be called by passing a context object. This function is called when the view is rendered. Within the template file, the Handlebars.js place holders are transformed into JavaScript functions. For example the following if construct: {{#if showLanguages}} Is transformed into the following code when the template is compiled: if(context.showLanguages){} Handlebars.js placeholders that do not contain logic are also transformed into JavaScript functions. For example the following HTML code and placeholder: <p>my name is {{userName}}</p> Is transformed into the following when the template is compiled: function(context){var s = '<p>myname is'; s += context.userName; s += '</p>'; return s; } SuiteCommerce Site Development Logic-less Templates and Handlebars.js 355 Interaction Between Templates and Views Since templates do not contain application code and contain minimal logic, the data they require must be passed to them. When calling, the template method passes the context object. Templates only contain logic for performing loops and conditionals. Views contain all of the logic required to display the contents of a template. Views also contain all of the application logic. To display a template, the view calls the template function from the view.render method. For example, when the application is compiled and running, a view’s render method would contain code similar to the following to access the values contained in context object: var context = this.getContext() body.innerHTML = this.template(context) In this example, the view passes the context object to the template function. The object passed to the template is the object returned by the getContext method. In SuiteCommerce Advanced, almost every view contains a getContext method. In general, this method is responsible for returning a context object that contains all of the data required by the template. This object may contain properties that contain data obtained from the model, configuration properties, or other properties the view requires. Template Context The template's context object returned by the getContext method, can be seen as a contract between the view and the template. The purpose of this contract is to ensure that any customizations you make to the template are not overridden or broken when upgrading to a new version of SuiteCommerce Advance. Any properties within the context object are not removed or modified in future versions. New properties may be added to the context object, but it will always be backward compatible with previous versions. To ensure that this contract is maintained, the template only has access to this context object. The view is responsible for providing the context object and defining and respecting the contract in future versions. Another area where the template context is important is within composite views. For example, you can customize a child view to use a custom template instead of the default template. When customizing an existing template or creating a new one, if you access the properties contained in the context object, these customizations will be preserved after an upgrade. Custom Helpers The Handlebars.js library defines helpers that perform functionality beyond that performed by the default placeholders. Handlebars.js defines multiple default helpers. In addition to these default helpers, SuiteCommerce Advanced defines custom helpers that perform various tasks. These helpers are defined in the HandlebarsExtras.js file located in the JavaScript subdirectory of the HandlebarsExtras application module. The following helpers are defined: ■ translate: returns a safe string that contains a localized version of the string by calling the _.translate function. Returning a safe string ensures that any HTML formatting or other text is preserved. ■ formatCurrency: returns a formatted currency value by calling the formatCurrency function. ■ highlightKeyword: returns a highlighted keyword by calling the _.highlightKeyword function. For example, the site_search_item.tpl template file uses this helper to highlight search results within a page using the following: {{highlightKeyword model._name query}} ■ displayMessage: creates an instance of a GlobalViewsMessageView view and renders the view. SuiteCommerce Site Development Logic-less Templates and Handlebars.js 356 ■ objectToAtrributes: returns the attributes of an object, causing them to be displayed in the template. This helper calls the _.objectToAtrributes method. ■ each: defines a custom each helper that supports a Backbone.js collection. This helper iterates through each item of the collection. ■ resizeImage: builds URL images using the imageSizeMapping utility. This helper passes a URL and an object containing the dimensions of the image to this utility. It returns a normalized URL image based on these values. ■ fixUrl: returns a valid URL by calling the _.fixURL utility. ■ trimHtml: returns a trimmed HTML string based on the length passed to the helper. This helper calls the jQuery.trim method. The string returned can contain HTML elements. ■ breaklines: places break tags (<br/>) instead of new lines provided by the backend. Use this in Quotes, Returns, Case, and Review Order messages. ■ ifEquals: creates an equality condition to a Handlebars {{if}} helper. The following example depicts use for a custom transaction body field: {{#ifEquals model.options.custbody_my_transaction_body_field_2 'T'}} This is true {{else}} This is false {{/ifEquals}} SuiteCommerce Site Development Commerce Modules 357 Commerce Modules Applies to: SuiteCommerce Advanced The source files for SuiteCommerce Advanced are organized in multiple modules. Each module defines a specific area of functionality which generally falls in one of the following categories: ■ Application modules: define higher-level collections of features that perform similar types of functions. SuiteCommerce Advanced is composed of three separate applications: □ Shopping □ Checkout □ My Account ■ Framework modules: define the general logic and structure of SuiteCommerce Advanced and define how modules and applications work together. The application modules extend these modules to inherit the basic framework. ■ Feature modules: define specific areas of functionality within SuiteCommerce Advanced. The Case module, for example contains the code and style sheets that implement Case Management feature. ■ Utility modules: provide functionality that is used by multiple modules. The GlobalViews module, for example, defines views that are reused in multiple areas of SuiteCommerce Advanced. Modules can be edited locally and stored in version control. Developer tools used to compile source files, templates, and style sheets into a deployable application. The SuiteCommerce Advanced Source Directory Applies to: SuiteCommerce Advanced You can download the SuiteCommerce Advanced source files directly from the File Cabinet in NetSuite. The structure of these source files depends on your implementation. The following table describes the files and folders you see when you extract your source files from the NetSuite file cabinet. SC_xxx Advanced Backend Commons DeployDistributionAdvanced DeployDistributionAdvancedSS2 gulp LocalDistributionAdvanced LocalDistributionAdvancedSS2 gulp node_modules File / Folder Description SC_xxx This folder contains the workspace for SuiteCommerce Advanced source code. This folder also contains administrative files necessary to run npm and gulp commands. Note: This folder was named SC_19.2_Live for the 2019.2 release. You execute npm and node commands from this folder location. In this case, xxx refers to the release. For example, SC_20.1. Advanced SuiteCommerce Site Development This folder contains the source code for all of the modules that are used exclusively by SuiteCommerce Advanced. This folder also contains the distro.json file, which lists all of the modules used by The SuiteCommerce Advanced Source Directory 358 the SuiteCommerce Advanced application and the name and version number of the distribution. Backend This folder contains models and service controllers for modules that have been migrated to SuiteScript 2.0. Commons This folder contains the source code for all of all modules that are common to both SuiteCommerce Advanced and SuiteCommerce InStore. DeployDistributionAdvanced This folder contains all of the files associated with the compiled application and any that rely on SuiteScript 1.0. This directory is created when you run the gulp deploy command. When you run the command the compiled application files are output to this directory. After compilation, the contents of this directory are deployed to your NetSuite account. See Contents of the Deploy and Local Distribution Directories for information on the contents of this directory. Important: Do not manually edit the files in this directory. It is created and updated when you run the gulp command. DeployDistributionAdvancedSS2 This folder contains all of the files associated with the compiled application that rely on SuiteScript 2.0. This directory is created when you run the gulp deploy command. See Contents of the Deploy and Local Distribution Directories for information on the contents of this directory. Important: Do not manually edit the files in this directory. It is created and updated when you run the gulp command. LocalDistributionAdvanced Created when you run the gulp local command, this directory contains all of the files associated with the compiled application used by the local server. When you run this command Gulp.js outputs the compiled application files to this directory. After compilation, the contents of this directory are deployed to the local Node.js server. See Contents of the Deploy and Local Distribution Directories for information on the contents of this directory. Important: Do not manually edit the files in this directory. It is created and updated when you run the gulp command. LocalDistributionAdvancedSS2 Created when you run the gulp local command, this directory contains all of the files associated with the compiled application that rely on SuiteScript 2.0 and are used by the local server. When you run this command Gulp.js outputs the compiled application files to this directory. After compilation, the contents of this directory are deployed to the local Node.js server. See Contents of the Deploy and Local Distribution Directories for information on the contents of this directory. SuiteCommerce Site Development The SuiteCommerce Advanced Source Directory 359 Important: Do not manually edit the files in this directory. It is created and updated when you run the gulp command. gulp This folder contains all of the files required by Gulp.js. You should not edit the files within this directory. node_modules This folder stores the dependencies and other files required by Node.js. This directory is created when running the npm install command. .nsdeploy This file defines how Gulp.js connects to your NetSuite account during deployment. This file is created the first time you run the gulp deploy command. distro.json This file, located in the Live directory, lists all of the modules used by the SuiteCommerce Advanced application. It also specifies the name and version number of the distribution. SuiteCommerce Advanced 2019.1 and Earlier File / Folder Description LocalDistribution Created when you run the gulp local command. This directory contains all of the files associated with the compiled application used by the local server. When you run this command Gulp.js outputs the compiled application files to this directory. After compilation, the contents of this directory are deployed to the local Node.js server. See Contents of the Deploy and Local Distribution Directories for information on the contents of this directory. Important: Do not manually edit the files in this directory. It is created and updated when you run the gulp command. DeployDistribution Contains all of the files associated with the compiled application. This file is created when you run the gulp deploy command. When you run the command the compiled application files are output to this directory. After compilation, the contents of this directory are deployed to your NetSuite account. Contents of the Deploy and Local Distribution Directories Important: Do not manually edit the files in this directory. It is created and updated when you run the gulp command. gulp Contains all of the files required by Gulp.js. This file is created when Gulp.js is installed. You should not edit the files within this directory. Modules Contains source code for all of the SuiteCommerce Advanced modules. node_modules Stores the dependencies and other files required by Node.js. This directory is created when running the npm install command. .nsdeploy Defines how Gulp.js connects to your NetSuite account during deployment. This file is created the first time you run the gulp deploy command. distro.json Lists all of the modules used by the SuiteCommerce Advanced application. It also specifies the name and version number of the distribution. SuiteCommerce Site Development The SuiteCommerce Advanced Source Directory gulpfile.js 360 Contains all the JavaScript code for Gulp.js. You should only edit this file if you need to add a new task to Gulp.js . Dependencies Applies to: SuiteCommerce Advanced Every JavaScript file in the SCA source contains the same general structure that corresponds to Asynchronous Module Definition (AMD) API. RequireJS uses the AMD API to asynchronously load modules within the application. The following shows the general structure of each file: define('<module_name>' , [ '<dependency_1>' , '<dependency_2>'. ... ] function ( <module_1> , <module_2> ... ) ) { } <module code> All files within a module contain one define function which occurs at the beginning of the file and uses the following syntax: define(module_id, [dependencies], function) ■ module_id — a string defining the name of the module. ■ dependencies — an array containing the names of the dependencies. In SCA, this is generally the name of a module, a component within a module, or a core dependency. ■ function — defines a function that instantiates the module. By following this structure consistently, the developer tools can compile the application into a single JavaScript file by calculating the cascading dependencies starting with the root level application modules down to each lower-level feature and utility modules. See Core SuiteCommerce Advanced Developer Tools for more information. Application Modules Applies to: SuiteCommerce Advanced SuiteCommerce Advanced is composed of three separate applications: Checkout, My Account, and Shopping. Each of these applications contains its own top-level modules that define the dependencies and general layout. These modules are contained in the following directories: Application Directory Entry Point My Account MyAccountApplication SC.MyAccount.Starter.js SuiteCommerce Site Development Application Modules 361 MyAccountApplication.SCA Checkout CheckoutApplication SC.Checkout.Starter.js Shopping Shopping Application SC.Shopping.Starter.js Each application module contains a starter file which defines the starting node or entry point for each application. The starter file lists all of the dependencies for the application. Any dependencies not listed in this file will not be included in the application. Note: When creating a new module, you must add it to the starter file for each application that uses the new module. See Create a Custom Module for more information. The following image show the hierarchical relationship between the top-level application modules and the lower-level feature modules. Module Architecture Applies to: SuiteCommerce Advanced Most of the modules within SuiteCommerce Advanced define the behavior for a specific feature or related functionality. In contrast to the application and framework modules which define the underlying infrastructure and logic of an application, these modules perform the following: ■ Define the user interface for a feature. ■ Define the low-level application behavior. ■ Define data models. ■ Handle data transfer between the application and NetSuite. SuiteCommerce Site Development Module Architecture Feature modules generally conform to the Model-View-Present (MVP) design paradigm prescribed by Backbone.js. This means that they implement some combination of the following: ■ Routers ■ Views ■ Models ■ Collections Entry Point Applies to: SuiteCommerce Advanced Most feature module contain an entry point which defines how the module interfaces with the top-level application module. The entry point of a module is defined in a file called <module_name>.js. All modules that are dependencies of the application define a method called mountToApp. The ApplicationSkeleton module calls this method for each module listed as a dependency in the starter file of the application. For most modules, the mountToApp method initializes and returns the router for the module, making the module available to the higher-level application context. For modules that are included in the My Account application, the entry point also returns a MenuObject item. This object contains information about the module that the SC.MyAccount node uses to create and display the menu items that appear in My Account. Routers Applies to: SuiteCommerce Advanced Within a single-page application, routers direct URLs to client-side methods rather than passing an HTTP request to the server. All routers contain a routes property that maps between a partial URL and a method defined within the router. Methods within the router perform different functions including initializing views, models, and collections. For example, the Address.Router contains the following routes property: routes: { 'addressbook': 'addressBook' , 'addressbook/new': 'newAddress' , 'addressbook/:id': 'addressDetailed' } When a user clicks on the Address Book menu item in the My Account application, the router of the Address module intercepts the partial URL (addressbook) and calls the addressBook method. The addressBook method is responsible for initializing the collection containing the list of addresses and initializing the view that displays them. Depending on the module, routers may initialize properties and variables required by the module. They may also contain methods that define the behavior and logic of the module. Views Applies to: SuiteCommerce Advanced Within the Backbone.js framework, views listen to the user interface events and coordinate with the data required by the associated module. In some modules, when a router initializes a view, the router SuiteCommerce Site Development 362 Module Architecture 363 also passes a model or collection containing the data required. In other modules, the view includes all necessary models or collections as dependencies. View Architecture This section applies to the Elbrus release of SCA and later. All Backbone.Views are Backbone.CompositeViews by default. Composite views are simply views that contain child views. Composite views further modularize the application, so some types of views can be used in multiple contexts. For example, some modules define Child Views that are extensions of Backbone.View. As a consequence, those Child Views are also Backbone.CompositeViews. This ensures that some types of data are displayed in a consistent way across the application. All views extend Backbone.CompositeView by default. Any custom views should use similar code to the example below: ...js var MyView = Backbone.View.extend({ initialize: function() { //every view now is a composite view! } }); ... A Parent View must declare its Child Views. To do this, each Parent View declares the childViews property, which is an object containing all the Container names from the View (the data-views). Each container has an object with the Child View’s name and an object for each View with the following information: ■ childViewIndex – this is the order in which the children render in that container. ■ childViewConstructor – This can be either functions or Backbone.View subclasses. Each defined function must return an instance of a Backbone.View. The following example declares the childViews property, containing the Buttons container. The Buttons container declares the Wishlist and SaveForLater objects. You can include multiple views in one container. ... childViews: { 'Buttons': { 'Whishlist': { SuiteCommerce Site Development Module Architecture , } } 364 'childViewIndex': 10 'childViewConstructor': function() { return new WhishlistView(); } } 'SaveForLater': { 'childViewIndex': 20 , 'childViewConstructor': SomeView } ... Note: You can add new Child Views to a View class using the addChildViews( ) method. You can also add new Child Views to an instance of a view using the addChildViews( ) method or by passing the childViews property in the options when initializing it. To add a plugin before or after you initialize the View, add the plugin to the View Class and execute code in those moments (beforeInitialize and afterInitialize), as shown below: ... Backbone.View.beforeInitialize.install({ name: 'compositeView' , priority: 1 , execute: function () { var childViews = _.extend({}, this.childViews, this.constructor.childViews); this.childViewInstances = {}; this.addChildViews(childViews); if (this.options) { if (this.options.extraChildViews) { console.warn('DEPRECATED: "options.extraChildViews" is deprecated. Use "options.childViews" instead'); //Add extra child views from view's initialization options } } }); } this.addChildViews(this.options.extraChildViews); if (this.options.extraChildViews) { //Add child views from view's initialization options this.addChildViews(this.options.extraChildViews); } ... Backwards Compatibility To make this change backward compatible with earlier releases of SCA, Backbone.CompositeView.js includes a CompositeView.add() method as a no operation (noop) method. This prevents any errors when calling it from any custom code in implementations prior to Elbrus release. SCA supports the previous format as shown below: ... childViews: { 'Promocode': function() { return new PromocodeView({model: this.model.get('promocode')}); } , 'SomeWidget': SomeWidget SuiteCommerce Site Development Module Architecture 365 } ... In this case, the container and the view name have the same, and you can combine the old and the new format and in the childViews property. ... childViews: { Promocode': { 'Promocode': { childViewIndex: 10 , childViewConstructor: function(options) { return new PromocodeView({model: this.model.get('promocode')}); } } } } ... View Architecture (Vinson Release and Earlier) This section applies to the Vinson release of SCA and earlier. In the Vinson release of SCA and earlier, each view must declare itself as a composite view using the require( ) method and call CompositeView.add(this) within the initialize( ) method. Any custom views should use similar code to the example below: ... var CompositeView = require('Backbone.CompositeView'); var MyView = new backbone.View.extend({ initialize: function() { CompositeView.add(this); //now this view is a composite view! } }); ... Rendering Data From the View The process of rending the HTML is handled by the templating engine and the Backbone.js framework. To work within this framework, each view defines the following: ■ A template file included as a dependency within the define method of the view. ■ A template property defined in the body of the view. SuiteCommerce Site Development Module Architecture 366 ■ A getContext method that returns all of the data attributes required by the template. When you compile SuiteCommerce Advance using the developer tools, Gulp.js uses these elements to compile the templates into the application. See Logic-less Templates and Handlebars.js for more information on templates and the template engine. If implementing the Elbrus release of SCA or later, a data view acts as a container for multiple child views. Any parent view must declare a placeholder element in its associated template to render the children within it as depicted in the following example: ... html ... <div data-view="Buttons"></div> Models, Collections, and Services Applies to: SuiteCommerce Advanced SuiteCommerce Advanced works with data stored in NetSuite. During a shopping session, for example, SuiteCommerce Advance may perform the following data-related actions: ■ Read data from NetSuite records. For example when a user views details about an item, this information is retrieved from the NetSuite item record. ■ Update data based on user input. For example when a user places an order, information about the order is stored in a NetSuite order record. ■ Receive new data based on user input. For example, when a user adds a new address to the Address Book, the NetSuite address record is updated. To retrieve, create, and update data, SuiteCommerce Advanced implements ways of handling the data on the frontend and backend. ■ Frontend: defines how data is presented to the user and how the user inputs data. This data is handled by frontend models and collections. ■ Backend: defines how SuiteCommerce Advanced transfers data to and from NetSuite. This transfer is handled by services and backend models. Frontend Models Applies to: SuiteCommerce Advanced Frontend models contain the data that SuiteCommerce Advanced uses. Frontend models are part of the Backbone.js framework that defines the data component within the MVC paradigm. Each frontend model is an extension of Backbone.Model which is defined in BackboneExtras. Backbone.Model defines inheritable methods that are available to all models defined in SuiteCommerce Advanced. If necessary, a model can override these core methods. For example, many modules override the initialize method to set values of properties that are specific to that model. Most feature modules define models that hold the data they require. There are ways models are defined in SuiteCommerce Advanced: ■ Models that are specific to features are defined by returning an object containing the model. These models are defined using the following syntax: return Backbone.Model.extend SuiteCommerce Site Development Module Architecture 367 ■ Models that are used by the wider application context. These models are crated and their data populated when they are initialized. These models are defined in the following manner: ProfileModel = Backbone.Model.extend By defining a model this way, it can be accessed from models and views that are defined outside of the current module. In this example, the ProfileModel can be access by other modules that need to access information stored in the user’s profile. Most models that are created this way are defined as singletons. These means that there can only be one instance defined per user session. Note: In SuiteCommerce 2020.1 and later, you should use the SuiteCommerce SCModel component instead of Backbone.Model. SCModel is a component of the SuiteCommerce extensibility API. It inherits all methods and properties of Backbone.Model. See the extensibility API reference for more information. When a router or view initializes a model, it may pass properties that the model requires. These can be properties that the frontend model uses internally or properties that are passed to the backend model. In general, frontend models contain code that performs the following: ■ Set initial values of properties. ■ Define model-specific methods. ■ Override default methods. ■ Perform frontend validation of user-submitted data. All frontend modules define the following properties: ■ urlRoot: specifies the backend service that is used to handle HTTP requests. This property is a string containing a partial URL. ■ validation: specifies an object that defines the properties that are validated when a user submits form data. Asynchronous Data Transactions Applies to: SuiteCommerce Advanced When working with data stored in NetSuite or internally within the application, SuiteCommerce Advance often needs to perform tasks asynchronously. Handling tasks asynchronously improves the performance and user experience of SuiteCommerce Advanced. To handle tasks asynchronously, SuiteCommerce Advanced uses the jQuery Deferred Object API. This API provides an easy way of registering callbacks and monitoring the success or failure of data transactions. See https://api.jquery.com/category/deferred-object/ for information on the methods provided by the Deferred Object API. Note: Although there are other mechanisms JavaScript for performing tasks asynchronously, NetSuite recommends that you use jQuery Deferred Objects when customizing or extending SuiteCommerce Advanced. There are two main contexts where SuiteCommerce Advanced uses the Deferred Object API: ■ When performing AJAX calls when using the save(), fetch(), and destroy() methods of a model or collection. ■ When performing tasks asynchronously using promises SuiteCommerce Site Development Module Architecture 368 Using the Deferred Object in AJAX Calls SuiteCommerce Advanced frequently interacts with data stored in NetSuite. To perform a data transaction, code within a Router or View calls a method on the front-end model. This method then makes an AJAX call that sends an HTTP request to the service. In general, this AJAX call needs to be asynchronous since other application code may need to continue processing while the data is loading. The primary reason for using asynchronous AJAX calls is that each browser window operates within a single thread. A synchronous AJAX call will freeze the browser until the AJAX call is complete. One frequent use of the deferred object is to wait until the AJAX call is complete to perform other tasks. The following example from Case.Detail.View shows how the done method is used when saving data to NetSuite: this.model.save().done(function() { self.showContent(); self.showConfirmationMessage(_('Case successfully closed').translate()); jQuery('#reply').val(''); }); In this example, the done method accepcts a single function as an argument. This function calls the showContent() method of the view and performs other tasks. This defers calling the showContent() method until the data transaction initiated by the save method is completed. Using Promises in Asynchronous Data Transfers SuiteCommerce Advanced also uses the Deferred Object API in other contexts where tasks need to be performed asynchronously. In this case, a module explicitly creates an instance of the jQuery.Deferred object. After creating this object the module must ensure that the deferred object is ultimately resolved. This resolution is handled using promises. Promises are part of the jQuery Deferred Object that enable asynchronous data transfers. Promises prevent other methods from interfering with the progress or status of the request. The following code example from the the ProductList.CartSaveForLater.View module shows how a deferred object is created and ultimately resolved: addItemToList: function (product) { var defer = jQuery.Deferred(); if (this.validateGiftCertificate(product)) { var self = this; this.application.ProductListModule.Utils.getSavedForLaterProductList().done(function(pl_json) { if (!pl_json.internalid) { var pl_model = new ProductListModel(pl_json); pl_model.save().done(function (pl_json) { self.doAddItemToList(pl_json.internalid, product, defer); }); } else { self.doAddItemToList(pl_json.internalid, product, defer); } }); SuiteCommerce Site Development Module Architecture 369 } else { defer.resolve(); } } return defer.promise(); Stopping AJAX Requests SuiteCommerce Advanced includes an AjaxRequestsKiller utility module used to stop execution of AJAX requests. Performance is enhanced by stopping AJAX requests that are no longer needed. This module is primarily used in two contexts: ■ URL changes: When a URL change is detected, this module stops execution of all pending AJAX requests that were initiated by another Router or View. Some AJAX requests are initiated without a URL change, for example, the collection.fetch and model.fetch methods. In such cases, you should pass the killerID property to the method as in the following: model.fetch({ killerId: AjaxRequestsKiller.getKillerId() }) ■ Site Search: The SiteSearch module uses the AjaxRequestsKiller module to delete unnecessary AJAX calls when using the type ahead functionality. As a user enters a character in the search field, the SiteSearch module sends an AJAX request to retrieve information from the Item Search API. As the user continues entering characters, additional AJAX requests are sent. Using the AjaxRequestsKiller improves performance be deleting old requests. When the value of the killerID property is reset, this module aborts the AJAX request associated with the old value of the killerID property. It also sets the preventDefault property of the request to true to avoid sending an error to the ErrorHandling module. This module defines the following properties and methods: ■ getKillerId (method): returns an unique ID that identifies the AJAX request. Each time the URL is reset, a new ID is generated. ■ getLambsToBeKilled (method): returns an array of AJAX request IDs to be halted. ■ mountToApp (method): loads the module into the application context. This method performs the following □ Sets the value of the killerID property. □ Pushes the killerID property to an array. □ When the killerID property is reset, calls the abort method on the AJAX request. Collections Applies to: SuiteCommerce Advanced Collections are sets of models. Define the data object that contains the set of models. Define methods that perform actions when the data in a model changes. They can also perform actions on all models within the collection. SuiteCommerce Advanced often uses collections when displaying lists of items. The Case module, for example, uses the Case.Collection to load a list of support cases assigned to a user. The Case.List.View uses the collection to display the list. SuiteCommerce Site Development Module Architecture 370 Note: In SuiteCommerce 2020.1 and later, you should use the SuiteCommerce SCCollection component instead of Backbone.Collection. SCCollection is a component of the SuiteCommerce extensibility API. It inherits all methods and properties of Backbone.Collection. See the extensibility API reference for more information. Services and Backend Models Applies to: SuiteCommerce Advanced To handle data transactions with NetSuite, SuiteCommerce Advanced provides multiple endpoints that enable access to data stored in NetSuite records. How SuiteCommerce Advanced handles these RESTful services depends on your implementation. For details on services architecture when implementing earlier versions of SCA, see Architecture Overview (Pre-Vinson) This section explains the service and backend model architecture for Vinson release of SuiteCommerce Advanced and later. Services handle communication between the frontend SCA application and the backend models that connect to NetSuite. With Vinson release, these (.ss files) are auto-generated and call Service Controllers. These Service Controllers and other files maintain code common to all services within a centralized location, as described below. Note: The Vinson release of SuiteCommerce Advanced is backward-compatible with pre-Vinson services. This requires editing the associated module’s ns.package.json files. See Using Pre-Vinson Services with Vinson Release or Later for more information. Frontend Backend ServiceController.Validations.js SC.EventWrapper.js extend HTTP Request GET POST PUT DELETE ... ServiceController.js Module extend [Module].Service.ss Frontend Model [Module].ServiceController.js JSON Data Backend Model Pre-Vinson Implementation Note: The files and functionality described in this topic apply to the SuiteCommerce Advanced components that are coded in SuiteScript 1.0. This content does not apply to the components that have been migrated to SuiteScript 2.0. When the migration to SuiteScript 2.0 nears completion, more information will be provided for the migrated components. See Commerce Migration to SuiteScript 2.0 for more information about migration progress. The following components make up the backend service architecture: SuiteCommerce Site Development Module Architecture 371 SC.EventWrapper This file contains centralized, extensible Before and After Event listening capabilities plus extension capabilities for use by all service methods. SC.EventWrapper.js is located in the SspLibraries module. ServiceController This file contains the common logic used to operate any service. ServiceController contains the handle() method, which executes the method related to the HTTP requests identified in any [Module].ServiceController. ServiceController.js is located in the SspLibraries module. ServiceController contains the required try/catch block to ensure that any errors are passed back to the frontend application and are handled by the ErrorManagement module. The ServiceController module also extends SC.EventWrapper and references validation methods declared in ServiceController.Validations. Note: As of the 2019.2 release of SCA, all instances that extend ServiceController are located in one of two places. For modules utilizing SuiteScript 2.0, these instances can be found in SC_xxx/Backend/SC/. If customizing using SuiteScript 1.0, these can be found in the SuiteScript folder of the module during development. When you deploy to the server, the specific [Module].ServiceController code writes to the ssp_libraries.js file. [Module].ServiceController One [Module].ServiceController exists per service. This file processes requests for a specific service and extends code within ServiceController. Each [Module].ServiceController executes the proper functions based on the HTTP actions (GET, POST, PUT, DELETE) initiated by the frontend framework, which are passed through the associated .ss file. [Module].ServiceController can also call methods on any necessary backend models. Each [Module].ServiceController can include an options object, which details any permissions and validations needed for the HTTP methods. Each service requires a unique [Module].ServiceController. [Module].Service.ss This file handles communication between the frontend SCA application and the associated controller ([Module].ServiceController). The .ss file is automatically generated in the services folder of the local distribution. After you deploy your site, the .ss file exists in the services folder of the proper SSP Application. One .ss file exists per service. Each [Module].Service.ss file is also responsible for passing data from the backend model to the frontend model or collection that initiated the HTTP request. This data is passed as a JSON object from the backend model to the .ss file via the associated [Module].ServiceController. The following example shows the auto-generated .ss file for the Account Login service. This file only calls the [Model].ServiceController associated with the service as defined in the ns.package.json file. //Autogenerated service function. function service(request, response) { 'use strict'; require('Account.Login.ServiceController').handle(request,response); } SuiteCommerce Site Development Module Architecture 372 Note: When you deploy your site, the autogenerated-services object of the associated module’s ns.package.json file signals the dev tools to auto-generate each .ss file and associate it with a specific service controller. Failure to include this code will result in an error and the .ss file will not generate. If you want to use pre-existing (preVinson) services with a Vinson implementation, you must register the service in the services section of the associated module’s the ns.package.json file. See Using Pre-Vinson Services with Vinson Release or Later for more information. Backend Model The backend model contains methods that access NetSuite records by calling the SuiteScript API. The Backend Model architecture and logic have not changed with the Vinson Release of SuiteCommerce Advanced. ServiceController.Validations.js This file contains the extensible validation methods for requests common to all services. This file is located in the SspLibraries module. Each feature or module in SuiteCommerce Advanced generally defines the services and backend models needed to access the required data. The Cart module, for example, defines the services and backend models for accessing items currently in the cart. Each module’s [Module].ServiceController files and backend models are stored in the JavaScript directory of each module. When you deploy SuiteCommerce Advanced, the gulp tasks auto-generate the required .ss files and deploy all of the services to the SSP application. The gulp tasks also add backend models to the ssp_libraries.js file. See The ssp_libraries.js File for more information. Architecture Overview (Pre-Vinson) Applies to: SuiteCommerce Advanced To handle data transactions with NetSuite, SuiteCommerce Advanced provides multiple endpoints that enable access to data stored in NetSuite records. These endpoints run on NetSuite and are implemented as RESTful APIs. Each endpoint has the following components: Service (request handler) The service (.ss file) handles communication between the frontend SCA application and the backend models that connect to NetSuite. The service receives an HTTP request initiated by the frontend SuiteCommerce Site Development Module Architecture 373 framework, usually a model or collection. Services handle standard HTTP request methods (GET, POST, PUT, DELETE). Based on the HTTP action specified in the request, the service calls methods on the backend model. For example, the ProductLists.Service.ss service returns information about product lists. Since this is a RESTful service, you can access product list information using HTTP methods as follows: ■ HTTP POST — create a new product list. ■ HTTP PUT — update a product list. ■ HTTP DELETE — delete a product list. ■ HTTP GET — perform a search on a product list. This is accomplished by passing search filters as parameters to the service. Services are also responsible for passing data from the backend model to the frontend model or collection that initiated the HTTP request. This data is passed as a JSON object. Backend Model The backend model contains methods that access NetSuite records by calling the SuiteScript API. See the help topic SuiteScript API for more information. Each model defines methods that correspond to the HTTP actions handled by the service. For example, if a model is handling a GET action to retrieve data from NetSuite, it must also format the corresponding JSON object that is return to the frontend framework. Each feature or module in SuiteCommerce Advanced generally defines the services and backend models needed to access the required data. The Cart module, for example, defines the services and backend models for accessing items currently in the cart. Services and backend models are stored in the JavaScript directory of each module. When you deploy SuiteCommerce Advanced, the gulp tasks deploy all of the services to the SSP application. The gulp tasks also add backend models to the ssp_libraries.js file. See The ssp_libraries.js File for more information. Services and Backend Models in Custom Modules Applies to: SuiteCommerce Advanced When creating a custom module to access NetSuite records you must read the following topics. Define a JSON Object to Represent a NetSuite Record Applies to: SuiteCommerce Advanced To use the data in a NetSuite record, you must determine how to represent the record as a JSON object. For example, a custom record containing a set of questions and answers may have the following structure: ■ record name —customrecord_q_and_a ■ custom field —custrecord_q_and_a_queston ■ custom field —custrecord_q_and_a_answer A JSON object representing this custom record would look like the following: { SuiteCommerce Site Development Module Architecture } 374 "question": "A String with the question" "answer": "A String with the answer" "createdAt": "2016-03-31" , , This example only requires name/value pairs representing each custom field and its value. However, depending on the complexity of the record you need to represent, a JSON object can be more complex. For example, a JSON object can contain arrays or nested objects. After defining the formal structure of a JSON object, you can define the backend model that accesses the NetSuite record. See Create a Backend Model for more information. Create a Backend Model Applies to: SuiteCommerce Advanced Backend models handle data transactions with NetSuite using SuiteScript. Note: The following code samples use SuiteScript 1.0 functions and objects only. These examples do not include SuiteScript 2.0 capabilities. define( 'QuestionsAndAnswers.Model' , ['SC.Model', 'Application'] , function (SCModel, Application) { 'use strict'; return SCModel.extend({ name: 'QuestionsAndAnswers' , validation: { question: {required: true, msg: 'The question is required'} } search: function(page) { var filters = [ new nlobjSearchFilter('custrecord_q_and_a_answer', null, 'isnot', '') ] , columns = [ new nlobjSearchColumn('custrecord_q_and_a_queston') , new nlobjSearchColumn('custrecord_q_and_a_answer') , new nlobjSearchColumn('created') ]; } return Application.getPaginatedSearchResults({ record_type: 'customrecord_q_and_a' , filters: filters , columns: columns , page: parseInt(page, 10) || 1 }); create: function(data) { this.validate(data); var question = nlapiCreateRecord('customrecord_q_and_a'); question.setFieldValue('custrecord_q_and_a_queston', data.question); var question_id = nlapiSubmitRecord(question); }); } return data; SuiteCommerce Site Development Module Architecture 375 }); This example demonstrates the following tasks that are common to all backend models. Define Dependencies Like frontend modules, backend models use RequireJS to define dependencies. See Dependencies for more information. All backend models must include the following dependencies: ■ SC.Model — defines the base class for backend models. All backend models should extend this module. ■ Application — provides useful methods, including server-side search helpers. Extend from SC.Model All backend models must return an object that is extended from SC.Model. return SCModel.extend() SC.Model defines the base model which defines core functionality, including validation. Define the Validation Object The validation object defines any validation requirements for the JSON object. validation: { question: {required: true, msg: 'The question is required'} } The Backbone.Validation module uses this object to perform validation. Any validation errors are returned to the frontend appllication via the service. The SC.Model module includes Backbone.Validation as a dependency. In the above example, the required attribute indicates that the question property of the JSON object must have a value. If this property is undefined, the backend model returns the message specified by the msg property. Define Methods to Handle HTTP Actions A backend model must define a method to handle each of the HTTP actions supported by a service. These methods frequently use the SuiteScript API to handle data transactions with NetSuite. For example, the search method in the above example shows how a backend model retrieves data from a NetSuite record: search: function(page) { var filters = [ new nlobjSearchFilter('custrecord_q_and_a_answer', null, 'isnot', '') ] , columns = [ new nlobjSearchColumn('custrecord_q_and_a_queston') , new nlobjSearchColumn('custrecord_q_and_a_answer') , new nlobjSearchColumn('created') ]; return Application.getPaginatedSearchResults({ record_type: 'customrecord_q_and_a' , filters: filters , columns: columns SuiteCommerce Site Development Module Architecture } 376 , page: parseInt(page, 10) || 1 }); In this example, the search method performs the following: ■ Creates an array containing search filters. Each search filter is defined by calling the nlobjSearchFilter method. Since this model is only retrieving data for one record, only one search filter is required. ■ Creates an array for each column of the NetSuite record. In this example, each column corresponds to a property in the JSON object. ■ Calls the getPaginatedSearchResults of the Application module. This method returns a JSON object based on the parameters it receives. This JSON object contains all of the customrecord_q_and_a records in NetSuite. Create a Service to Handle HTTP Requests Applies to: SuiteCommerce Advanced Services handle HTTP requests sent by the frontend application to access backend models, which connect to NetSuite. Different releases of SuiteCommerce Advanced handle services with significant differences. This section explains how to create a service when implementing the Vinson release of SuiteCommerce Advanced or later. ■ 2019.2 implementations and later provide two options: SuiteScript 2.0 or SuiteScript 1.0. How you go about this depends on the services you are creating. These implementations require Service Controllers. Note: The following code samples use SuiteScript 1.0 functions and objects only. These examples do not include SuiteScript 2.0 capabilities. ■ SCA implementations of Vinson through 2019.1 require only SuiteScript 1.0. These implementations require Service Controllers. ■ If using custom services that pre-date the Vinson release of SCA, you can still use them without refactoring your code. SCA offers backward compatibility with any services of implementations prior to Vinson. See Using Pre-Vinson Services with Vinson Release or Later Much of the logic required to operate a service is contained in a centralized location within the source files provided. However, you must still perform the following to create a custom service: ■ Step 1: Create a custom [Module].ServiceController. ■ Step 2: Set up the Dev Tools to auto-generate the service and associate it with a service controller. ■ Step 3: Customize your own validations (optional). Step 1: Create a Custom [Module].ServiceController Each service requires a unique [Module].ServiceController. You create this file, where [Module] is the module using the service. To create this custom ServiceController, perform the following: 1. Create a new [Module].ServiceController file. 2. Define the custom ServiceController and dependencies. 3. Extend ServiceController. 4. Add any custom validation options (optional). 5. Add any HTTP methods as required for the service. SuiteCommerce Site Development Module Architecture 377 6. Define exports. To create a new [Module].ServiceController file: 1. Create a new file titled [Module].ServiceController.js, where [Module] is the module associated with the service. 2. Locate this service controller file in the modules SuiteScript directory. To define your custom [Module].ServiceController and dependencies: 1. In your new [Module].ServiceController, define the specific ServiceController and any dependencies. 2. Include ServiceController as a dependency. How you do this depends on your implementation. The following code defines the Account Login ServiceController and enables the service to access methods defined in ServiceController and Account.Model. // Account.Login.ServiceController.js - Service to handle the login of a user into the system define( 'Account.Login.ServiceController' , [ 'ServiceController' , 'Account.Model' ] , function( ServiceController , AccountModel ) To extend ServiceController: 1. [Module].ServiceController must extend ServiceController and include the name property. This property is used when listening to an event is needed. The value of the name property should match the name of [Module].ServiceController. 2. Use the following example as a guide. This shows this extension with the name property. { 'use strict'; return ServiceController.extend({ name:'Account.Login.ServiceController' To add custom Validation Options (Optional): 1. If you need to define any validation options for the service, include these within return ServiceController.extend. 2. Use the following example as a guide. This defines a requirement for the HTTP protocol to be secure before operating this service. , } options: { common: { requireSecure: true } To add HTTP methods: 1. Within the object returned, define the functions required to handle the HTTP methods for the service. This code reads the HTTP method sent from the frontend (POST, DELETE, GET or PUT). SuiteCommerce Site Development Module Architecture 378 For your [Module].ServiceController to function, you must declare each method in lowercase and it must match the name of the HTTP method being used. 2. Use the following example as a guide. This defines what the service does on a POST request. , post: function() { return AccountModel.login(this.data.email, this.data.password, this.data.redirect) } Using these examples, your custom [Module].ServiceController might look something like this: // Account.Login.ServiceController.js - Service to handle the login of a user into the system define( 'Account.Login.ServiceController' ,[ 'ServiceController' , 'Account.Model' ] ,function( ServiceController , AccountModel ) { 'use strict'; return ServiceController.extend({ name:'Account.Login.ServiceController' , options: { common: { requireSecure: true } } , post: function() { return AccountModel.login(this.data.email, this.data.password, this.data.redirect) } }); } ); Step 2: Set Up the Dev Tools If implementing the Vinson release of SCA or later, the dev tools automatically generates the required .ss service file when you execute gulp deploy. However, you must perform the following to successfully deploy your new services: ■ Include your new [Module].ServiceController in the ssp_libraries.js file. ■ Signal the dev tools to auto-generate your service and associate it with your new Service Controller. To set up your new service controller: 1. You must edit the distro.json file to include your new [Module].ServiceController in the ssp_libraries.js file when you deploy your site. Open the distro.json file in the root directory of the SuiteCommerce Advanced source code. 2. Create a new dependency within the Ssp-libraries object for your new custom Service Controller. For example, Account.Login.ServiceController: "ssp-libraries": { "entryPoint": "SCA", "dependencies": [ "Account.Login.ServiceController", ... SuiteCommerce Site Development Module Architecture } 379 ], 3. Save the distro.json file. To auto-generate your [Module].Service.ss file: 1. You must edit the ns.package.json file of the module associated with the service. This file signals the dev tools to auto-generate your [Module].Service.ss file and associate it with a specific service controller. Open the ns.package.json file located in the module containing your new, custom Service Controller. 2. In the autogenerated-services object, define the new .ss file and associate it with the appropriate Service Controller. , { } "autogenerated-services": "Account.Login.Service.ss" : "Account.Login.ServiceController" Note: The autogenerated-services object may not exist in your implementation. If not, create the object and add the .ss files and Service Controller associations. Each .ss file must associate with one Service Controller. 3. Save the ns.package.json file. 4. Use the dev tools to deploy your services to your site. The dev tools will create Account.Login.Service.ss and associate it with Account.Login.ServiceController.js. Step 3: Set Up Custom Validations (Optional) As an option, you can extend ServiceController.Validations to create any custom validations for your services beyond those included by default. To set up custom validations, perform the following: ■ Create a custom Validations file and add custom validation logic. ■ Edit the distro.json file to include this new file as a dependency. To create a custom Validations file: 1. In the SspLibraries folder, create a new file titled ServiceController.Extend.Validations.js. 2. Define this file and extend ServiceController.Validations. 3. Add your custom validation logic. The following example depicts a typical custom validations file. This file extends ServiceController.Validations and contains custom logic to check validations. define( 'ServiceController.Extend.Validations' , [ 'underscore' , 'ServiceController.Validations' ] , function ( _ , ServiceControllerValidations ) { SuiteCommerce Site Development Module Architecture 380 'use strict'; _.extend(ServiceControllerValidations, { checkValidationGeneric: function() { // validation logic here... } }); }); 4. Set up the options object in any [Module].ServiceController using these validations. For example: , options: { common: { checkValidationGeneric: true } } To set up the dependency in distro.json: 1. Open the distro.json file in the root directory of the SuiteCommerce Advanced source code. 2. Create a new dependency within the Ssp-libraries object for your new custom Service Controller. For example: "ssp-libraries": { "entryPoint": "SCA", "dependencies": [ "ServiceController.Extend.Validations", ... } ], 3. Save the distro.json file and deploy using the dev tools. Create a Service to Handle HTTP Requests (Pre-Vinson) Applies to: SuiteCommerce Advanced The following example shows the required components of a service in pre-Vinson implementations of SuiteCommerce Advanced. function service (request) { 'use strict'; var Application = require('Application'); try { var method = request.getMethod(); var QuestionsAndAnswersModel = require('QuestionsAndAnswers.Model'); switch (method) { case 'GET': var page = request.getParameter('page'); , result = QuestionsAndAnswersModel.search(page); Application.sendContent(result,{'cache': response.CACHE_DURATION_LONG}); break; SuiteCommerce Site Development Module Architecture 381 case 'POST': var data = JSON.parse(request.getBody() || '{}') , result = QuestionsAndAnswersModel.create(data) Application.sendContent(result, {'status': 201}); break; default: } } Application.sendError(methodNotAllowedError); } catch (e) { Application.sendError(e); } To create a custom service for a pre-Vinson implementation of SCA, you must perform the following: ■ Step 1: Create a Reference to the Application Module ■ Step 2: Define a try/catch Block ■ Step 3: Create a Reference to the Backend Model ■ Step 4: Define a Switch Statement to Handle the HTTP Request Step 1: Create a Reference to the Application Module The following code enables the service to access methods defined in the Application module. var Application = require('Application'); The Application module contains HTTP methods the service uses to send data to the frontend application and return any errors. This module is define in the ssp_libraries.js file. See The ssp_libraries.js File. Note: Services in SuiteCommerce Advanced do not include the HTTP response as a parameter. Services return a JSON object using the sendContent method defined in the Application module. Step 2: Define a try/catch Block The body of a service must be included within a try/catch block. This ensures that any errors that occur are handled correctly. These errors are passed back to the frontend application and are handled by the ErrorManagement module. Step 3: Create a Reference to the Backend Model var QuestionsAndAnswersModel = require('QuestionsAndAnswers.Model'); This statement enables the service to call methods defined in the backend model. Step 4: Define a Switch Statement to Handle the HTTP Request The main task of a service is to specify how to handle the HTTP action specified by the request. This is generally performed by a switch statement which contains a case statement for each HTTP method supported by the service. switch (method) { case 'GET': SuiteCommerce Site Development Module Architecture 382 var page = request.getParameter('page'); , result = QuestionsAndAnswersModel.search(page); Application.sendContent(result,{'cache': response.CACHE_DURATION_LONG}); break; case 'POST': var data = JSON.parse(request.getBody() || '{}') , result = ProductReview.create(data) Application.sendContent(result, {'status': 201}); break; default: Application.sendError(methodNotAllowedError); The switch statement also contains a default statement to handle errors related to the HTTP request. This statement returns an error which is sent back to the frontend application and handled by the ErrorManagement module. Using Pre-Vinson Services with Vinson Release or Later Applies to: SuiteCommerce Advanced Services included with SuiteCommerce Advanced prior to the Vinson software release contain all the logic necessary to function with Vinson release and later. The Vinson release of SuiteCommerce Advanced ports existing, unmodified services of previous releases. Therefore, any unmodified services using pre-Vinson architecture will function with Vinson without requiring any changes to the code. However, if you made any customizations to pre-Vinson services, you can still use your existing customizations with the Vinson release of SCA. This requires editing the appropriate ns.package.json file to use the existing service (.ss file). With the Vinson release of SuiteCommerce Advanced, each module’s ns.package.json file contains the autogenerated-services object. This object includes a list of .ss files to automatically generate when you deploy your site plus their associated Service Controllers. The following example displays the ns.package.json file for the Account module: { "gulp": { "javascript": [ "JavaScript/*.js" ] , "ssp-libraries": [ "SuiteScript/*.js" ] , "autogenerated-services": { "Account.ForgotPassword.Service.ss" : "Account.ForgotPassword.ServiceController", "Account.Login.Service.ss" : "Account.Login.ServiceController", "Account.Register.Service.ss" : "Account.Register.ServiceController", "Account.RegisterAsGuest.Service.ss" : "Account.RegisterAsGuest.ServiceController", "Account.ResetPassword.Service.ss" : "Account.ResetPassword.ServiceController" } } } If you have customized any services using pre-Vinson architecture, you can add code to the services array of the appropriate ns.package.json file, forcing the dev tools to use existing .ss files of the same name instead of automatically generating ones. SuiteCommerce Site Development Module Architecture 383 To use pre-Vinson services with Vinson release or later: 1. Open the ns.package.json file located in the module containing the service file you want to use. 2. Add the following code to the file: , "services": [ "SuiteScript/*.ss" ] Note: If a custom service (.ss file) exists in the module that bears the same name as one listed in the autogenerated-services object, this code prevents the dev tools from automatically generating that .ss file. The dev tools will display a warning, informing you that the service will not be automatically generated because of the custom service with the same name. This warning is displayed as information only and does not require any action. 3. Save the ns.package.json file. 4. Use the dev tools to deploy your services to your site. SuiteCommerce Site Development Product Details Page Architecture 384 Product Details Page Architecture Applies to: SuiteCommerce Advanced This section applies to the Elbrus release of SuiteCommerce Advanced and later. The following architecture is not backwards compatible with previous versions of SuiteCommerce Advanced. The product details page (PDP) provides shoppers with detailed information about a product and lets shoppers add items to their cart. To ensure a positive user experience, the PDP needs to create intuitive interactions and return information from the server quickly and efficiently. The architecture of the PDP is designed to accommodate these challenges. Communication of item details is accomplished through the Items and Product modules. This unifies the data structure governing order management. The following diagram details the architecture behind the PDP and how user selections interact with NetSuite. 1. Logic in the Item module retrieves read-only data from NetSuite. Item.Model retrieves data about an item via the Search API. This is a client-side, read-only instance of an item record in NetSuite. Item.Option receives read-only information about an option associated with the item. Item.Option.Collection is a collection of these possible options. Note: The Item.Model is the read-only data from NetSuite used by the Product.Model to validate the user selection. Providing a read-only version of the Item ensures that the original backend data cannot be accidentally overridden. 2. Product.Model contains an Item.Model associated with an item to display in the PDP. Product.Option.Model contains editable instances of the related Item.Option models, and Product.Option.Collection is a collection of these options. 3. The views and child views in the ProductDetails module use the data in the Product module to render the PDP. ProductDetails.Base.View contains the abstract view from which the Full PDP and Quick View views inherit. 4. The views and child views in the ProductViews module use the data in the Product module to render price and item options in the PDP. SuiteCommerce Site Development Product Details Page Architecture 385 Note: To enhance extensibility, SCA uses two different item option templates, one for the PDP and another for search results (Facets). 5. When the user interacts with the PDP to select options, Product.Model validates the data against the Item.Model that each Product.Model contains. This is why the Product.Model contains a Item.Model and why the Item.Model is a client-side representation of the backend record. 6. When the user chooses valid options and clicks Add To Cart, the following conversions occur: ■ Product.Option.Model gets converted into Transaction.Line.Option.Model ■ Product.Option.Collection gets converted to Transaction.Line.Option.Collection ■ Product.Model gets converted into a Transaction.Line.Model The Transaction.Model contains a collection of transaction lines, which each include an item and selected options. Transaction.Line.Option.Model contains one of the selected option, and Transaction.Line.Option.Collection is a collection of all selected options. 7. The ProductLine module contains views that are shared between the PDP, Checkout, and My Account applications. 8. The Transaction module uses views in the Transaction.Line.Views module to render transaction details in the cart and in other modules. Note: Item.KeyMapping.js is part of the Item Module. This file contains mapping definitions of what is returned by the Search API. For example, if you want to set the name of items for data stored in a custom field instead of the default Display Name field, you extend the mapping in the Item.KeyMapping file, as opposed to customizing each instance across the entire code base. Configuration To configure the Product Details Page, you must have the SuiteCommerce Configuration bundle installed. Refer to the correct section for details on configurable properties as described below. To configure the Product Details Page: 1. Select the domain to configure at Setup > SuiteCommerce Advanced > Configuration. 2. In the SuiteCommerce Configuration record, navigate to the Shopping Catalog tab and the appropriate subtab: ■ Item Options Subtab – configure how item options appear in the Product Details Page and in My Account transactions pages. ■ Product Details Information Subtab – configure extra fields to appear on your Product Details Page. ■ Multi-Image Option Subtab – configure multiple images in the Product Details Page based on multiple option selections. 3. Save the SuiteCommerce Configuration record to apply changes to your site. Code Examples Add an Item to the Cart The following example of a custom model adds an item to the cart. Product.Model contains the item via the fetch method. Based on the internal ID of the item, this code then sets the quantity and item options and adds the product to the cart via the LiveOrderModel. define('AddToCart', SuiteCommerce Site Development Product Details Page Architecture [ , 386 'Product.Model' 'LiveOrder.Model' ], function( ProductModel , LiveOrderModel ) { var my_item_internal_id = '40' , quantity = 10 , product = new ProductModel() // load the item. product.getItem().fetch({ data: {id: my_item_internal_id} }).then(function (){ // set quantity product.set('quantity', quantity); // set options product.setOption('option_id', 'value'); // add to cart LiveOrderModel.getInstance().addProduct(product); }); }); Validate an Item for Purchase All shopping, wishlist, and quote item validation is centralized in the Product.Model. You can validate per field and developers can override the default validation per field. The following customization uses a generic areAttributesValid method to validate per field. In this case options and quantity, as opposed to validating the entire set. This method uses a pre-set default validation to validate the specified fields. The generateOptionalExtraValidation method overrides the default validation for the any fields. In this case, quantity. If the values are not valid, the code introduces an alert message. Otherwise, the code adds the product to the cart. Note: The default validation is set in Product.Model.js. define('ValidateAddToCart' , [ 'LiveOrder.Model' ] , function ( LiveOrderModel ) { function generateOptionalExtraValidation() { return { 'quantity': function (){} } } var product = obtainSomeProduct(/*...*/); var cart = LiveOrderModel.getInstance(); if (!product.areAttributesValid(['options','quantity'], this.generateOptionalExtraValidation())) { alert('Invalid Product!') } else { cart.addProduct(product); } }); Add Item to Wishlist The following customization gets new item data from the product and the correct product list. It then adds the product line to the list and alerts the user upon successful validation. SuiteCommerce Site Development Product Details Page Architecture 387 define('ValidateForWishList' , [ 'ProductList.Item.Model' ] , function ( ProductListItemModel ) { var getNewItemData = function (product, productList) { var product_list_line = ProductListItemModel.createFromProduct(product); product_list_line.set('productList', { id: productList.get('internalid') , owner: productList.get('owner').id }); return product_list_line; }; }); var doAddProductToList = function (product, productList, dontShowMessage) { var product_list_line_to_save = getNewItemData(product, productList); product_list_line_to_save.save(null, { validate: false , success: function (product_list_line_to_save_saved) { alert('Product Added!'); } }); }; var product = getSomeProduct(/*...*/) , product_list = getSomeProduct(/*...*/); doAddProductToList(product, product_list); Get Options The following customization returns all valid options for an item or matrix item. It then determines which item options are valid. Only valid options will render as selectable options in the browser. define('ReadProductOptions' , [ 'underscore' ] , function ( _ ) { var showFirstOptionWithValidValues = function (product) { //Collection of product.options var options_to_render = product.get('options'); options_to_render.each(function (option) { //each option is a Model if (option.get('isMatrixDimension')) { var valid_values_for_selected_option = product.getValidValuesForOption(option); _.each(option.get('values'), function (value) { value.set('isAvailable', _.contains(valid_values_for_selected_option, value.get('label'))); }); } }); var first_valid_option = options_to_render.find(function (option) { return _.some(option.get('values'), function (value) { return value.get('isAvailable'); }); }); var selected_option = product.get('options').findWhere({cartOptionId: first_valid_option.get('cartOptionId')}); //Note that we are always backbone Model and the value of the set option contains all details of the set value (label and internalid) SuiteCommerce Site Development Product Details Page Architecture alert('First Option with value values: ' + first_valid_option.get('cartOptionId') + ' set value: ' + selected_op tion.get('value').label) }; showFirstOptionWithValidValues(getSomeIProduct(/*...*/)); }); SuiteCommerce Site Development 388 Overview 389 Overview Applies to: SuiteCommerce Advanced As of the Aconcagua release of SuiteCommerce Advanced, the best practice to update your application is to migrate to the latest release. However, if you are on an earlier version of SCA and wish to manually update your application to fix issues you encounter, you can apply patches as described in this topic. This section also explains how to upgrade your Commerce applications. See the following topics for more information: ■ Patches – The patches in this section provide updates for specific issues with your SuiteCommerce Advanced site. ■ Upgrade SuiteCommerce to SuiteCommerce Advanced – This section explains how to upgrade our site from SuiteCommerce to SuiteCommerce Advanced. ■ Update SuiteCommerce Advanced – This section explains how to migrate your SuiteCommerce Advanced application to the latest release. ■ How Releases and Patches Work – This topic explains the release structure of SuiteCommerce and SuiteCommerce Advanced. SuiteCommerce Site Development Patches 390 Patches Applies to: SuiteCommerce Advanced Patches are documented instructions detailing how to implement a code update by manually customizing core SuiteCommerce Advanced source code. If you are implementing the Kilimanjaro release of SCA or earlier and you do not want to migrate to the latest release of SCA, we provide patching instructions for some issues you may encounter with your implementation. Note: Implementations of SuiteCommerce and the Aconcagua release of SCA and later do not require patching. SuiteCommerce implementations receive updates automatically. The best practice to update SCA (Aconcagua and later) is to migrate to the latest major or minor release. When implementing patches for SuiteCommerce Advanced, refer to the following resources: ■ Patch Instructions provides links to the procedures to follow to resolve particular issues. ■ Patches Overview describes the modes available for patching. Note that review of the detailed steps for each mode is not required before getting started. The individual patch instructions tell you which mode to use and also provide a link to the detailed steps. Patches Overview Applies to: SuiteCommerce Advanced We provide two primary ways to patch SCA: ■ Patch Using Extend Mode ■ Patch Using Override Mode The preferred mode when implementing patches is extend mode. With extend mode, you use the JavaScript prototype function to extend a specific property, object, or method. Extend mode enables you to target the exact item you need to modify so that you don’t have to extend an entire model or view. This mode also helps ensure the customization you implement for a patch continues to work when you migrate to a newer version of SuiteCommerce Advanced. You can patch using override mode if you need to modify a file in a way that cannot be accomplished using extend mode. With override mode, you create a custom module to override a particular file. However, NetSuite best practice is to use extend mode for patches and to use override mode only when absolutely necessary. Patch Using Extend Mode Applies to: SuiteCommerce Advanced If you want to implement a patch that corrects an issue by extending a property, object, or method, follow the steps in this procedure. You can access the instructions for each patch from a list provided in Patch Instructions. Note: Before proceeding, familiarize yourself with Best Practices for Customizing SuiteCommerce Advanced. Step 1: Develop An Extension 1. Create an extensions directory where you can store your custom module. Depending on your implementation, this directory might already exist. SuiteCommerce Site Development Patches Overview 391 ■ If you’re patching SCA 2019.1 and earlier, create the extensions directory in the Modules directory. ■ If you’re patching SCA 2019.2 and later, create the extensions directory in the directory where the module that contains the file you want to extend resides. 2. Within the extensions directory, create a subdirectory with a name similar to the module you need to customize. A good pattern to follow is: .../extensions/<module_name>Extension@<extension_version> For example, If you need to patch the CMSadapter module, name your subdirectory: CMSadapterExtension@1.0.0. 3. Open the custom module subdirectory from the preceding step and create a new subdirectory with a name that reflects the type of file you need to patch. Possible types include: JavaScript, SuiteScript, Configuration, Sass, Template. For example: .../extensions/CMSadapterExtension@1.0.0/JavaScript 4. In the subdirectory from the preceding step, create a file that includes the code needed for your extension. Name this file according to best practices. For example: CMSadapter.Component.Extension.js 5. Open the file and extend the property, object, or method by copy-pasting the code sample included in your patch instructions. 6. Save the file. Step 2: Prepare the Developer Tools For Your Patch 1. Open the custom module directory you created in the first part of this procedure. For example, if you are extending the CMSadapter module, open the CMSadapterExtension@1.0.0 directory. 2. Create a file in the custom module directory named ns.package.json. For example : .../extensions/CMSadapterExtension@1.0.0/ns.package.json 3. Paste the code provided in your patch instructions into the new ns.package.json file. The provided code is specific to the file type for your extension. 4. In the top level of the SuiteCommerce Advanced directory, open the distro.json file. Note: For SuiteCommerce Advanced 2019.2 and later, the distro.json file is located in the Advanced directory. For example: SuiteCommerce Advanced 2019.2/SC_19.2_Live/Advanced/ distro.json. 5. Add your extension to the modules object in the distro.json file. Add your extension to the list of existing values that follow the “modules”: key as shown in the following example. Note: Values for keys in the modules object are release-specific and so the following example may not look exactly like the object in your distro.json file. Be sure to add your module to the list of existing values exactly as shown in the instructions for your patch { "name": "SuiteCommerce Advanced Kilimanjaro", "version": "2.0", "isSCA": true, "buildToolsVersion": "1.3.1", "folders": { "modules": "Modules", "suitecommerceModules": "Modules/suitecommerce", SuiteCommerce Site Development Patches Overview }, 392 "extensionsModules": "Modules/extensions", "thirdPartyModules": "Modules/third_parties", "distribution": "LocalDistribution", "deploy": "DeployDistribution" "modules": { "extensions/CMSadapterExtension": "1.0.0", "extensions/MyExampleCartExtension1": "1.0.0", ... This step ensures that the Gulp tasks include your extension when you deploy. In the preceding example, extensions have been added at the beginning of the list of modules. However, you can add your extension anywhere in the list of existing values. The order of precedence in this list does not matter. 6. You may need to add your custom extension as a dependency to the starters of the required applications. See your patch instructions for details. 7. Save the distro.json file. Step 3: Test and Deploy Your Patch How you test and deploy depends on your patch. ■ If your patch extends a SuiteScript file, deploy the source code to NetSuite to test the functionality. See Deploy to NetSuite for details. SuiteScript files run on the server and must be deployed to NetSuite to take effect. ■ For extensions to file types other than SuiteScript, you can test your source code on a local server or deploy to your NetSuite account. See SCA on a Local Server or Deploy to NetSuite for details. Patch Using Override Mode Applies to: SuiteCommerce Advanced If you want to implement a patch that corrects an issue by overriding a method, follow the steps in this procedure. Remember to use override mode for patches only when you need to modify a file in a way that cannot be accomplished using extend mode. You can access the instructions for each patch from a list provided in Patches. Note: Before proceeding, familiarize yourself with Best Practices for Customizing SuiteCommerce Advanced. Step 1: Create the Override File 1. Create an extensions directory to store your custom module. Depending on your implementation, this directory might already exist. ■ If you’re patching SCA 2019.1 and earlier, create the extensions directory in the Modules directory. ■ If you’re patching SCA 2019.2 and later, create the extensions directory in the directory where the module that contains the file you want to override resides. 2. Within the extensions directory, create a subdirectory with a name similar to the module you need to patch. A good pattern to follow is: .../extensions/<module_name>Extension@<extension_version> For example, if you need to patch the CMSadapter module, name your subdirectory: CMSadapterExtension@1.0.0. SuiteCommerce Site Development Patches Overview 393 3. Open the custom module subdirectory from the preceding step and create a new subdirectory with a name that reflects the type of file you need to override. Possible types include: JavaScript, SuiteScript, Templates. For example: .../extensions/CMSadapterExtension@1.0.0/JavaScript 4. Copy the source file that you want to override and paste it into the JavaScript, Suitescript, or Templates subdirectory from the preceding step. For example, to override the MSadapter.Component.js file in SCA 2018.2, you would: Copy This File: Place the Copy Here: Modules/suitecommerce/CMSadapter@X.Y.Z/JavaScript/ CMSadapter.Component.js Modules/extensions/CMSadapterExtension@1.0.0/ JavaScript In this example, X.Y.Z represents the version of the module in your implementation of SuiteCommerce Advanced. 5. Paste the code provided in your patch instructions into your copy of the source file that you want to override. Make sure you replace the specific blocks or lines of code as instructed. 6. Save the file. Step 2: Prepare the Developer Tools For Your Patch 1. Open the custom module directory you created in the first part of this procedure. For example, if you are patching the CMSadapter module, open the CMSadapterExtension@1.0.0 directory. 2. Create a file in the custom module directory named ns.package.json. For example: .../extensions/CMSadapterExtension@1.0.0/ns.package.json 3. Paste the code provided in your patch instructions into the new ns.package.json file. The code provided for the ns.package.json file is specific to the file that you want to override. 4. In the top level of the SuiteCommerce Advanced directory, open the distro.json file. Note: For SuiteCommerce Advanced 2019.2 and later, the distro.json file is located in the Advanced directory. For example: SuiteCommerce Advanced 2019.2/SC_19.2_Live/Advanced/ distro.json. 5. Add your custom module to the modules object in the distro.json file. Add your custom module to the list of existing values that follow the “modules”: key as shown in the following example. Note: Values for keys in the modules object are release-specific and so the following example may not look exactly like the object in your distro.json file. Be sure to add your module to the list of existing values exactly as shown in the instructions for your patch. { "name": "SuiteCommerce Advanced Kilimanjaro", "version": "2.0", "isSCA": true, "buildToolsVersion": "1.3.1", "folders": { "modules": "Modules", "suitecommerceModules": "Modules/suitecommerce", "extensionsModules": "Modules/extensions", "thirdPartyModules": "Modules/third_parties", "distribution": "LocalDistribution", "deploy": "DeployDistribution" }, "modules": { "extensions/CMSadapterExtension": "1.0.0", SuiteCommerce Site Development Patches Overview 394 "extensions/MyExampleCartExtension1": "1.0.0", ... This step ensures that the Gulp tasks include your module when you deploy. In the preceding example, custom modules have been added at the beginning of the list of modules. However, you can add your custom module anywhere in the list of existing values. The order of precedence in this list does not matter. 6. Save the distro.json file. Step 3: Test and Deploy Your Patch How you test and deploy depends on your patch. ■ If your patch overrides a SuiteScript file, deploy the source code to NetSuite to test the functionality. See Deploy to NetSuite for details. SuiteScript files run on the server and must be deployed to NetSuite to take effect. ■ For overrides to JavaScript files, you can test your source code on a local server or deploy to your NetSuite account. See SCA on a Local Server or Deploy to NetSuite for details. Patch Instructions Applies to: SuiteCommerce Advanced The following table lists available patches for SuiteCommerce Advanced. Click on the issue title for information about how to implement the patch. Issue Release Description CVE-2020-14728: Vulnerability in SuiteCommerce Advanced Services Mont Blanc These patch instructions describe how to protect your site from the risk of Cross-site Scripting (XSS). Vinson Elbrus Kilimanjaro Aconcagua 2018.2 2019.1 2019.2 CVE-2020-14729: Vulnerability in SCA sites prior to SuiteCommerce Advanced Sites 2020.1.4 This patch describes how to add security headers to minimize the risk of interface redressing, also known as clickjacking. Shopping User Environment Experiences Degraded Performance This patch corrects an issue in some implementations of SuiteCommerce Advanced where shopping.user.enivornment.ssp experiences degraded performance. Aconcagua 2018.2 2019.1 2019.2 beforeShowContent Event Stops 2019.1 Working After Initial Trigger 2019.2 SuiteCommerce Site Development This patch corrects an issue in some implementations of SCA 2019.1 and 2019.2 where the beforeShowContentEvent stops working after the initial trigger in these components: ProductListPageComponent and ProductDetailsComponent. Patch Instructions Issue Release Description Filter Site Option Does Not Work Vinson As Expected This patch corrects an issue in some Vinson implementations where site filtering fails to filter out orders for other web stores from the same account. Quantity Facet Displays Dollar Sign This patch corrects an issue in some implementations where adjusting the filter for a quantity facet on your site displays a numerical value that includes a dollar sign. Kilimanjaro Vinson Elbrus 395 Bronto Cart Recovery Link Redirects to Blank Page Kilimanjaro Custom Overrides Not Applying When Deployed 2018.2 This patch corrects an issue where overrides to core SCA source files do not work as expected. Theme Developer Tool Overrides May Cause Error On Activation 2018.2 This patch corrects an issue where overrides implemented using the 2018.2 theme developer tools cause an error on activation. Categories Do Not Display Properly Kilimanjaro This patch corrects a problem where a child category does not display properly. Incorrect Value for Shipping Estimate Occurs in Shopping Cart Elbrus This patch corrects a problem in some Elbrus implementations where the shipping estimate contains incorrect values before the actual value is shown. Standard Promotion with Inline Discount and Rate as Percentage Not Updating the Amount in Checkout Vinson This patch corrects a problem in some Vinson, Mont Blanc, and Denali implementations where the amount in checkout does not update when applying a standard promotion with an inline discount and setting rate as percentage. Page With URL Fragments Redirects Too Many Times Elbrus See Complete List of Stores Link on Store Locator Page Does Not Show Store List Kilimanjaro Elbrus Mont Blanc Denali Kilimanjaro Vinson This patch corrects a problem in some Kilimanjaro and Elbrus implementations where the Bronto cart recovery link redirects to a blank page. This patch corrects a problem where a page with one or more URL fragments that return an ERR_TOO_MANY_REDIRECTS instead of showing a 404 error or the Product Details page. This patch corrects a problem where the See Complete List of Stores link on the Store Locator page reloads the page but does not show the complete list of stores. Elbrus Quantity Pricing Displayed in Web Store Even When “Require Login for Pricing” is Enabled Kilimanjaro Vinson This patch corrects a problem where quantity pricing displays in the web store even when Require Login for Pricing is enabled. Elbrus Edited Shipping Address on the Review Your Order Page is Not Showing Changes Aconcagua Custom Page Title in SMT Does Not Display Correctly Aconcagua This patch corrects a problem where creating a title for a custom facets page with Site Management Tools does not display the correct title. Currencies Change to the Default in the Shopping Application Kilimanjaro This patch corrects a problem where customers using multi-subsidiaries experience currencies not changing in the webstore, which continues to use the default currency. Kilimanjaro SuiteCommerce Site Development This patch corrects a problem where the Review Your Order page is not showing changes when user edits the shipping address. Patch Instructions Issue Release Description Order Confirmation Page Not Displayed When Using Single Page Checkout and External Payment Elbrus This patch corrects a problem where the order confirmation page is not displayed when using single page checkout and an external payment method. Incorrect Discounted Amounts on Checkout Summary Aconcagua Vinson Kilimanjaro Elbrus This patch corrects a problem where Checkout Summary pages display incorrect discounted sub-total amounts and inconsistent strike-through and original amounts. DeployDistribution Folder Does Not Include Local Files Aconcagua R2 This patch corrects a problem preventing local files to deploy to the DeployDistribution folder. HTML List Styles Do Not Display Aconcagua This patch corrects a problem where editing item descriptions on an Item record using <li> and <ul> styles does not display as expected in the webstore. Kilimanjaro 396 Elbrus Vinson Some SuiteCommerce Themes Item Search Displays Incorrect Results Elbrus This patch corrects a problem where the application returns incorrect results when entering more than one search term in the item search criteria. Category Product Lists Return Page Not Found 2018.2 This patch corrects a problem in some implementations that results in a Page Not Found error, instead of returning Commerce Categories based on filtered facet values. Cannot Test an Extension on a Local Server 2018.2 This patch corrects a problem in some implementations that prevents developers from testing extensions locally. Secure Shopping for Site Builder Site Builder Extensions Implementations Premium Vinson Site Builder Extensions Vinson This patch allows some Site Builder customers to secure the shopping portion of a web store under an HTTPS domain. Reference Checkout 2.05 Reference Checkout 2.04 Reference My Account Premium 1.06 Reference My Account 1.06 Reference My Account Premium 1.05 Reference My Account 1.05 Cannot Scroll Through Long Menu Lists Using iOS Kilimanjaro, Elbrus, Vinson, Mont Blanc, and Denali SuiteCommerce Site Development This patch corrects a potential issue where iOS users cannot scroll through a long list of menu items when the list reaches beyond the device screen. Patch Instructions 397 Issue Release Description Pages Not Indexed Using Google’s Mobile-First Indexing 2018.2, Aconcagua, Kilimanjaro, Elbrus, Vinson, Mont Blanc, and Denali This patch corrects a problem in which search engines discard content and do not render the page correctly using mobile-first indexing. Disabling Display of SuiteCommerce Gift Wrap & Message Extension Transaction Line Fields SuiteCommerce This section provides procedures for disabling the display of Gift Wrap & Message extension transaction line item fields. Site Builder Websites Reference ShopFlow Reference Checkout Reference My Account Users Not Redirected to External Vinson Payment System This patch corrects an error where SuiteCommerce Advanced does not correctly send a user to an external payment system. Invoices Do Not Include the Request for a Return Button Vinson For Reference My Account v1.06, this patch adds the Request for a Return Button to Invoice records in My Account. Unable to Select Item Options Within the SuiteCommerce Configuration Record in NetSuite Elbrus This patch corrects an issue where site administrators cannot choose item options when configuring a domain using the SuiteCommerce Configuration record in NetSuite. Incorrect Redirect URL for External Payments Elbrus This patch corrects an error where the page for an external payment system fails to properly redirect back to the SuiteCommerce site from which it was launched. npm Error on Implementations Denali R2 Vinson This patch corrects an issue where npm install fails to run on Denali R2. Content Appears Incorrectly in a Elbrus Merchandising Zone Kilimanjaro This patch corrects an error when content incorrectly shows up in a merchandizing zone. Reference My Account Generates Error on Load Reference My Account version 1.04 This patch corrects an error where My Account fails to load if there are 1000+ invoices associated for that account. Error Loading Shopping Page Due to Uncaught TypeError Elbrus This patch corrects an error where SuiteCommerce could not correctly parse the percent sign (%) in a URL. Users Redirected to Checkout Application Instead of Shopping Application Elbrus and Kilimanjaro This patch corrects an issue where users in a password protected site were redirected to the Checkout application instead of the Shopping application. Add to Cart Button Does Not Work If Quality Field Selected Elbrus This patch corrects an issue where the Add to Cart button requires two clicks if the focus is on the Quality field. URLs with Redundant Facets Generated Elbrus This patch corrects an issue where URLs contain redundant facets. Content Flickers or Disappears When Browsing the Product Listing Page Kilimanjaro and earlier This patch corrects an error that occurs when the product listing page flickers or disappears, for content added in SMT. Enabling Google AdWords Causes Error on Login Vinson This patch contains a fix for an error that occurs when Google AdWords is enabled. SuiteCommerce Site Development Patch Instructions Issue Release Description URL for Commerce Categories Contains Incorrect Delimiters Elbrus and earlier This patch contains a fix for URLs to commerce categories that contain incorrect delimeters. Order Summary for Item-Based Promotions Elbrus and earlier This patch corrects an issue where the item totals for item-based promotions in the Order Summary are incorrect. 398 CSS Error Hides First div Element Mont Blanc and Vinson on Product Details Page This patch contains a fix for a CSS error that hides the first div element on the product details page. This div typically includes the product description. Invoice Terms Not Included In Order Details pre-Denali This patch corrects an issue in Reference My Account v1.05 where the order in My Account does not include the invoice terms. Users Required to Re-enter Credit Card Payment Method Details on Payment Page Elbrus and Kilimanjaro This patch corrects an issue where users are required to re-enter credit card payment method details to successfully complete their order. Selected Invoice Not Displayed When Making an Invoice Payment Mont Blanc This patch corrects an issue where an invoice selected for payment does not appear on the Make a Payment page. Log In to See Prices Message Appears When Users are Logged In Elbrus This patch corrects an issue where logged-in users receive a message directing them to log in to see prices. Item Record HTML Meta Data Not Appearing on Page Meta Data Elbrus This patch corrects an issue where the value of an Item record’s Meta Tag HTML field does not appear in the page’s meta data. Delivery Options Not Appearing After Editing the Cart and Reentering a Shipping Address SiteBuilder Extensions — This patch corrects an issue on Site Builder Extensions Elbrus where delivery methods do not appear after editing cart and re-entering the same shipping address. Order Confirmation and Thank You Page is Blank Mont Blanc and Vinson This patch corrects an issue where a Thank You page is not displayed after an order is complete. Matrix Item Options Not Displaying With Google Tag Manager Enabled Elbrus This patch corrects an issue where not all selected options of a matrix item appear in the Product Details Page. This issue only applies to sites implementing Google Tag Manager. Delivery Methods Not Appearing Mont Blanc, Vinson, in One Page Checkout Elbrus This patch corrects an issue where not all delivery methods appear in the One Page Checkout flow after adding a zip code and checking out as a guest. Mastercard 2-Series BIN Regex Patch Denali, Mont Blanc, Vinson This patch is required to include the Mastercard 2–Series BIN regex value for payment method configuration as of the Elbrus release of SuiteCommerce Advanced. Auto-Apply Promotions for Elbrus Elbrus This patch is required for Elbrus to take advantage of the auto-apply promotions features available as of the Kilimanjaro release of SuiteCommerce Advanced. Change Email Address Patch Denali, Mont Blanc, Vinson, Elbrus This patch is required to take advantage of the change email address feature available as of the Kilimanjaro release of SuiteCommerce Advanced. SuiteCommerce Site Development Patch Instructions 399 Issue Release Description Duplicate Product Lists in Internet Explorer 11 pre-Denali Provides instructions on how to modify the ProductList.js file in ShopFlow 1.07 to correct an issue where IE 11 caching causes duplicate Product Lists to display in My Account. Save for Later Item not Moved to Cart Mont Blanc This patch corrects an issue where an error is returned when users set an item as Save for Later and then return to move that item to the cart. Running Gulp Commands Results in a Syntax Error Vinson and earlier This patch corrects an issue where running gulp commands from a command line or terminal results in a syntax error. Missing Promo Code on Return Request Mont Blanc This patch corrects an issue where promo codes applied to the original sales order are not included in the calculations for a return request. Enhanced Page Content Disappears when Resizing the Browser Denali, Mont Blanc, Vinson, Elbrus This patch corrects an issue where enhanced pages do not maintain content when dynamically resizing the browser window. Invoices Page Displays Incorrect Date Sort (pre-Denali) pre-Denali This patch corrects an issue in Reference My Account v1.05, where invoices are displayed out of order. PayPal Payments Cause Error at Checkout Mont Blanc This patch extends the past() method in the OrderWizard.Module.PaymentMethod.PayPal.js file to correct cases where an error message is displayed when orders are placed using PayPal. Canonical Tags Populated With Relative Paths Vinson This patch modifies commerce category canonical URLs to use absolute paths. Shopping Cart Not Scrolling (Mobile) Vinson and earlier This patch corrects a situation where mobile users cannot scroll their Cart after removing an item from the Saved for Later product list. Follow these instructions to extend the ProductList.DetailsLater.View.js file and override the existing Query.scPush.js file with a new one (provided). Error When Adding Items to Categories in Site Management Tools Vinson This patch contains a fix for an error on a category or subcategory that contains more than 10 items in Site Management Tools. Item Search API Response Data not Cached Vinson This patch extends the getSearchApiParams() method in the Session module to include the pricelevel parameter. This is required to enable caching of the Item Search API Response data. SearchApiCdnCache.zip Secure Shopping Domains (Elbrus, Vinson, Mont Blanc, and Denali) Elbrus, Vinson, Mont Blanc, and Denali SuiteCommerce Site Development This patch enables you to configure your site to maintain a secure browser. The patch for the Denali release of SuiteCommerce Advanced also includes a fix to maintain the identity of the user and cart contents as described in Serversync Touchpoint. Patch Instructions Issue Release 400 Description Note: The original patches provided for this fix have been updated. If you have previously applied a patch for SSL, only the diff between the previous patch and the current one should be applied. Vinson-ssl-V2.patch MontBlanc-ssl-V2.patch Denali-ssl-V2.patch Elbrus-ssl.patch Secure Shopping Domain (preDenali) pre-Denali This section guides you through changes required for you to configure your pre-Denali site to maintain a secure browser. PayPal Address not Retained in Customer Record. Vinson and earlier Provides instructions to retain PayPal Address details in the NetSuite customer record. Login Email Address Appears in the Password Reset URL Elbrus This patch corrects a security issue in which the password reset email message includes the original login email address in the password reset URL. CVE-2020-14728: Vulnerability in SuiteCommerce Advanced Services Applies to: SuiteCommerce Advanced | Mont Blanc | Vinson | Elbrus | Kilimanjaro | Aconcagua | 2018.2 | 2019.1 | 2019.2 Cross-site Scripting (XSS) is a technique where malicious scripts may be injected into your website. Several versions of SuiteCommerce Advanced (SCA) may be vulnerable to CVE-2020-14728. These patch instructions describe how to protect your site from this vulnerability. To implement this patch, create a custom module to override the appropriate file for your release within the SspLibraries module. The following table lists the appropriate file for each release. The location of the file that you need to override depends on the SCA release that you need to patch: Montblanc .../Modules/suitecommerce/SspLibraries@2.2.0/SuiteScript/Application.js Vinson .../Modules/suitecommerce/SspLibraries@3.0.0/SuiteScript/ServiceController.js Elbrus .../Modules/suitecommerce/SspLibraries@4.0.0/SuiteScript/ServiceController.js Kilimanjaro .../Modules/suitecommerce/SspLibraries@4.2.0/SuiteScript/ServiceController.js Aconcagua .../Modules/suitecommerce/SspLibraries@aconcaguaR2/SuiteScript/ServiceController.js 2018.2 .../Modules/suitecommerce/SspLibraries@sc-2018.2.0/SuiteScript/ServiceController.js 2019.1 .../Modules/suitecommerce/SspLibraries@sc-2019.1.0/SuiteScript/ServiceController.js 2019.2 .../SC_19.2_Live/Commons/SspLibraries/SuiteScript/ServiceController.js If you are not familiar with implementing patches for SCA, refer to the following: SuiteCommerce Site Development Patch Instructions 401 ■ Before you get started, familiarize yourself with Best Practices for Customizing SuiteCommerce Advanced. ■ For step by step instructions, refer to Patch Using Override Mode. Step 1: Create the Override File Following the instructions and recommendations in the Patch Using Override Mode procedure, copy and paste the following code sample in the new directory and file you create. Where you create the new directory and file depends on the SCA release that you need to patch: Montblanc .../Modules/extensions/SspLibrariesExtension@1.00/SuiteScript/Application.js Vinson, Elbrus, Kilimanjaro, Aconcagua, 2018.2, and 2019.1 .../Modules/extensions/SspLibrariesExtension@1.00/SuiteScript/ ServiceController.js 2019.2 .../SC_19.2_Live/Commons/extensions/SspLibrariesExtension@1.00/SuiteScript/ ServiceController.js Note: If you are patching 2019.2, you also need to complete the steps in Additional Edits for the 2019.2 Release. ■ In the Application.js file in the Montblanc release and the ServiceController.js file in all other releases, find the following lines of code in the processError method: var content = { errorStatusCode: parseInt(status,10).toString() , errorCode: code , errorMessage: message } And replace them with the following code: var content = { errorStatusCode: parseInt(status, 10).toString(), errorCode: code, errorMessage: _.escape(message) }; ■ In the ServiceController.js file in the 2019.2 release, find the following lines of code in the processError method: var content = { errorStatusCode: parseInt(status,10).toString(), errorCode: code, errorMessage: message }; And replace them with the following code: var content = { errorStatusCode: parseInt(status, 10).toString(), errorCode: code, errorMessage: _.escape(message) }; Additional Edits for the 2019.2 Release For the 2019.2 release, you also need to directly edit the ServiceController.ts file in the following directory: .../SC_19.2_Live/Backend/Libraries/SspLibraries SuiteCommerce Site Development Patch Instructions 402 1. Find the following lines of code in the ServiceController.ts file: const content = { errorStatusCode: status.toString(), errorCode: code, errorMessage: message, errorDetails: null, errorMessageParams: null }; 2. And replace them with the following code: const content = { errorStatusCode: status.toString(), errorCode: code, errorMessage: _.escape(message), errorDetails: null, errorMessageParams: null }; 3. Save the ServiceController.ts file and then continue with Step 2: Prepare the Developer Tools For Your Patch. Step 2: Prepare the Developer Tools For Your Patch When preparing the Developer Tools for your patch as described in the Patch Using Override Mode procedure, you should: 1. Paste the code appropriate for the SCA release you are patching into a new ns.package.json file that you create. Where you create the ns.package.json file depends upon the release you are working with. Montblanc, Vinson, Elbrus, Kilimanjaro, Aconcagua, 2018.2, and 2019.1 .../Modules/extensions/SspLibrariesExtension@1.00/ns.package.json 2019.2 .../SC_19.2_Live/Commons/extensions/SspLibrariesExtension@1.00/ ns.package.json ■ Use the following code if you are patching the Montblanc release: { } "gulp": { "ssp-libraries": [ "SuiteScript/*.js" ] }, "overrides": { "suitecommerce/SspLibraries@2.2.0/SuiteScript/Application.js" : "SuiteScript/Application.js" } ■ Use the following code if you are patching the Vinson, Elbrus, Kilimanjaro, Aconcagua, 2018.2, or 2019.1 release: { } "gulp": { "ssp-libraries": [ "SuiteScript/*.js" ] }, "overrides": { "suitecommerce/SspLibraries@X.Y.Z/SuiteScript/ServiceController.js" : "SuiteScript/ServiceController.js" } SuiteCommerce Site Development Patch Instructions 403 Important: In the preceding code sample, you must replace the string X.Y.Z with the version of the module in your implementation of SuiteCommerce Advanced. ■ Use the following code if you are patching the 2019.2 release: { } "gulp": { "ssp-libraries": [ "SuiteScript/*.js" ] }, "overrides": { "suitecommerce/SspLibraries/SuiteScript/ServiceController.js" : "SuiteScript/ServiceController.js" } 2. Open the distro.json file and then add your custom module to the modules object as described in the Patch Using Override Mode procedure. The location of the distro.json file depends on the version of SCA you are patching. Montblanc, Vinson, Elbrus, Kilimanjaro, Aconcagua, 2018.2, and 2019.1 For these releases, the distro.json file resides in the top-level directory. For example, for the 2018.2 release, if you accepted the default directory name for your release, the top-level directory would be SuiteCommerce Advanced 2018.2. 2019.2 For this release, the distro.json file resides in the SC_19.2_Live/Advanced directory. If you accepted the default name for the top-level directory, the complete path is: SuiteCommerce Advanced 2019.2/SC_19.2_Live/Advanced/distro.json. The following sample shows the value to add to the list of existing values that follow the “modules” key. Refer to the appropriate sample for the version of SCA you are working with. ■ Use the following sample if you are patching the Montblanc, Vinson, Elbrus, Kilimanjaro, Aconcagua, 2018.2, or 2019.1 release: "modules": { "extensions/SspLibrariesExtension": "1.0.0", . . . ■ Use the following sample if you are patching the 2019.2 release: "modules": { "extensions/SspLibrariesExtension", . . . Step 3: Test and Deploy Your Patch Follow the instructions provided in the Patch Using Override Mode procedure to test and deploy your patch. CVE-2020-14729: Vulnerability in SuiteCommerce Advanced Sites Applies to: SuiteCommerce Advanced You can set X-Frame-Options (XFO) and Content-Security-Policy (CSP) HTTP headers to ensure SuiteCommerce Advanced (SCA) sites prior to 2020.1.4 cannot be framed by any other site or origin. SuiteCommerce Site Development Patch Instructions 404 These patch instructions describe how to add these HTTP security headers to help prevent any potential security risks. Note: XFO is being deprecated by most modern browsers in favor of CSP. But some browsers, such as versions of Internet Explorer that predate Edge, still do not support CSP. These patch instructions include both types of security headers to help minimize security risks on all browsers. To learn more about these security headers and the options available with them, refer to the following resources: ■ https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options ■ https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP To implement this patch, choose from the following options and then refer to the instructions for that option. Your site does not need to be framed by any other site/origin Framing Not Required Your site needs to be framed by Framing by a Single Site/Origin another single site/origin Your site needs to be framed by Framing by Multiple Sites/Origins multiple sites/origins Note: X-Frame-Options (XFO) do not support multiple sites/origins, so these instructions include only the Content-Security-Policy (CSP) header. Your site needs to be framed by Framing by any Site any site/origin SSP Files These patch instructions require that you add headers to the SSP files in your local SCA directory. Where the SSP files are stored depends on the release of SCA that you have installed. To locate all required files, you can search your SCA directory using a placeholder. For example: *.ssp Current SCA installations will include the following .ssp files, while older versions may not include all of these files: ■ shopping.ssp ■ checkout.ssp ■ my_account.ssp ■ challengeShopperForm.ssp ■ deviceAuthenticationForm.ssp ■ threedsecure.ssp ■ external_payment.ssp ■ download.ssp ■ print-statement.ssp ■ goToCart.ssp ■ logOut.ssp ■ redirections.ssp ■ searchApi.ssp ■ index-local.ssp (Each application includes an index-local.spp file.) SuiteCommerce Site Development Patch Instructions 405 ■ shopping-local.ssp, checkout-local.ssp, ... (When you compile local SCA source by running gulp deploy, SCA generates these files in the DeployDistribution directory.) Framing Not Required If your site does not need to be framed by any other site, add the following lines to all SSP files in your local SCA directory. For example, shopping.ssp, checkout.spp, and so on. For more information about the files to update, see SSP Files. 1. At the very top of each .ssp file, copy and paste the following lines to set the headers. Make sure to add these lines inside a <% block as shown in the following code. Important: These lines allow your site to be framed only by itself, which is required to ensure that Site Management Tools (SMT) continue to function properly. <% response.addHeader('X-Frame-Options', 'SAMEORIGIN'); response.addHeader('Content-Security-Policy', 'frame-ancestors \'self\''); %> 2. After adding the headers, deploy the updated source files. See Deploy to NetSuite for details. Framing by a Single Site/Origin If your site does need to be framed by another single site, add the following lines to all SSP files in your local SCA directory. For example, shopping.ssp, checkout.spp, and so on. For more information about the files to update, see SSP Files. 1. At the very top of each .ssp file, copy and paste the following lines to set the headers. Make sure to: ■ Add these lines inside a <% block as shown in the following code. ■ Change tempdomain.com in the URL on each of these lines to the domain for the single site that is allowed to frame your site. Note that the URL for the allowed site must include http:// or https://. <% response.addHeader('X-Frame-Options', 'ALLOW-FROM http://tempdomain.com'); response.addHeader('Content-Security-Policy', 'frame-ancestors http://tempdomain.com'); %> 2. After adding the headers, deploy the updated source files. See Deploy to NetSuite for details. Framing by Multiple Sites/Origins If your site needs to be framed by multiple sites, add the following line to all SSP files in your local SCA directory. For example, shopping.ssp, checkout.spp, and so on. For more information about the files to update, see SSP Files. Note: X-Frame-Options (XFO) do not support multiple sites/origins, so these instructions include only the Content-Security-Policy (CSP) header. 1. At the very top of each .ssp file, copy and paste the following line to set the header. Make sure to: ■ Add this line inside a <% block as shown in the following code. ■ Include your own site as shown in the following code to ensure that Site Management Tools (SMT) continue to function properly. SuiteCommerce Site Development Patch Instructions 406 ■ Change tempdomain.com in the URLs to the domains for the sites that are allowed to frame your site. <% response.addHeader('Content-Security-Policy', 'frame-ancestors \'self\' http://tempdomain1.com http://tempdomain2.com'); %> 2. After adding the header, deploy the updated source files. See Deploy to NetSuite for details. Framing by any Site If you don’t want to restrict framing and want any site to be able to frame your site, you do not need to make any changes. Important: Allowing your site to be framed by any other site by omitting security headers makes your site vulnerable to clickjacking attacks. Shopping User Environment Experiences Degraded Performance Applies to: SuiteCommerce Advanced | Aconcagua | 2018.2 | 2019.1 | 2019.2 In some implementations of SuiteCommerce Advanced (SCA), shopping.user.enivornment.ssp experiences degraded performance. For example, time to first byte (TTFB) may increase from less than 500 milliseconds to 2 seconds. These patch instructions describe how to correct this problem. To implement this patch, create a custom module to override the shopping.ssp file, which is part of the ShoppingApplication module. The location of this file depends on the SCA release that you need to patch: Aconcagua SuiteCommerce Advanced Aconcagua/Modules/suitecommerce/ShoppingApplication@aconcaguaR2/ SuiteScript/shopping.ssp 2018.2 SuiteCommerce Advanced 2018.2.0/Modules/suitecommerce/ShoppingApplication@sc-2018.2.0/SuiteScript/ shopping.ssp 2019.1 SuiteCommerce Advanced 2019.1/Modules/suitecommerce/ShoppingApplication@sc-2019.1.0/SuiteScript/ shopping.ssp 2019.2 SuiteCommerce Advanced 2019.2/SC_19.2_Live/Advanced/ShoppingApplication/SuiteScript/shopping.ssp If you are not familiar with implementing patches for SCA, refer to the following: ■ Before you get started, familiarize yourself with Best Practices for Customizing SuiteCommerce Advanced. ■ For step by step instructions, refer to Patch Using Override Mode. Step 1: Create the Override File Following the instructions and recommendations in the Patch Using Override Mode procedure, copy and paste the following code sample in the new directory and file you create. Where you create the new directory and file depends on the SCA release that you need to patch: Aconcagua, 2018.2, and 2019.1 .../Modules/extensions/ShoppingApplicationExtension@1.00/SuiteScript/shopping.ssp SuiteCommerce Site Development Patch Instructions 407 .../SC_19.2_Live/Advanced/extensions/ShoppingApplicationExtension@1.00/SuiteScript/ shopping.ssp 2019.2 ■ For the Aconcagua release, find this line: new_script_tag.src = '<%= session.getAbsoluteUrl2("shopping.user.environment.ssp?lang=" + Language + "&cur=" + Currency + "&XSC-Touchpoint=shopping") %>&t=' + datetime + ""; And replace it with the following code: new_script_tag.src = '<%= session.getAbsoluteUrl2("shopping.user.environment.ssp?lang=" + Language + "&cur=" + Currency + "&XSC-Touchpoint=shopping") %> + ""; ■ For the 2018.2, 2019.1, and 2019.2 releases, find this line: loadJSON('<%= session.getAbsoluteUrl2("services/ShoppingUserEnvironment.Service.ss?lang=" + Language + "&cur=" + Currency + "&X-SC-Touchpoint=shopping") %>'+ googletagmanager_cookie + '&t=' + datetime + "", 'shoppingUserEnvironment') And replace it with the following code: loadJSON('<%= session.getAbsoluteUrl2("services/ShoppingUserEnvironment.Service.ss?lang=" + Language + "&cur=" + Currency + "&X-SC-Touchpoint=shopping") %>'+ googletagmanager_cookie + "", 'shoppingUserEnvironment') Step 2: Prepare the Developer Tools For Your Patch When preparing the Developer Tools for your patch as described in the Patch Using Override Mode procedure, you should: 1. Paste the code appropriate for the SCA release you are patching into a new ns.package.json file that you create. Where you create the ns.package.json file depends upon the release you are working with. Aconcagua, 2018.2, and 2019.1 .../Modules/extensions/ShoppingApplicationExtension@1.00/ns.package.json 2019.2 .../SC_19.2_Live/Advanced/extensions/ShoppingApplicationExtension@1.00/ ns.package.json ■ Use the following code if you are patching the Aconcagua, 2018.2, or 2019.1 release. { } "gulp": { "ssp-files": [ "SuiteScript/*.ssp" ] }, "overrides": { "suitecommerce/ShoppingApplication@X.Y.Z/SuiteScript/shopping.ssp" : "SuiteScript/shopping.ssp" } Important: In the preceding code sample, you must replace the string X.Y.Z with the version of the module in your implementation of SuiteCommerce Advanced. ■ Use the following code if you are patching the 2019.2 release. { "gulp": { "ssp-files": [ SuiteCommerce Site Development Patch Instructions ] } 408 "SuiteScript/*.ssp" }, "overrides": { "suitecommerce/ShoppingApplication/SuiteScript/shopping.ssp" : "SuiteScript/shopping.ssp" } 2. Open the distro.json file and then add your custom module to the modules object as described in the Patch Using Override Mode procedure. The location of the distro.json file depends on the version of SCA you are patching. Aconcagua, 2018.2, and 2019.1 For these releases, the distro.json file resides in the top-level directory. If you accepted the default directory name for your release, these would be SuiteCommerce Advanced Aconcagua, SuiteCommerce Advanced 2018.2, and SuiteCommerce Advanced 2019.1. 2019.2 For this release, the distro.json file resides in the SC_19.2_Live/Advanced directory. If you accepted the default name for the top-level directory, the complete path is: SuiteCommerce Advanced 2019.2/SC_19.2_Live/Advanced/distro.json. The following sample shows the value to add to the list of existing values that follow the “modules” key. Refer to the appropriate sample for the version of SCA you are working with. ■ Use the following sample if you are patching the Aconcagua, 2018.2, or 2019.1 release. "modules": { "extensions/ShoppingApplicationExtension": "1.0.0", . . . ■ Use the following sample if you are patching the 2019.2 release. "modules": { "extensions/ShoppingApplicationExtension", . . . Step 3: Test and Deploy Your Patch Follow the instructions provided in the Patch Using Override Mode procedure to test and deploy your patch. beforeShowContent Event Stops Working After Initial Trigger Applies to: SuiteCommerce Advanced | 2019.1 | 2019.2 In some implementations of SuiteCommerce Advanced (SCA), the beforeShowContentEvent stops working after the initial trigger in these components: ProductListPageComponent and ProductDetailsComponent. These patch instructions describe how to correct this problem. To implement this patch, create a custom module to override the NavigationHelper.Plugins.Modals file, which is part of the NavigationHelper module. The location of this file depends on the SCA release that you need to patch: 2019.1 SuiteCommerce Advanced 2019.1/Modules/suitecommerce/NavigationHelper@sc-2019.1.0/JavaScript/ NavigationHelper.Plugins.Modals.js 2019.2 SuiteCommerce Advanced 2019.2/SC_19.2_Live/Commons/NavigationHelper/JavaScript/ NavigationHelper.Plugins.Modals.ts SuiteCommerce Site Development Patch Instructions 409 If you are not familiar with implementing patches for SCA, refer to the following: ■ Before you get started, familiarize yourself with Best Practices for Customizing SuiteCommerce Advanced. ■ For step by step instructions, refer to Patch Using Override Mode. Step 1: Create the Override File Following the instructions and recommendations in the Patch Using Override Mode procedure, copy and paste the following code sample in the new directory and file you create. Where you create the new directory and file depends on the SCA release that you need to patch: 2019.1 .../Modules/extensions/NavigationHelperExtension@1.0.0/JavaScript/NavigationHelper.Plugins.Modals.js 2019.2 .../SC_19.2_Live/Commons/extensions/NavigationHelperExtension@1.0.0/JavaScript/ NavigationHelper.Plugins.Modals.ts Find this line: layout.originalShowContent = layout._showContent; And replace it with the following code: layout.originalShowContent = layout.showContent Step 2: Prepare the Developer Tools For Your Patch When preparing the Developer Tools for your patch as described in the Patch Using Override Mode procedure, you should: 1. Paste the code appropriate for the SCA release you are patching into a new ns.package.json file that you create. Where you create the ns.package.json file depends upon the release you are working with. 2019.1 .../Modules/extensions/NavigationHelperExtension@1.0.0/ns.package.json 2019.2 .../SC_19.2_Live/Commons/extensions/ NavigationHelperExtension@1.0.0/ns.package.json ■ Use the following code if you are patching the 2019.1 release. { "gulp": { "javascript": [ "JavaScript/*.js" ] }, "overrides": { "suitecommerce/NavigationHelper@SC-2019.1.0/JavaScript/NavigationHelper.Plugins.Modals.js" : "JavaScript/Naviga tionHelper.Plugins.Modals.js" } } ■ Use the following code if you are patching the 2019.2 release. { "gulp": { "javascript": [ "JavaScript/*.js" SuiteCommerce Site Development Patch Instructions 410 ] }, "overrides": { "suitecommerce/NavigationHelper/JavaScript/NavigationHelper.Plugins.Modals.ts" : "JavaScript/Navigation Helper.Plugins.Modals.ts" } } 2. Open the distro.json file and then add your extension to the modules object as described in the Patch Using Override Mode procedure. The location of the distro.json file depends on the version of SCA you are patching. 2019.1 For this release, the distro.json file resides in the top-level directory. If you accepted the default directory name for the top-level directory, the complete path is: SuiteCommerce Advanced 2019.1/ distro.json. 2019.2 For this release, the distro.json file resides in the SC_19.2_Live/Advanced directory. If you accepted the default name for the top-level directory, the complete path is: SuiteCommerce Advanced 2019.2/ SC_19.2_Live/Advanced/distro.json. The following sample shows the value to add to the list of existing values that follow the “modules” key. Refer to the appropriate sample for the version of SCA you are working with. ■ Use the following sample if you are patching the 2019.1 release. "modules": { "extensions/NavigationHelperExtension": "1.0.0", . . . ■ Use the following sample if you are patching the 2019.2 release. "modules": { "../Commons/extensions/NavigationHelperExtension", . . . Step 3: Test and Deploy Your Patch Follow the instructions provided in the Patch Using Override Mode procedure to test and deploy your patch. Filter Site Option Does Not Work As Expected Applies to: SuiteCommerce Advanced | Vinson In some implementations of the Vinson release of SuiteCommerce Advanced (SCA), site filtering does not work as expected. For example, in NetSuite if you go to Set Up > SuiteCommerce Advanced > Configuration, select the Advanced Tab, and then on the Filter Site Subtab you set the Filter Site option to current, you should only see orders for the current web store when viewing the Purchase History in the My Account home page. But, orders for other web stores from the same account are also listed in the Purchase History. These patch instructions describe how to correct this problem. To implement this patch, create a custom module to override the SuiteScript Transaction.Model.js file, which is part of the Transaction module. If you are not familiar with implementing patches for SuiteCommerce Advanced, refer to the following: ■ Before you get started, familiarize yourself with Best Practices for Customizing SuiteCommerce Advanced. ■ For step by step instructions, refer to Patch Using Override Mode. SuiteCommerce Site Development Patch Instructions 411 Step 1: Create the Override File Following the instructions and recommendations in the Patch Using Override Mode procedure, create a new directory and file: /Modules/extensions/TransactionExtension@1.0.0/SuiteScript/ Transaction.Model.js. In the new Transaction.Model.js file, find and replace the following lines with the provided code sample. Find these lines: if (this.isMultiSite) { var site_id = ModelsInit.session.getSiteSettings(['siteid']).siteid , filter_site = SC.Configuration.filter_site , search_filter_array = null; if (_.isString(filter_site) && filter_site === 'current') { search_filter_array = [site_id, '@NONE@']; } else if (_.isString(filter_site) && filter_site === 'all') { search_filter_array = []; } else if (_.isArray(filter_site)) { search_filter_array = filter_site; search_filter_array.push('@NONE@'); } } if (search_filter_array && search_filter_array.length) { this.filters.site_operator = 'and'; this.filters.site = ['website', 'anyof', _.uniq(search_filter_array)]; } And replace them with the following code: if (this.isMultiSite) { var site_id = ModelsInit.session.getSiteSettings(['siteid']).siteid , filter_site = SC.Configuration.filterSite.option , filter_site_id = SC.Configuration.filterSite.ids , search_filter_array = null; if (_.isString(filter_site) && filter_site === 'current') { search_filter_array = [site_id, '@NONE@']; } else if (_.isString(filter_site) && filter_site === 'all') { } search_filter_array = []; else if (_.isArray(filter_site_id) && filter_site === 'siteIds') { } search_filter_array = filter_site_id; search_filter_array.push('@NONE@'); if (search_filter_array && search_filter_array.length) { this.filters.site_operator = 'and'; SuiteCommerce Site Development Patch Instructions } } 412 this.filters.site = ['website', 'anyof', _.uniq(search_filter_array)]; Step 2: Prepare the Developer Tools For Your Patch When preparing the Developer Tools for your patch as described in the Patch Using Override Mode procedure, you should: 1. Paste the following sample code into the new ns.package.json file that you create in the Modules directory: /Modules/extensions/TransactionExtension@1.0.0/ns.package.json { }, } "gulp": { "ssp-libraries": [ "SuiteScript/*.js" ] "overrides": { "suitecommerce/Transaction@1.2.0/SuiteScript/Transaction.Model.js" : "SuiteScript/Transaction.Model.js" } 2. Open the distro.json file in the root SuiteCommerce Advanced development directory and then add your custom module to the modules object as described in the Patch Using Override Mode procedure. The following sample shows the value to add to the list of existing values that follow the “modules” key. "modules": { "extensions/TransactionExtension": "1.0.0", . . . Step 3: Test and Deploy Your Patch Follow the instructions provided in the Patch Using Override Mode procedure to test and deploy your patch. Quantity Facet Displays Dollar Sign Applies to: SuiteCommerce Advanced | Elbrus | Kilimanjaro | Vinson In some implementations of the Elbrus, Kilimanjaro, and Vinson releases of SuiteCommerce Advanced, adjusting the filter for a quantity facet on your site displays a numerical value that includes a dollar sign. Using Extend mode, the following patch corrects this issue in Facets.FacetsDisplay.View.js, which is part of the Facets module. To implement this patch, create a custom module to extend the prototype object for the getContext() method within Facets.FacetsDisplay.View.js. If you are not familiar with implementing patches for SuiteCommerce Advanced, refer to the following: ■ Before you get started, familiarize yourself with Best Practices for Customizing SuiteCommerce Advanced. ■ For step by step instructions, refer to Patch Using Extend Mode. Step 1: Develop An Extension Use the following code sample to extend the prototype of the getContext() method within Facets.FacetsDisplay.View.js. SuiteCommerce Site Development Patch Instructions Following the instructions and recommendations in the Patch Using Extend Mode procedure, copy and paste the following code sample in the new directory and file you create: Modules/extensions/ FacetsDisplayViewExtension@1.0.0/JavaScript/Facets.FacetsDisplay.View.Extend.js define( 'Facets.FacetsDisplay.View.Extend' , [ 'Facets.FacetsDisplay.View' , 'Backbone.CollectionView' , 'Backbone' , 'underscore' , { ] function( FacetsFacetsDisplayViewExtend , BackboneCollectionView , Backbone , _ ) 'use strict'; _.extend(FacetsFacetsDisplayView.prototype, { getContext: function() { var facets = this.options.facets , translator = this.options.translator; _.each(facets, function(facet) { facet.value = _.isArray(facet.value) ? facet.value : [facet.value]; }); var facet_values = []; _.each(facets, function(facet) { var parser = facet.config.parser; _.each(facet.value, function(value) { var from = _.isObject(value) ? value.from : ''; var to = _.isObject(value) ? value.to : ''; var value_data = { facetValueIsObject: _.isObject(value) , from: from && parser ? parser(from) : from , to: to && parser ? parser(to) : to , valueLabel: translator.getLabelForValue(facet.id, value) , facetValueUrl: translator.cloneForFacetId(facet.id, value).getUrl() , facetValue: facet.value }; }); }); facet_values.push(value_data); // @class Facets.FacetsDisplay.View.Context return { // @property {Boolean} hasFacets hasFacets: facets.length > 0 , } // @property {String} clearAllFacetsLink clearAllFacetsLink: translator.cloneWithoutFacets().getUrl() // @property {Array} values , values: facet_values }; // @class Facets.FacetsDisplay.View SuiteCommerce Site Development 413 Patch Instructions }); 414 }); Step 2: Prepare the Developer Tools For Your Patch When preparing the Developer Tools for your patch as described in the Patch Using Extend Mode procedure, you should: 1. Paste the following sample code into the new ns.package.json file that you create in the Modules directory: Modules/extensions/FacetsDisplayViewExtension@1.0.0/ns.package.json. { } "gulp": { "javascript": [ "JavaScript/*.js" ] } 2. Open the distro.json file in the root SuiteCommerce Advanced development directory and then add your extension to the modules object as described in the Patch Using Extend Mode procedure. The following sample shows the value to add to the list of existing values that follow the “modules” key. "modules": { "extensions/FacetsDisplayViewExtension": "1.0.0", . . . 3. Add Facets.FacetsDisplay.View.Extend as a dependency to the entry point within the SC.Shopping.Starter array. Your distro.js file should look similar to: "tasksConfig": { //... "javascript": [ //... { "entryPoint": "SC.Shopping.Starter", "exportFile": "shopping.js", "dependencies": [ //... "ProductDetailToQuote", "StoreLocator", "Facets.FacetsDisplay.View.Extend" ], //... Step 3: Test and Deploy Your Patch Follow the instructions provided in the Patch Using Extend Mode procedure to test and deploy your patch. Bronto Cart Recovery Link Redirects to Blank Page Applies to: SuiteCommerce Advanced | Kilimanjaro | Elbrus In some implementations of the Kilimanjaro and Elbrus releases of SuiteCommerce Advanced, the link provided in the Bronto cart recovery email redirects to a blank page. SuiteCommerce Site Development Patch Instructions 415 The following patch corrects a problem in Utils.js, which is part of the Utilities module and in productDetails.Router.js, which is a part of the ProductDetails module. To implement these patches, create custom modules to extend the prototype object for the parseUrlOptions() and productDetailsRouter() methods. You can download the code samples described in this procedure here: BrontoCartRecoveryLinkRedirects—ElbrusSample.zip. Note: Before proceeding, familiarize yourself with Best Practices for Customizing SuiteCommerce Advanced. Step 1: Extend Utils.js 1. Create an extensions directory to store your custom module. Depending on your implementation, this directory might already exist. 2. Within this directory, create a custom module with a name similar to the module being customized. For example: Modules/extensions/UtilitiesExtension@1.0.0. 3. Open your new UtilitiesExtension@1.0.0 module and create a subfolder titled JavaScript. For example: Modules/extensions/UtilitiesExtension@1.0.0/JavaScript 4. In your new JavaScript subdirectory, create a JavaScript file to extend Utils.js. Name this file according to best practices. For example: Utils.Extension.js 5. Open this file and extend the parseUrlOptions() method as shown in the following code snippet. define('Utils.Extension' , [ 'Utils' , 'jQuery' , 'underscore' , 'Backbone' , 'String.format' , 'Backbone.Validation' ] , function ( Utils , jQuery , _ , Backbone ) { 'use strict'; _.extend(Utils.prototype, function parseUrlOptions(options_String) { options_string = options_string || ''; if (~options_string.indexOf('?')) { options_string = _.last(options_string.split('?')); } if (~options_string.indexOf('#')) { options_string = _.first(options_string.split('#')); } var options = {}; if (options_string.length > 0) { var tokens = options_string.split(/\&/g) , current_token; SuiteCommerce Site Development Patch Instructions 416 while (tokens.length > 0) { current_token = tokens.shift().split(/\=/g); if (current_token[0].length === 0) { continue; } } } try{ options[current_token[0]] = decodeURIComponent(current_token[1]); }catch(e){ options[current_token[0]] = current_token[1]; } return options; }); }); 6. Save the file. Step 2: Extend ProductDetails.Router.js 1. Create an extensions directory to store your custom module. Depending on your implementation, this directory might already exist. 2. Within this directory, create a custom module with a name similar to the module being customized. For example: Modules/extensions/ProductDetailsExtension@1.0.0. 3. Open your new ProductDetailsExtension@1.0.0 module and create a subfolder titled JavaScript. For example: Modules/extensions/ProductDetailsExtension@1.0.0/JavaScript 4. In your new JavaScript subdirectory, create a JavaScript file to extend ProductDetails.Router.js. Name this file according to best practices. For example: ProductDetails.Router.Extension.js 5. Open this file and extend the productDetailsRouter() method as shown in the following code snippet. define( 'ProductDetails.Router.Extension' , [ 'ProductDetails.Router' , 'Product.Model' , 'ProductDetails.Full.View' , 'ProductDetails.QuickView.View' , 'underscore' , 'Backbone' , 'AjaxRequestsKiller' , 'Utils' ] , function ( ProductDetailsRouter , ProductModel , ProductDetailsFullView , ProductDetailsQuickView , _ , Backbone , AjaxRequestsKiller , Utils ) { 'use strict'; _.extend(productDetailsRouter.prototype, function productDetailsByUrl(url){ SuiteCommerce Site Development Patch Instructions { try{ url = decodeURIComponent(url); }catch(e){ //do nothing } // if there are any options in the URL var options = null; } }); if (~url.indexOf('?')) { options = Utils.parseUrlOptions(url); url = url.split('?')[0]; } // Now go grab the data and show it if (options) { this.productDetails({url: url}, url, options); } else { this.productDetails({url: url}, url); } }); 6. Save the file. Step 3: Prepare the Developer Tools For Your Customization 1. Open your new UtilitiesExtension@1.0.0 module directory. 2. Create a file in this directory titled ns.package.json. Modules/extensions/UtilitiesExtension@1.0.0/ns.package.json 3. Paste the following code into your new ns.package.json file: { } "gulp": { "javascript": [ "JavaScript/*.js" ] } 4. Open your new ProductDetailsExtension@1.0.0 module directory. 5. Create a file in this directory titled ns.package.json. Modules/extensions/ProductDetailsExtension@1.0.0/ns.package.json 6. Paste the following code into your new ns.package.json file: { } "gulp": { "javascript": [ "JavaScript/*.js" ] } 7. Open the distro.json file. This is located in your root directory. 8. Add your custom modules to the modules object. Your code should look similar to: { SuiteCommerce Site Development 417 Patch Instructions 418 "name": "SuiteCommerce Advanced Elbrus", "version": "2.0", "isSCA": true, "buildToolsVersion": "1.3.0", "folders": { "modules": "Modules", "suitecommerceModules": "Modules/suitecommerce", "extensionsModules": "Modules/extensions", "thirdPartyModules": "Modules/third_parties", "distribution": "LocalDistribution", "deploy": "DeployDistribution" }, "modules": { "extensions/UtilitiesExtension": "1.0.0", "extensions/ProductDetailsExtension"; "1.0.0", "suitecommerce/Account": "2.3.0", ... This step ensures that the Gulp tasks include your modules when you deploy. In this example, the custom modules are added at the beginning of the list of modules. However, you can add the modules anywhere in the modules object. The order of precedence in this list does not matter. 9. Add ProductDetails.Router.Extension as a dependency to SCA entry point within the SC.Shopping.Starter entrypoint of the JavaScript array. Your distro.js file should look similar to: "javascript": [ { //... //... "entryPoint": "SC.Shopping.Starter", "exportFile": "shopping.js", "dependencies": [ "GoogleMap", "StoreLocator", "ProductDetails.Router.Extension" ], 10. Save the distro.json file. Step 4: Test and Deploy Your Customization 1. Test your source code customizations on a local server (see SCA on a Local Server) or deploy them to your NetSuite account (see Deploy to NetSuite). If you are currently running SCA on a local server, your changes should appear on your local site immediately. 2. Confirm your results. Upon successful deployment, the link in the Bronto cart recovery email redirects to a valid page. Custom Overrides Not Applying When Deployed Applies to: SuiteCommerce Advanced | 2018.2 Developers working with the 2018.2 release of SuiteCommerce Advanced may notice that overrides to core source files implemented via the SCA developer tools are not working properly. For more information about working with SCA developer tools, see Core SuiteCommerce Advanced Developer Tools. For example, if you try to override a template as described in Override a Template File and then run gulp ssp-libraries to compile and view the modifications, the overrides are not implemented as expected. This issue has been fixed in the 2019.1 release of SuiteCommerce Advanced. If you experience this issue and cannot migrate to the latest release, you can fix this issue as described in the following procedure. SuiteCommerce Site Development Patch Instructions 419 Edit the ssp-libraries.js File 1. Locate the gulp/tasks/ssp-libraries.js file in the top-level directory of your SCA developer tools installation. 2. Add the following line of code to the ssp-libraries.js file: config.amdConfig.rawText[relativePath] = file.contents.toString(); The following example shows where to place the new line: if (isSCIS && moduleName === 'Configuration') { if (relativePath.includes('PosApplication')) { config.amdConfig.paths[inv_path[moduleName] || moduleName] = relativePath; } } else { config.amdConfig.paths[inv_path[moduleName] || moduleName] = relativePath; } config.amdConfig.rawText[relativePath] = file.contents.toString(); }; 3. Run the following command and then view your site to verify the changes in your override are visible: gulp ssp-libraries Theme Developer Tool Overrides May Cause Error On Activation Applies to: SuiteCommerce | 2018.2 Overrides implemented using the 2018.2 theme developer tools may cause an error on activation. For example, if you copy a template (.tpl) or Sass (.scss) file from the Modules directory of the published extension to a theme Overrides directory, customize the new file, and then deploy and activate that theme, you may receive this error: Templates Job Error: Could not find overriding file. For more information about overriding an active theme using the theme developer tools, refer to Override Active Extension Files. This issue occurs because the theme developer tools are not adding overrides to your theme’s manifest.json file as part of the deployment process as expected. This issue has been fixed in the 2019.1.2 release of SuiteCommerce Advanced. If you experience this issue and cannot migrate to the latest release, you can fix this issue as described in the following procedure. Step 1: Edit the overrides.js File 1. Locate the gulp/extension-mechanism/overrides.js file in the top-level directory of your theme developer tools installation. 2. Add the following lines of code to the overrides.js file: file_path = file_path.replace(extension_manifest.vendor + '/', ''); file_path = file_path.replace(extension_manifest.name + '/', ''); The following example shows where to place the new lines: SuiteCommerce Site Development Patch Instructions 420 else if(ext === '.tpl') { var aux = dst_path.split('/') , extensions_name = aux.length > 1 && aux[1] , file_path = aux.join('/') , extension_manifest = manifest_manager.getManifestByName(extensions_name); file_path = file_path.replace(extension_manifest.vendor + '/', ''); file_path = file_path.replace(extension_manifest.name + '/', ''); _.each(extension_manifest.templates.application, function(app, app_name) { var files = theme_manifest.templates.application[app_name].files; if(_.contains(app.files, file_path) && !_.contains(files, src_path)) { files.push(src_path); } }); } Step 2: Deploy and Activate Your Theme 1. Deploy the theme to your NetSuite account. Refer to Deploy a Theme to NetSuite for details. 2. Activate the theme as described in Activate Themes and Extensions. After following the preceding steps, the theme development tools will automatically add overrides to your theme’s manifest.json file so that activations are successful. Categories Do Not Display Properly Applies to: SuiteCommerce Advanced | Kilimanjaro In some implementations of the Kilimanjaro release of SuiteCommerce Advanced, the parent of a product category would incorrectly overwrite the data of a child category when it displays the child category. This could result in a Page Not Found (404) or the display of the wrong category. The fix in this patch sets the data for a category correctly, no matter if the category data came first or the overwrite data from the parent came first. To implement this patch, create a custom module to override Categories.Model.js, which is part of the Categories module. You can download the code samples described in this procedure here: CategoriesDoNotDisplayProperlyinSCA.zip Note: In general, NetSuite best practice is to extend JavaScript using the JavaScript prototype object. This improves the chances that your customizations with continue to work when migrating to a new version of SuiteCommerce Advanced. However, this patch requires you to modify a file in a way that you cannot extend, and therefore requires you to use a custom module to override the existing module file. For more information, see Customize and Extend Core SuiteCommerce Advanced Modules. Step 1: Create the Override File 1. Create an extensions directory to store your custom module. Depending on your implementation, this directory might already exist. 2. Within this directory, create a custom module with a name similar to the module being customized. For example: Modules/extensions/CategoriesExtension@1.0.0. 3. In your new CategoriesExtension@1.0.0 directory, create a folder titled SuiteScript. SuiteCommerce Site Development Patch Instructions For example: Modules/extensions/CategoriesExtension@1.0.0/SuiteScript 4. Copy the following source file and paste into the correct location: Copy This File: Place a Copy Here: Modules/suitecommerce/Categories@X.Y.Z/SuiteScript/ Categories.Model.js Modules/extensions/Categories@X.Y.Z/ SuiteScript In this example, X.Y.Z represents the version of the module in your implementation of SuiteCommerce Advanced. 5. Open your new copy of Categories.Model.js and locate the following lines: if (cat) { if (cat.isprimaryurl === 'T') { cat.idpath = category.idpath; cat.canonical = cat.fullurl; } else { cat.canonical = category.fullurl; } } else { categories[line.getValue('internalid')] = category; } 6. Replace these lines with the following code: if (cat) { if (category.isprimaryurl === 'T') { cat.canonical = category.fullurl; } if (categoryIds && categoryIds.fullurl === category.fullurl) { cat.idpath = category.idpath; } } else { category.canonical = category.fullurl; categories[line.getValue('internalid')] = category; } 7. Save the file. Step 2: Prepare the Developer Tools For Your Customization 1. Open your Modules/extensions/CategoriesExtension@1.0.0 module directory. 2. Create a file in this directory titled ns.package.json. Modules/extensions/CategoriesExtension@1.0.0/ns.package.json 3. Paste the following code in your new ns.package.json file: Important: You must replace the string X.Y.Z with the version of the module in your implementation of SuiteCommerce Advanced. { SuiteCommerce Site Development 421 Patch Instructions } 422 "gulp": { "javascript": [ "JavaScript/*.js" ] }, "overrides": { "suitecommerce/Categories@X.Y.Z/SuiteScript/Categories.Model.js" : "SuiteScript/Categories.Model.js" } 4. Open the distro.json file. This file is located in your root directory. 5. Add your custom module to the modules object. Your code should look similar to: { "name": "SuiteCommerce Advanced Kilimanjaro", "version": "2.0", "isSCA": true, "buildToolsVersion": "1.3.1", "folders": { "modules": "Modules", "suitecommerceModules": "Modules/suitecommerce", "extensionsModules": "Modules/extensions", "thirdPartyModules": "Modules/third_parties", "distribution": "LocalDistribution", "deploy": "DeployDistribution" }, "modules": { "extensions/CategoriesExtension": "1.0.0", "extensions/MyExampleCartExtension1": "1.0.0", ... This step ensures that the Gulp tasks include your module when you deploy. In this example, the custom modules are added at the beginning of the list of modules. However, you can add the modules anywhere in the modules object. The order of precedence in this list does not matter. 6. Save the distro.json file. Step 3: Test and Deploy Your Customization 1. Before you deploy, run the following command to compile and deploy the ssp-libraries: gulp --source ssp-libraries 2. Deploy your source code customizations to your NetSuite account and test the functionality. See Deploy to NetSuite for details. Note: Since this patch modifies a SuiteScript file, changes are not visible in your local environment. SuiteScript files run on the server and must be deployed to NetSuite to take effect. 3. Confirm your results. Upon successful deployment, both parent categories and their associated child directories display correctly. Incorrect Value for Shipping Estimate Occurs in Shopping Cart Applies to: SuiteCommerce Advanced | Elbrus In some implementations of the Elbrus release of SuiteCommerce Advanced, a value of $0.00 appears for the shipping estimate when calculating the actual estimated value for shipping. As a result, this indicates SuiteCommerce Site Development Patch Instructions 423 an incorrect value of shipping while SuiteCommerce is calculating the actual shipping value. This error occurs if you use SiteBuilder Extensions to create the site. The following patch corrects a problem in Cart.Detailed.View.js, which is part of the Cart module. To implement this patch, create a custom module to extend the prototype object for the estimateTaxShip() method. You can download the code samples described in this procedure here: IncorrectValueforEstimateOccursinShoppingCart.zip. Note: Before proceeding, familiarize yourself with Best Practices for Customizing SuiteCommerce Advanced. Step 1: Extend Cart.Detailed.View.js 1. Create an extensions directory to store your custom module. Depending on your implementation, this directory might already exist. 2. Within this directory, create a custom module with a name similar to the module being customized. For example, create Modules/extensions/Cart@1.0.0. 3. In your new Cart@1.0.0 directory, create a subdirectory called JavaScript. For example: Modules/extensions/Cart@1.0.0/JavaScript 4. In your new JavaScript subdirectory, create a JavaScript file to extend Cart.Detailed.View.js. Name this file according to best practices. For example: Cart.Detailed.View.Extension.js 5. Open this file and extend the estimateTaxShip() method as shown in the following code snippet. define('Cart.Detailed.View.Extension' , [ 'Utils' , 'underscore' , 'Backbone' ] , function ( , Utils , _ , Backbone { , ) jQuery 'use strict'; _.extend(estimateTaxShip.prototype: function estimateTaxShip(e), { // Build this code in a text editor to make sure that the indents are correct. { var options = this.$(e.target).serializeObject() , address_internalid = options.zip + '-' + options.country + '-null' , self = this; e.preventDefault(); var address = { internalid: address_internalid , zip: options.zip , country: options.country }; // Render method should not fire right now, the accordion must close when the promise resolves. this.model.set('shipaddress', address_internalid, {silent: true}); this.$('.cart-summary-button-estimate').text(_('Estimating...').translate()); this.$('.cart-summary-button-estimate').prop('disabled', true); var promise = this.saveForm(e); SuiteCommerce Site Development Patch Instructions 424 if (promise) { promise.then(function() { var address_internalid = self.model.get('shipaddress'); self.model.set('shipaddress', address_internalid); self.$('.cart-summary-button-estimate').text(_('Estimate').translate()); self.$('.cart-summary-button-estimate').prop('disabled', false); self.swapEstimationStatus(); }); } }); 6. Save the file. Step 2: Prepare the Developer Tools For Your Customization 1. Open your new Cart@1.0.0 module directory. 2. Create a file in this directory and name it ns.package.json. Modules/extensions/Cart@1.0.0/ns.package.json 3. Paste the following code into your new ns.package.json file: { } "gulp": { "javascript": [ "JavaScript/*.js" ] } 4. Open the distro.json file. This is located in your root directory. 5. Add your custom module to the modules object. Your code should look similar to the following example: { "name": "SuiteCommerce Advanced Elbrus", "version": "2.0", "buildToolsVersion": "1.3.0", "folders": { "modules": "Modules", "suitecommerceModules": "Modules/suitecommerce", "extensionsModules": "Modules/extensions", "thirdPartyModules": "Modules/third_parties", "distribution": "LocalDistribution", "deploy": "DeployDistribution" }, "modules": { "extensions/Cart.Extension": "1.0.0", "extensions/MyExampleCartExtension1": "1.0.0", ... This ensures that the Gulp tasks include your module when you deploy. In this example, the custom modules are added at the beginning of the list of modules. However, you can add the modules anywhere in the modules object. The order of precedence in this list does not matter. 6. Add Cart.Extension as a dependency to SCA entry point within the SC.Shopping.Starter entrypoint of the JavaScript array. Your Distro.js file should look similar to the following: "tasksConfig": { //... "javascript": [ SuiteCommerce Site Development Patch Instructions //... { 425 "entryPoint": "SC.Checkout.Starter", "exportFile": "checkout.js", "dependencies": [ //... "Cart.Extension", //... ], //... 7. Save the distro.json file. Step 3: Test and Deploy Your Customization 1. Test your source code customizations on a local server (see SCA on a Local Server) or deploy them to your NetSuite account (see Deploy to NetSuite). If you are currently running SCA on a local server, your changes should appear on your local site immediately. 2. Confirm your results. Upon successful deployment, the estimated shipping does not display a value until the calculation is complete. Standard Promotion with Inline Discount and Rate as Percentage Not Updating the Amount in Checkout Applies to: SuiteCommerce Advanced | Vinson | Mont Blanc | Denali In some implementations of the Vinson, Mont Blanc, and Denali releases of SuiteCommerce Advanced, the amount in checkout is not updating when applying a standard promotion with an inline discount and the rate as percentage. The following patch corrects a problem in ItemViews.Cell.Navigable.View.js, which is part of the ItemViews module. To implement this patch, create a custom module to extend the prototype object for the getContext() method. You can download the code samples described in this procedure here: ItemViews.Cell.Navigable.View.Extension@1.0.0–Vinson.zip. Note: Before proceeding, familiarize yourself with Best Practices for Customizing SuiteCommerce Advanced. Step 1: Extend ItemViews.Cell.Navigable.View.js 1. Create an extensions directory to store your custom module. Depending on your implementation, this directory might already exist. 2. Within this directory, create a custom module with a name similar to the module being customized. For example: Modules/extensions/ItemViews.Cell.Navigable.View.Extension@1.0.0. 3. Open your new ItemViews.Cell.Navigable.View.Extension@1.0.0 module and create a subfolder titled JavaScript. For example: Modules/extensions/ItemViews.Cell.Navigable.View.Extension@1.0.0/JavaScript 4. In your new JavaScript subdirectory, create a JavaScript file to extend ItemViews.Cell.Navigable.View.js. Name this file according to best practices. For example: ItemViews.Cell.Navigable.View.Extension.js 5. Open this file and extend the getContext() function as shown in the following code snippet. SuiteCommerce Site Development Patch Instructions 426 define('ItemViews.Cell.Navigable.View.Extension' , [ 'ItemViews.SelectedOption.View' , 'underscore' ] , function ( ItemViewsSelectedOptionView , _ ) { 'use strict'; _.extend(ItemViews.Cell.Navigable.View.prototype, { getContext: function () { var item = this.model.get('item') , line = this.model; //@class ItemViews.Navigable.View.Context return { //@property {String} itemId itemId: item.get('internalid') //@property {String} itemName , itemName: item.get('_name') //@property {String} cellClassName , cellClassName: this.options.cellClassName //@property {Boolean} isNavigable , isNavigable: !!this.options.navigable && !!item.get('_isPurchasable') //@property {String} rateFormatted , rateFormatted: line.get('rate_formatted') //@property {String} itemSKU , itemSKU: item.get('_sku') //@property {Boolean} showOptions , showOptions: !!(line.get('options') && line.get('options').length) //@property {String} itemImageURL , itemImageURL: item.get('_thumbnail').url //@property {String} itemImageAltText , itemImageAltText: item.get('_thumbnail').altimagetext //@property {String} itemURLAttributes , itemURLAttributes: item.get('_linkAttributes') //@property {Number} quantity , quantity: line.get('quantity') //@property {Boolean} showDetail2Title , showDetail2Title: !!this.options.detail2Title //@property {String} detail2Title , detail2Title: this.options.detail2Title //@property {String} detail2 , detail2: line.get(this.options.detail2) //@property {Boolean} showReason , showBlockDetail2: !!line.get(this.options.detail2) //@property {Boolean} showDetail3Title , showDetail3Title: !!this.options.detail3Title //@property {String} detail3Title , detail3Title: this.options.detail3Title //@property {String} detail3 , detail3: line.get('amount') > line.get('total') ? line.get('total_formatted') : line.get(this.options.de tail3) , } }); } }; , //@property {Boolean} showComparePrice showComparePrice: line.get('amount') > line.get('total') //@property {String} comparePriceFormatted comparePriceFormatted: line.get('amount_formatted') 6. Save the file. Step 2: Prepare the Developer Tools For Your Customization 1. Open your new ItemViews.Cell.Navigable.View.Extension@1.0.0 module directory. SuiteCommerce Site Development Patch Instructions 427 2. Create a file in this directory titled ns.package.json. Modules/extensions/ItemViews.Cell.Navigable.View.Extension@1.0.0/ns.package.json 3. Paste the following code into your new ns.package.json file: { } "gulp": { "javascript":[ "JavaScript/*.js" ] } 4. Open the distro.json file. This is located in your root directory. 5. Add your custom modules to the modules object. Your code should look similar to: { "name": "SuiteCommerce Advanced Vinson Release", "version": "2.0", "buildToolsVersion": "1.2.1", "folders": { "modules": "Modules", "suitecommerceModules": "Modules/suitecommerce", "extensionsModules": "Modules/extensions", "thirdPartyModules": "Modules/third_parties", "distribution": "LocalDistribution", "deploy": "DeployDistribution" }, "modules": { "extensions/ItemViews.Cell.Navigable.View.Extension": "1.0.0", "suitecommerce/Account": "2.2.0", ... This ensures that the Gulp tasks include your modules when you deploy. In this example, the custom modules are added at the beginning of the list of modules. However, you can add the modules anywhere in the modules object. The order of precedence in this list does not matter. 6. Add ItemViews.Cell.Navigable.View.Extension as a dependency to SCA entry point within the SC.Shopping.Starter entrypoint of the JavaScript array. Your Distro.js file should look similar to the following: "tasksConfig": { //... "javascript": [ //... { "entryPoint": "SC.Checkout.Starter", "exportFile": "checkout.js", "dependencies": [ //... "ProductDetailToQuote", "ItemViews.Cell.Navigable.View.Extension" ], //... 7. Save the distro.json file. Step 3: Test and Deploy Your Customization 1. Test your source code customizations on a local server (see SCA on a Local Server) or deploy them to your NetSuite account (see Deploy to NetSuite). If you are currently running SCA on a local server, your changes should appear on your local site immediately. 2. Confirm your results. SuiteCommerce Site Development Patch Instructions 428 Upon successful deployment, the amount displays on checkout pages when applying standard promotion with inline discount and the rate set as a percentage. Page With URL Fragments Redirects Too Many Times Applies to: SuiteCommerce Advanced | Elbrus | Kilimanjaro In some implementations of the Elbrus and Kilimanjaro releases of SuiteCommerce Advanced, some pages return ERR_TOO_MANY_REDIRECTS instead of displaying the Product Details page or a 404 error. This error occurs when the URL contains one or more URL fragments. The patch instructions described below correct this problem. To implement this patch, create a custom module to override ProductDetails.Router.js, which is part of the ProductDetails module. You can download the code samples described in this procedure here: PageWithURLFragmentsRedirectsTooManyTimes.zip. Note: In general, NetSuite best practice is to extend JavaScript using the JavaScript prototype object. This improves the chances that your customizations continue to work when migrating to a newer version of SuiteCommerce Advanced. However, this patch requires you to modify a file in a way that you cannot extend, and therefore requires you to use a custom module to override the existing module file. For more information, see Customize and Extend Core SuiteCommerce Advanced Modules. Step 1: Create the Override File 1. Create an extensions directory to store your custom module. Depending on your implementation, this directory might already exist. 2. Within this directory, create a custom module with a name similar to the module being customized. For example, create Modules/extensions/ProductDetailsExtension@1.0.0. 3. In your new ProductDetailsExtension@1.0.0 directory, create a subdirectory called JavaScript. For example: Modules/extensions/ProductDetailsExtension@1.0.0/JavaScript 4. Copy the following source file and paste into the correct location: Copy This File: Place a Copy Here: Modules/suitecommerce/ProductDetails@X.Y.Z/ JavaScript/ ProductDetails.Router.js Modules/extensions/ProductDetailsExtension@1.0.0/ JavaScript In this example, X.Y.Z represents the version of the module in your implementation of SuiteCommerce Advanced. 5. Open your new copy of ProductDetails.Router.js and locate the following lines: if (api_query.id && item.get('urlcomponent') && SC.ENVIRONMENT.jsEnvironment === 'server') { nsglobal.statusCode = 301; nsglobal.location = product.generateURL(); } if (data.corrections && data.corrections.length > 0) { if (item.get('urlcomponent') && SC.ENVIRONMENT.jsEnvironment === 'server') { nsglobal.statusCode = 301; nsglobal.location = data.corrections[0].url + product.getQuery(); } else { SuiteCommerce Site Development Patch Instructions } } return Backbone.history.navigate('#' + data.corrections[0].url + product.getQuery(), {trigger: true}); 6. Replace these lines with the following code: if (api_query.id && item.get('urlcomponent') && SC.ENVIRONMENT.jsEnvironment === 'server') { var productUrl = product.generateURL(); productUrl = productUrl[0] === '/' ? productUrl : '/' + productUrl; } nsglobal.statusCode = 301; nsglobal.location = productUrl; if (data.corrections && data.corrections.length > 0) { if (item.get('urlcomponent') && SC.ENVIRONMENT.jsEnvironment === 'server') { var url = data.corrections[0].url; url = url[0] === '/' ? url : '/' + url; } { } } nsglobal.statusCode = 301; nsglobal.location = url + product.getQuery(); else return Backbone.history.navigate('#' + data.corrections[0].url + product.getQuery(), {trigger: true}); 7. Save the file. Step 2: Prepare the Developer Tools For Your Customization 1. Open your Modules/extensions/ProductDetailsExtension@1.0.0 module directory. 2. Create a file in this directory and name it ns.package.json. Modules/extensions/ProductDetailsExtension@1.0.0/ns.package.json 3. Paste the following code in your new ns.package.json file: { "gulp": { "javascript": [ "JavaScript/*.js" ] }, "overrides": { "Modules/suitecommerce/ProductDetails@X.Y.Z/JavaScript/ProductDetails.Router.js" : "JavaScript/ProductDetail s.Router.js" } } Important: You must replace the string X.Y.Z with the version of the module in your implementation of SuiteCommerce Advanced. 4. Open the distro.json file. This file is located in your root directory. 5. Add your custom module to the modules object. Your code should look similar to the following example: { "name": "SuiteCommerce Advanced Kilimanjaro", "version": "2.0", "isSCA": true, SuiteCommerce Site Development 429 Patch Instructions 430 "buildToolsVersion": "1.3.1", "folders": { "modules": "Modules", "suitecommerceModules": "Modules/suitecommerce", "extensionsModules": "Modules/extensions", "thirdPartyModules": "Modules/third_parties", "distribution": "LocalDistribution", "deploy": "DeployDistribution" }, "modules": { "extensions/ProductDetailsExtension": "1.0.0", "extensions/MyExampleCartExtension1": "1.0.0", ... This ensures that the Gulp tasks include your module when you deploy. In this example, the custom modules are added at the beginning of the list of modules. However, you can add the modules anywhere in the modules object. The order of precedence in this list does not matter. 6. Save the distro.json file. Step 3: Test and Deploy Your Customization 1. Test your source code customizations on a local server (see SCA on a Local Server) or deploy them to your NetSuite account (see Deploy to NetSuite). If you are currently running SCA on a local server, your changes should appear on your local site immediately. 2. Confirm your results. Upon successful deployment, instead of showing ERR_TOO_MANY_REDIRECTS, the browser shows a 404 error or the Product Details page. See Complete List of Stores Link on Store Locator Page Does Not Show Store List Applies to: SuiteCommerce Advanced | Kilimanjaro | Vinson | Elbrus In some implementations of the Kilimanjaro, Vinson and Elbrus releases of SuiteCommerce Advanced, the See Complete List of Stores link on the Store Locator page reloads the page but does not show the complete list of stores. The patch instructions described below correct this problem. To implement this patch, create a custom module to override the store_locator_main.tpl, store_locator_list.tpl, and store_locator_list_all_store.tpl files, which are part of the StoreLocator@X.Y.Z module. In this example, X.Y.Z represents the version of the StoreLocator module in your implementation of SuiteCommerce Advanced. You can download the code samples described in this procedure here: StoreLocator.Extension@1.0.0 ElbrusCodeSamples.zip Step 1: Create the Override Files 1. Create an extensions directory to store your custom module. Depending on your implementation, this directory might already exist. For example, create Modules/extensions 2. Within this directory, create a custom module with a name similar to the module being customized. For example, create Modules/extensions/StoreLocator.Extension@1.0.0. 3. In your new StoreLocator.Extension@1.0.0 directory, create a subdirectory called Templates. For example: Modules/extensions/StoreLocator.Extension@1.0.0/Templates 4. Copy the following source file and paste into the correct location: Copy This File: Place a Copy Here: Modules/suitecommerce/StoreLocator@X.Y.Z/ Templates/store_locator_main.tpl Modules/extensions/StoreLocator.Extension@1.0.0/ Templates SuiteCommerce Site Development Patch Instructions Copy This File: Place a Copy Here: Modules/suitecommerce/StoreLocator@X.Y.X/ Templates/store_locator_list.tpl Modules/extensions/StoreLocator.Extension@1.0.0/ Templates Modules/suitecommerce/StoreLocator@X.Y.Z/ Templates/store_locator_list_all_store.tpl Modules/extensions/StoreLocator.Extension@1.0.0/ Templates 431 In this example, X.Y.Z represents the version of the module in your implementation of SuiteCommerce Advanced. 5. Revise your new store_locator_main.tpl file following these steps: a. Locate the following line: <a data-touchpoint="{{touchpoint}}" data-hashtag="stores/all" href="stores/ all" href="stores/all">{{trans late 'See complete list of stores'}}</a> b. Replace this line with the following code: <a href="stores/all">{{translate 'See complete list of stores'}}</a> c. Save the file. 6. Revise your new store_locator_list.tpl file following these steps: a. Locate the following line: <a data-hashtag="stores/details/{{storeId}}" data-touchpoint="{{touchpoint}}" data-toggle="show-in-pusher"> b. Replace these line with the following code: <a href="stores/details/{{storeId}}" data-toggle="show-in-pusher"> c. Save the file. 7. Revise your new store_locator_list_all_store.tpl file following these steps: a. Locate the following lines: <a class="store-locator-list-all-store-name" data-touchpoint="{{touchpoint}}" data-toggle="show-in-pusher" datahashtag="stores/details/{{storeId}}" href="stores/details/{{storeId}}">{{name}}</a> b. Replace this line with the following code: <a class="store-locator-list-all-store-name" data-toggle="show-in-pusher" href="stores/details/ {{storeId}}">{{name}}</a> c. Save the file. Step 2: Prepare the Developer Tools For Your Customization 1. Open your Modules/extensions/StoreLocator.Extension@1.0.0 module directory. 2. Create a file in this directory and name it ns.package.json. Modules/extensions/StoreLocator.Extension@1.0.0/ns.package.json 3. Paste the following code in your new ns.package.json file: { "gulp": { "templates": [ "Templates/*" ] SuiteCommerce Site Development Patch Instructions 432 }, "overrides": { "suitecommerce/StoreLocator@X.Y.Z/Templates/store_locator_main.tpl": "Templates/store_locator_main.tpl", "suitecommerce/StoreLocator@X.Y.Z/Templates/store_locator_list.tpl": "Templates/store_locator_list.tpl", "suitecommerce/StoreLocator@X.Y.Z/Templates/store_locator_list_all_store.tpl": "Templates/store_locator_list_al l_store.tpl" } } Important: You must replace the string X.Y.Z with the version of the module in your implementation of SuiteCommerce Advanced. 4. Open the distro.json file. This file is located in your root directory. 5. Add your custom module to the modules object. Your code should look similar to the following example: { "name": "SuiteCommerce Advanced Elbrus", "version": "2.0", "isSCA": true, "buildToolsVersion": "1.3.0", "folders": { "modules": "Modules", "suitecommerceModules": "Modules/suitecommerce", "extensionsModules": "Modules/extensions", "thirdPartyModules": "Modules/third_parties", "distribution": "LocalDistribution", "deploy": "DeployDistribution" }, "modules": { "extensions/StoreLocator.Extension": "1.0.0", "suitecommerce/Account": "2.3.0", ... This ensures that the Gulp tasks include your module when you deploy. In this example, the custom modules are added at the beginning of the list of modules. However, you can add the modules anywhere in the modules object. The order of precedence in this list does not matter. 6. Save the distro.json file. Step 3: Test and Deploy Your Customization 1. Test your source code customizations on a local server (see SCA on a Local Server) or deploy them to your NetSuite account (see Deploy to NetSuite). If you are currently running SCA on a local server, your changes should appear on your local site immediately. 2. Confirm your results. Upon successful deployment, Store Locator reloads the page and shows the complete list of stores. Quantity Pricing Displayed in Web Store Even When “Require Login for Pricing” is Enabled Applies to: SuiteCommerce Advanced | Kilimanjaro | Vinson | Elbrus In some implementations of the Kilimanjaro, Vinson, and Elbrus releases of SuiteCommerce Advanced, quantity pricing displays in the web store even when Require Login for Pricing is enabled. The following patch corrects a problem in QuantityPricing.View.js, which is part of the QuantityPricing module. To implement this patch, create a custom module to extend the prototype object for the initialize function. You can download the code samples described in this procedure here: QuantityPricingAconcaguaCodeSamples.. SuiteCommerce Site Development Patch Instructions 433 Note: Before proceeding, familiarize yourself with Best Practices for Customizing SuiteCommerce Advanced. Step 1: Extend QuantityPricing.View.js 1. Create an extensions directory to store your custom module. Depending on your implementation, this directory might already exist. 2. Within this directory, create a custom module with a name similar to the module being customized. For example, create Modules/extensions/QuantityPricing.Extension@1.0.0. 3. In your new QuantityPricing.Extension@1.0.0 directory, create a subdirectory called JavaScript. For example: Modules/extensions/QuantityPricing.Extension@1.0.0/JavaScript 4. In your new JavaScript subdirectory, create a JavaScript file to extend QuantityPricing.View.js. Name this file according to best practices. QuantityPricing.View.Extension.js 5. Open this file and extend the QuanitityPricing.View method as shown in the following code snippet. define( 'QuantityPricing.View.Extension' , [ 'QuantityPricing.View' , 'QuantityPricing.Utils' , 'SC.Configuration' , 'Profile.Model' , 'Backbone' , 'underscore' ] , function ( QuantityPricingView , QuantityPricingUtils , Configuration , ProfileModel , Backbone , _ ) { 'use strict'; _.extend(QuantityPricingView.prototype, { initialize: function () { this.profileModel = ProfileModel.getInstance(); this._isEnabled = !this.profileModel.hidePrices(); this.price_schedule = QuantityPricingUtils.rearrangeQuantitySchedule(this.model.get('item'), _.isFunc tion(this.model.getSelectedMatrixChilds) ? this.model.getSelectedMatrixChilds() : []); this.model.on('change', function () { var new_price_schedule = QuantityPricingUtils.rearrangeQuantitySchedule(this.model.get('item'), _.isFunc tion(this.model.getSelectedMatrixChilds) ? this.model.getSelectedMatrixChilds() : []); if (!_.isEqual(this.price_schedule, new_price_schedule)) { this.price_schedule = new_price_schedule; this.render(); } }, this); this.item_key = this.model.get('item').id + '' + (new Date()).getMilliseconds(); SuiteCommerce Site Development Patch Instructions 434 } }); }); 6. Save the file. Step 2: Prepare the Developer Tools For Your Customization 1. Open your new QuantityPricing.Extension@1.0.0 module directory. 2. Create a file in this directory and name it ns.package.json. Modules/extensions/QuantityPricing.Extension@1.0.0/ns.package.json 3. Paste the following code into your new ns.package.json file: { } "gulp": { "javascript": [ "JavaScript/*.js" ] } 4. Open the distro.json file. This is located in your root directory. 5. Add your custom module to the modules object. Your code should look similar to the following example: { "name": "SuiteCommerce Advanced Aconcagua", "version": "2.0", "isSCA": true, "buildToolsVersion": "sco-2018.1.0", "folders": { "modules": "Modules", "suitecommerceModules": "Modules/suitecommerce", "extensionsModules": "Modules/extensions", "thirdPartyModules": "Modules/third_parties", "distribution": "LocalDistribution", "deploy": "DeployDistribution" }, "modules": { "extensions/QuantityPricing.Extension": "1.0.0", "suitecommerce/Account": "sco-2018.1.0", ... This ensures that the Gulp tasks include your module when you deploy. In this example, the custom modules are added at the beginning of the list of modules. However, you can add the modules anywhere in the modules object. The order of precedence in this list does not matter. 6. Add QuantityPricing.Extension as a dependency to SCA entry point within the SC.Shopping.Starter and SC.MyAccount.Starter entrypoints of the JavaScript array. Your Distro.js file should look similar to the following: "tasksConfig": { //... "javascript": [ //... { "entryPoint": "SC.Shopping.Starter", "exportFile": "shopping.js", "dependencies": [ //... "ProductDetailToQuote", "StoreLocator", SuiteCommerce Site Development Patch Instructions ], { 435 "SC.CCT.Html", "QuantityPricing.View.Extension" //... "entryPoint": "SC.MyAccount.Starter", "exportFile": "myaccount.js", "dependencies": [ //... "GoogleMap.Configuration", "StoreLocatorAccessPoints", "SC.CCT.Html", "QuantityPricing.View.Extension" ], //... 7. Save the distro.json file. Step 3: Test and Deploy Your Customization 1. Test your source code customizations on a local server (see SCA on a Local Server) or deploy them to your NetSuite account (see Deploy to NetSuite). If you are currently running SCA on a local server, your changes should appear on your local site immediately. 2. Confirm your results. Upon successful deployment, quantity pricing will not display in the web store when Require Login for Pricing is enabled. Edited Shipping Address on the Review Your Order Page is Not Showing Changes Applies to: SuiteCommerce Advanced | Aconcagua | Kilimanjaro In some implementations of the Aconcagua and Kilimanjaro releases of SuiteCommerce Advanced, the Review Your Order page is not showing changes when user edits the shipping address. To implement this patch, create a custom module to override the OrderWizard.Module.ShowShipments.js file, which ispart of the OrderWizard.Module.Shipmethod@X.Y.Z module. In this example, X.Y.Z represents the version of the OrderWizard.Module.Shipment module in your implementation of SuiteCommerce Advanced. You can download the code samples described in this procedure here: OrderWizard.Module.Shipmethod.AconcaguaSampleCode.zip In general, NetSuite best practice is to extend JavaScript using the JavaScript prototype object. This improves the chances that your customizations continue to work when migrating to a newer version of SuiteCommerce Advanced. However, this patch requires you to modify a file in a way that you cannot extend, and therefore requires you to use a custom module to override the existing module file. For more information, see Customize and Extend Core SuiteCommerce Advanced Modules. Step 1: Create the Override File 1. Create an extensions directory to store your custom module. Depending on your implementation, this directory might already exist. For example, create Modules/extensions 2. Within this directory, create a custom module with a name similar to the module being customized. For example, create Modules/extensions/OrderWizard.Module.Shipmethod.Extension@1.0.0. 3. In your new StoreLocator.Extension@1.0.0 directory, create a subdirectory called JavaScript. For example: Modules/extensions/OrderWizard.Module.Shipmethod.Extension@1.0.0/JavaScript 4. Copy the following source file and paste into the correct location: SuiteCommerce Site Development Patch Instructions Copy This File: 436 Place a Copy Here: Modules/suitecommerce/OrderWizard.Module. Modules/extensions/OrderWizard.Module. Shipment@X.Y.Z/OrderWizard.Module.ShowShipments.js Shipmethod.Extension@1.0.0/JavaScript In this example, X.Y.Z represents the version of the module in your implementation of SuiteCommerce Advanced. 5. Revise your new OrderWizard.Module.ShowShipments.js file following these steps: Replace the existing initialize function with this code: a. , initialize: function () { WizardModule.prototype.initialize.apply(this, arguments); this.application = this.wizard.application; this.options.application = this.wizard.application; this.addressSource = this.options.useModelAddresses ? this.model.get('addresses') : this.wizard.options.profile.get('addresses'); BackboneCompositeView.add(this); } this.wizard.model.on('ismultishiptoUpdated', this.render, this); this.wizard.model.on('promocodeUpdated', this.render, this); this.address = this.addressSource.get(this.model.get('shipaddress')); this.address && this.address.on('change', this.render, this); Add this new destroy function after the initialize function: b. , c. destroy: function destroy() { this.address && this.address.off('change', this.render, this); return this._destroy(); } Save the file. Step 2: Prepare the Developer Tools For Your Customization 1. Open your Modules/extensions/StoreLocator.Extension@1.0.0 module directory. 2. Create a file in this directory and name it ns.package.json. Modules/extensions/OrderWizard.Module.Shipmethod.Extension@1.0.0/ns.package.json 3. Paste the following code in your new ns.package.json file: { "gulp": { "javascript": [ "JavaScript/*.js" ] }, "overrides": { "suitecommerce/OrderWizard.Module.Shipmethod@X.Y.Z/JavaScript/OrderWizard.Module.ShowShipments.js": "JavaScript/ OrderWizard.Module.ShowShipments.js" } } Important: You must replace the string X.Y.Z with the version of the module in your implementation of SuiteCommerce Advanced. 4. Open the distro.json file. This file is located in your root directory. SuiteCommerce Site Development Patch Instructions 437 5. Add your custom module to the modules object. Your code should look similar to the following example: { "name": "SuiteCommerce Advanced Aconcagua", "version": "2.0", "isSCA": true, "buildToolsVersion": "sc0-2018.1.0", "folders": { "modules": "Modules", "suitecommerceModules": "Modules/suitecommerce", "extensionsModules": "Modules/extensions", "thirdPartyModules": "Modules/third_parties", "distribution": "LocalDistribution", "deploy": "DeployDistribution" }, "modules": { "extensions/OrderWizard.Module.Shipmethod.Extension": "1.0.0", "suitecommerce/Account": "sc0-2018.1.0", ... This ensures that the Gulp tasks include your module when you deploy. In this example, the custom modules are added at the beginning of the list of modules. However, you can add the modules anywhere in the modules object. The order of precedence in this list does not matter. 6. Save the distro.json file. Step 3: Test and Deploy Your Customization 1. Test your source code customizations on a local server (see SCA on a Local Server) or deploy them to your NetSuite account (see Deploy to NetSuite). If you are currently running SCA on a local server, your changes should appear on your local site immediately. 2. Confirm your results. Upon successful deployment, edited shipping address information displays on the Review Your Order page. Custom Page Title in SMT Does Not Display Correctly Applies to: SuiteCommerce Advanced | Aconcagua In some implementations of SuiteCommerce Advanced, creating a title for a custom facets page using Site Management Tools does not display the correct title. In these cases, editing the page name on a custom page results in the page title inheriting the facet path instead of the custom title. The following patch corrects a problem in CMSadapter.Page.Router.js, which is part of the CMSAdapter module. To implement this patch, create a custom module to extend the prototype object for the getPageForFragment method. You can download the code samples described in this procedure here: CustomPageTitlesNotDisplayingCorrectly.zip. Note: Before proceeding, familiarize yourself with Best Practices for Customizing SuiteCommerce Advanced. Step 1: Extend CMSadapter.Page.Router.js 1. Create an extensions directory to store your custom module. Depending on your implementation, this directory might already exist. SuiteCommerce Site Development Patch Instructions 438 2. Within this directory, create a custom module with a name similar to the module being customized. For example: Modules/extensions/CMSadapterExtension@1.0.0. 3. Open your new CMSadapterExtension@1.0.0 module and create a subfolder titled JavaScript. For example: Modules/extensions/CMSadapterExtension@1.0.0/JavaScript 4. In your new JavaScript subdirectory, create a JavaScript file to extend CMSadapter.Page.Router.Extend.js. Name this file according to best practices. For example: CMSadapter.Page.Router.Extend.js 5. Open this file and extend the getPageForFragment() method as shown in the following code snippet. define( 'CMSadapter.Page.Router.Extend' , [ 'CMSadapter.Page.Router' , 'underscore' , 'Backbone' ] , function ( CMSadapterPageRouter { , , ) _ Backbone 'use strict'; _.extend(CMSadapterPageRouter.prototype, { getPageForFragment: function getPageForFragment(fragment, allPages) { fragment = fragment || Backbone.history.fragment || '/'; fragment = fragment.split('?')[0]; //remove options }); }); } var collection = allPages ? this.allPages : this.landingPages; return collection.find(function(page) { return ((page.get('url') === fragment) || (page.get('url') === '/' + fragment)); }); 6. Save the file. Step 2: Prepare the Developer Tools For Your Customization 1. Open your new CMSadapterExtension@1.0.0 module directory. 2. Create a file in this directory titled ns.package.json. Modules/extensions/CMSadapterExtension@1.0.0/ns.package.json 3. Paste the following code into your new ns.package.json file: { } "gulp": { "javascript": [ "JavaScript/*.js" ] } 4. Open the distro.json file. This is located in your root directory. SuiteCommerce Site Development Patch Instructions 439 5. Add your custom module to the modules object. Your code should look similar to: { "name": "SuiteCommerce Advanced Kilimanjaro", "version": "2.0", "isSCA": true, "buildToolsVersion": "1.3.1", "folders": { "modules": "Modules", "suitecommerceModules": "Modules/suitecommerce", "extensionsModules": "Modules/extensions", "thirdPartyModules": "Modules/third_parties", "distribution": "LocalDistribution", "deploy": "DeployDistribution" }, "modules": { "extensions/CMSadapterExtension": "1.0.0", "extensions/MyExampleCartExtension1": "1.0.0", ... This step ensures that the Gulp tasks include your module when you deploy. In this example, the custom modules are added at the beginning of the list of modules. However, you can add the modules anywhere in the modules object. The order of precedence in this list does not matter. 6. Add CMSadapter.Page.Router.Extend as a dependency to SCA entry point within the SC.Shopping.Starter, SC.Checkout.Starter, and SC.MyAccount.Starter entrypoints of the JavaScript array. Your distro.js file should look similar to: "tasksConfig": { //... "javascript": [ //... { "entryPoint": "SC.Shopping.Starter", "exportFile": "shopping.js", "dependencies": [ //... "ProductDetailToQuote", "StoreLocator", "CMSadapter.Page.Router.Extend" ], //... "entryPoint": "SC.MyAccount.Starter", "exportFile": "myaccount.js", "dependencies": [ //... "StoreLocatorAccessPoints", "StoreLocator", "SC.CCT.Html", "CMSadapter.Page.Router.Extend" ], //... "entryPoint": "SC.Checkout.Starter", "exportFile": "checkout.js", "dependencies": [ //... "StoreLocatorAccessPoints", "StoreLocator", "SC.CCT.Html", "CMSadapter.Page.Router.Extend" ], //... 7. Save the distro.json file. SuiteCommerce Site Development Patch Instructions 440 Step 3: Test and Deploy Your Customization 1. Test your source code customizations on a local server (see SCA on a Local Server) or deploy them to your NetSuite account (see Deploy to NetSuite). If you are currently running SCA on a local server, your changes should appear on your local site immediately. 2. Confirm your results. Upon successful deployment, custom page titles should display as expected. Currencies Change to the Default in the Shopping Application Applies to: SuiteCommerce Advanced | Kilimanjaro In some implementations of SuiteCommerce Advanced using multi-subsidiaries, users cannot change the currency on the site. The webstore continues to use the default currency. The following patch corrects the GlobalViews.CurrencySelector.View.js, which is part of the GlobalViews module. To implement this patch, create a custom module to extend the prototype object for the getContext() method. You can download the code samples described in this procedure here: CurrenciesChangeToDefault-Kilimanjaro.zip. Step 1: Extend GlobalViews.CurrencySelector.View.js 1. Create an extensions directory to store your custom module. Depending on your implementation, this directory might already exist. 2. Within this directory, create a custom module with a name that is unique but similar to the module being customized. For example: Modules/extensions/GlobalViewsExtension@1.0.0. 3. Open your new GlobalViewsExtension@1.0.0 module and create a subfolder titled JavaScript. For example: Modules/extensions/GlobalViewsExtension@1.0.0/JavaScript 4. In your new JavaScript subdirectory, create a JavaScript file to extend GlobalViews.CurrencySelector.View.js . Name this file according to best practices. For example: GlobalViews.CurrencySelector.View.Extend.js 5. Open this file and extend the getContext() method as shown in the following code snippet. define( 'GlobalViews.CurrencySelector.View.Extend' , [ 'GlobalViews.CurrencySelector.View' , { , , ] , , ) 'Backbone' 'underscore' function( GlobalViewsCurrencySelectorView Backbone _ SuiteCommerce Site Development Patch Instructions 'use strict'; _.extend(GlobalViewsCurrencySelectorView.prototype, { getContext: function() { var available_currencies = _.map(SC.ENVIRONMENT.availableCurrencies, function(currency) { // @class GlobalViews.CurrencySelector.View.Context.Currency return { // @property {String} code code: currency.code // @property {String} internalId , internalId: currency.internalid // @property {String} isDefault , isDefault: currency.isdefault // @property {String} symbol , symbol: currency.symbol // @property {Boolean} symbolPlacement , symbolPlacement: currency.symbolplacement // @property {String} displayName , displayName: currency.title || currency.name // @property {Boolean} isSelected , isSelected: SC.getSessionInfo('currency').code === currency.code }; }); // @class GlobalViews.CurrencySelector.View.Context return { // @property {Boolean} showCurrencySelector showCurrencySelector: !!(SC.ENVIRONMENT.availableCurrencies && SC.ENVIRONMENT.availableCurrencies.length > 1) , , }); }); } , }; // @property {Array<GlobalViews.CurrencySelector.View.Context.Currency>} availableCurrencies availableCurrencies: available_currencies || [] // @property {String} currentCurrencyCode currentCurrencyCode: SC.getSessionInfo('currency').code // @property {String} currentCurrencySymbol currentCurrencySymbol: SC.getSessionInfo('currency').symbol 6. Save the file. Step 2: Prepare the Developer Tools For Your Customization 1. Open your new Transaction.Line.Views.Extension@1.0.0 module directory. 2. Create a file in this directory titled ns.package.json. Modules/extensions/Transaction.Line.Views.Extension@1.0.0/ns.package.json 3. Paste the following code into your new ns.package.json file: { } "gulp": { "javascript": [ "JavaScript/*.js" ] } 4. Open the distro.json file. This is located in your root directory. 5. Add your custom module to the modules object. Your code should look similar to: { SuiteCommerce Site Development 441 Patch Instructions 442 "name": "SuiteCommerce Advanced Kilimanjaro", "version": "2.0", "isSCA": true, "buildToolsVersion": "1.3.1", "folders": { "modules": "Modules", "suitecommerceModules": "Modules/suitecommerce", "extensionsModules": "Modules/extensions", "thirdPartyModules": "Modules/third_parties", "distribution": "LocalDistribution", "deploy": "DeployDistribution" }, "modules": { "extensions/GlobalViewsExtension": "1.0.0", "extensions/MyExampleCartExtension1": "1.0.0", ... This step ensures that the Gulp tasks include your module when you deploy. In this example, the custom modules are added at the beginning of the list of modules. However, you can add the modules anywhere in the modules object. The order of precedence in this list does not matter. 6. Save the distro.json file. Step 3: Test and Deploy Your Customization 1. Test your source code customizations on a local server (see SCA on a Local Server) or deploy them to your NetSuite account (see Deploy to NetSuite). If you are currently running SCA on a local server, your changes should appear on your local site immediately. 2. Confirm your results. Upon successful deployment, Checkout Summary pages should display correct original and discounted sub-total amounts. Strike-through amounts also display correctly. Order Confirmation Page Not Displayed When Using Single Page Checkout and External Payment Applies to: SuiteCommerce Advanced | Vinson | Elbrus In some implementations of the Vinson and Elbrus releases of SuiteCommerce Advanced, the Order Confirmation Page is not displayed when using one page checkout with an external payment system. To implement this patch, create a custom module to override SC.Checkout.Configuration.Steps.OPC.js, which is part of the CheckoutApplication@2.2.0 module. You can download the code samples described in this procedure here: CheckoutApplication.Extension@1.0.0 VinsonCodeSamples.zip Note: In general, NetSuite best practice is to extend JavaScript using the JavaScript prototype object. This improves the chances that your customizations continue to work when migrating to a newer version of SuiteCommerce Advanced. However, this patch requires you to modify a file in a way that you cannot extend, and therefore requires you to use a custom module to override the existing module file. For more information, see Customize and Extend Core SuiteCommerce Advanced Modules. Step 1: Create the Override File 1. Create an extensions directory to store your custom module. Depending on your implementation, this directory might already exist. SuiteCommerce Site Development Patch Instructions 443 2. Within the extension directory, create a directory for a new custom module with a name similar to the module being customized. For example, create Modules/extensions/CheckoutApplication.Extension@1.0.0. 3. In your new CheckoutApplicationExtension@1.0.0 module directory, create a directory called JavaScript. For example: Modules/extensions/CheckoutApplication.Extension@1.0.0/JavaScript 4. Copy the following source file and paste into the correct location: Copy This File: Place a Copy Here: Modules/suitecommerce/CheckoutApplication@X.Y.Z/ JavaScript/ SC.Checkout.Configuration.Steps.OPC.js Modules/extensions/CheckoutApplication. Extension@1.0.0/JavaScript In this example, X.Y.Z represents the version of the module in your implementation of SuiteCommerce Advanced. 5. Open your new copy of SC.Checkout.Configuration.Steps.OPC.js and locate the following line: , [OrderWizardModulePaymentMethodSelector, {record_type:'salesorder', preventDefault: true}] 6. Replace this line with the following code: , [OrderWizardModulePaymentMethodSelector, {record_type:'salesorder', prevent_default: true}] 7. Save the file. Step 2: Prepare the Developer Tools For Your Customization 1. Open your Modules/extensions/CheckoutApplication.Extension@1.0.0 directory. 2. Create a file in this directory and name it ns.package.json. Modules/extensions/CheckoutApplication.Extension@1.0.0/ns.package.json 3. Paste the following code in your new ns.package.json file: { "gulp": { "javascript": [ "JavaScript/*.js" ] }, "overrides": { "suitecommerce/CheckoutApplication@2.2.0/JavaScript/SC.Checkout.Configuration.Steps.OPC.js" : "JavaScript/SC.Check out.Configuration.Steps.OPC.js" } } Important: You must replace the string X.Y.Z with the version of the module in your implementation of SuiteCommerce Advanced. 4. Open the distro.json file. This file is located in your root directory. 5. Add your custom module to the modules object. Your code should look similar to the following example: { "name": "SuiteCommerce Advanced Vinson Release", "version": "2.0", SuiteCommerce Site Development Patch Instructions 444 "isSCA": true, "buildToolsVersion": "1.2.1", "folders": { "modules": "Modules", "suitecommerceModules": "Modules/suitecommerce", "extensionsModules": "Modules/extensions", "thirdPartyModules": "Modules/third_parties", "distribution": "LocalDistribution", "deploy": "DeployDistribution" }, "modules": { "extensions/CheckoutApplication.Extension": "1.0.0", "suitecommerce/Account": "2.2.0", ... This ensures that the Gulp tasks include your module when you deploy. In this example, the custom modules are added at the beginning of the list of modules. However, you can add the modules anywhere in the modules object. The order of precedence in this list does not matter. 6. Save the distro.json file. Step 3: Test and Deploy Your Customization 1. Test your source code customizations on a local server (see SCA on a Local Server) or deploy them to your NetSuite account (see Deploy to NetSuite). If you are currently running SCA on a local server, your changes should appear on your local site immediately. 2. Confirm your results. Upon successful deployment, the Order Confirmation Page is displayed after completing an order when using one page checkout with an external payment system. Incorrect Discounted Amounts on Checkout Summary Applies to: SuiteCommerce Advanced | Aconcagua | Kilimanjaro | Elbrus In some implementations of SuiteCommerce Advanced, Checkout Summary pages display incorrect discounted sub-total amounts and inconsistent strike-through and original amounts. These issues occur on Subtotal and Items to Ship sections of the checkout flow. The patch instructions described below correct this problem. The following patch corrects a problem in Transaction.Line.Views.Cell.Navigable.View.js, which is part of the Transaction.Line.Views module. To implement this patch, create a custom module to extend the prototype object for the getContext() method. You can download the code samples described in this procedure here: IncorrectDiscountedAmountsOnCheckout.zip. Step 1: Extend Transaction.Line.Views.Cell.Navigable.View.js 1. Create an extensions directory to store your custom module. Depending on your implementation, this directory might already exist. 2. Within this directory, create a custom module with a name that is unique but similar to the module being customized. For example: Modules/extensions/Transaction.Line.Views.Extension@1.0.0. 3. Open your new Transaction.Line.Views.Extension@1.0.0 module and create a subfolder titled JavaScript. For example: Modules/extensions/Transaction.Line.Views.Extension@1.0.0/JavaScript SuiteCommerce Site Development Patch Instructions 4. In your new JavaScript subdirectory, create a JavaScript file to extend Transaction.Line.Views.Cell.Navigable.View.js. Name this file according to best practices. For example: Transaction.Line.Views.Cell.Navigable.View.Extend.js 5. Open this file and extend the getContext() method as shown in the following code snippet. define('Transaction.Line.Views.Cell.Navigable.View.Extend' , [ 'Transaction.Line.Views.Cell.Navigable.View' , 'underscore' , 'Backbone' ] , function ( TransactionLineViewsCellNavigableView , _ , Backbone ) { 'use strict'; _.extend(TransactionLineViewsOptionsSelectedView.prototype, { getContext: function () { var item = this.model.get('item') , line = this.model; s.detail3) //@class Transaction.Line.Views.Navigable.View.Context return { //@property {Transaction.Line.Model} model model: this.model //@property {String} itemId , itemId: item.get('internalid') //@property {String} itemName , itemName: item.get('_name') //@property {String} cellClassName , cellClassName: this.options.cellClassName //@property {Boolean} isNavigable , isNavigable: !!this.options.navigable && !!item.get('_isPurchasable') //@property {String} rateFormatted , rateFormatted: line.get('rate_formatted') //@property {Boolean} showOptions , showOptions: !!(line.get('options') && line.get('options').length) //@property {String} itemURLAttributes , itemURLAttributes: line.getFullLink({quantity:null,location:null,fulfillmentChoice:null}) //@property {Number} quantity , quantity: line.get('quantity') //@property {Boolean} showDetail2Title , showDetail2Title: !!this.options.detail2Title //@property {String} detail2Title , detail2Title: this.options.detail2Title //@property {String} detail2 , detail2: line.get(this.options.detail2) //@property {Boolean} showBlockDetail2 , showBlockDetail2: !!line.get(this.options.detail2) //@property {Boolean} showDetail3Title , showDetail3Title: !!this.options.detail3Title //@property {String} detail3Title , detail3Title: this.options.detail3Title //@property {String} detail3 , detail3: line.get('amount') > line.get('total') ? line.get('total_formatted') : line.get(this.option //@property {Boolean} showComparePrice showComparePrice: line.get('amount') > line.get('total') //@property {String} comparePriceFormatted , comparePriceFormatted: line.get('amount_formatted') // @property {ImageContainer} thumbnail , thumbnail: this.model.getThumbnail() // @property {Boolean} isFreeGift , isFreeGift: line.get('free_gift') === true , }; SuiteCommerce Site Development 445 Patch Instructions }); }); 446 } 6. Save the file. Step 2: Prepare the Developer Tools For Your Customization 1. Open your new Transaction.Line.Views.Extension@1.0.0 module directory. 2. Create a file in this directory titled ns.package.json. Modules/extensions/Transaction.Line.Views.Extension@1.0.0/ns.package.json 3. Paste the following code into your new ns.package.json file: { } "gulp": { "javascript": [ "JavaScript/*.js" ] } 4. Open the distro.json file. This is located in your root directory. 5. Add your custom module to the modules object. Your code should look similar to: { "name": "SuiteCommerce Advanced Aconcagua", "version": "2.0", "isSCA": true, "buildToolsVersion": "aconcaguaR2", "folders": { "modules": "Modules", "suitecommerceModules": "Modules/suitecommerce", "extensionsModules": "Modules/extensions", "thirdPartyModules": "Modules/third_parties", "distribution": "LocalDistribution", "deploy": "DeployDistribution" }, "modules": { "extensions/Transaction.Line.Views.Extension": "1.0.0", "suitecommerce/Account": "aconcaguaR2", ... This step ensures that the Gulp tasks include your module when you deploy. In this example, the custom modules are added at the beginning of the list of modules. However, you can add the modules anywhere in the modules object. The order of precedence in this list does not matter. 6. Add Transaction.Line.Views.Cell.Navigable.View.Extend as a dependency to SCA entry point within the SC.Checkout.Starter entrypoint of the JavaScript array. Your distro.js file should look similar to: "tasksConfig": { //... "javascript": [ //... { "entryPoint": "SC.Checkout.Starter", "exportFile": "checkout.js", "dependencies": [ //... "StoreLocator", "SC.CCT.Html", "Transaction.Line.Views.Cell.Navigable.View.Extend" SuiteCommerce Site Development Patch Instructions ], 447 //... 7. Save the distro.json file. Step 3: Test and Deploy Your Customization 1. Test your source code customizations on a local server (see SCA on a Local Server) or deploy them to your NetSuite account (see Deploy to NetSuite). If you are currently running SCA on a local server, your changes should appear on your local site immediately. 2. Confirm your results. Upon successful deployment, Checkout Summary pages should display correct original and discounted sub-total amounts. Strike-through amounts also display correctly. DeployDistribution Folder Does Not Include Local Files Applies to: SuiteCommerce Advanced | Aconcagua In some implementations of the Aconcagua R2 release of SuiteCommerce Advanced, local files are not deploying to the DeployDistribution folder after running the gulp deploy command using the developer tools. As a consequence, accessing Local SSP pages result in a Page Not Found error. This problem occurs because the R2 release of Aconcagua did not include three important files. This patch adds these files to your implementation. To implement this patch, you must add the following files to your source and deploy: ■ CheckoutApplication@aconcaguaR2\Internal\ index-local.ssp ■ MyAccountApplication@aconcaguaR2\Internal\ index-local.ssp ■ ShoppingApplication@aconcaguaR2\Internal\ index-local.ssp Because these files do not exist, you cannot use traditional best practices, such as extending or overriding. This instruction simply requires adding three files, renaming them to match the applicable module, and deploying. Step 1: Download the Patch Files 1. Download the .zip file containing the three local.ssp files here: LocalFilesNotDeployingAconcaguaR2.zip. This zip file includes the following files: ■ checkout-local.ssp ■ my_account-local.ssp ■ shopping-local.ssp 2. Extract the contents of this file to any location locally. 3. For the Checkout application: a. Copy checkout-local.ssp to the CheckoutApplication@aconcaguaR2/Internal folder. If the Internal folder does not exist, create it. b. Rename checkout-local.ssp to index-local.ssp. 4. For the MyAccount application: SuiteCommerce Site Development Patch Instructions a. 448 Copy myaccount-local.ssp to the MyAccountApplication@aconcaguaR2/Internal folder. If the Internal folder does not exist, create it. b. Rename myaccount-local.ssp to index-local.ssp. 5. For the Shopping application: a. Copy shopping-local.ssp to the ShoppingApplication@aconcaguaR2/Internal folder. If the Internal folder does not exist, create it. b. Rename shopping- local.ssp to index-local.ssp. Your source directory structure should look like this: ... CheckoutApplication@aconcaguaR2/ Internal/ index-local.ssp ... MyAccountApplication@aconcaguaR2/ Internal/ index-local.ssp ... ShoppingApplication@aconcaguaR2/ Internal/ index-local.ssp .... Step 2: Deploy Your Customization 1. Deploy your source code customizations to your NetSuite account and test the functionality. See Deploy to NetSuite for details. Note: Since this patch adds SuiteScript files, changes are not visible in your local environment. SuiteScript files run on the server and must be deployed to NetSuite to take effect. 2. Confirm your results. Upon successful deployment, local files should exist in your DeployDistribution folder. HTML List Styles Do Not Display Applies to: SuiteCommerce | SuiteCommerce Advanced | Aconcagua | Kilimanjaro | Elbrus | Vinson In some implementations of SuiteCommerce and SuiteCommerce Advanced, editing item descriptions on an Item record (Web Store tab, Detailed Description field) using <li> and <ul> styles does not display as expected in the webstore. This patch corrects this issue. However, the correct patching instructions depend on your implementation, as described below: Implementation Patching Instructions SCA Kilimanjaro HTML List Styles Do Not Display (Kilimanjaro) SCA Vinson, Elbrus HTML List Styles Do Not Display (Elbrus and Vinson) Any theme created using the 2018.1 release of the SuiteCommerce Base Theme bundle HTML List Style Does Not Display (Theme) SuiteCommerce Site Development Patch Instructions 449 HTML List Styles Do Not Display (Kilimanjaro) Applies to: SuiteCommerce Advanced | Kilimanjaro Apply the changes in this patch using the override method, as described in this section. The following table lists the files to be overridden and their locations in the source code: Module Location File BaseSassStyles _base.scss ProductDetails _product-details-information.scss You can download the code samples described in this procedure here: HtmlListStyleNotDisplayingKilimanjaro.zip Step 1: Create the Override File 1. Create an extensions directory to store your custom module. Depending on your implementation, this directory might already exist. 2. Within this directory, create a custom module with a name that is unique, but similar to each module being customized. Give these new modules a version of 1.0.0. Your implementation should look like this: ■ Modules/extensions/BaseSassStylesExtension@1.0.0 ■ Modules/extensions/ProductDetailsExtension@1.0.0 3. Open your new BaseSassStylesExtension@1.0.0 module and create nested subfolders titled Sass and base. For example: Modules/extensions/BaseSassStylesExtension@1.0.0/Sass/base 4. Open your new ProductDetailsExtension@1.0.0 module and create a subfolder titled Sass. For example: Modules/extensions/ProductDetailsExtension@1.0.0/Sass 5. Copy the following source files and paste into the correct location, where X.Y.Z represents the version of the module in your implementation of SuiteCommerce Advanced: Copy This File: Place a Copy Here: Modules/suitecommerce/BaseSassStyles@X.Y.Z/Sass/base/_ base.scss Modules/extensions/BaseSassStyles@1.0.0/Sass/ base Modules/suitecommerce/ProductDetails@X.Y.Z/Sass/_product- Modules/extensions/ProductDetails@1.0.0/Sass details-information.scss 6. Open your new copy of _base.scss and add the following lines to the end of file: .cms-content ul, .cms-content ol { margin-left: $sc-margin-lv4; } .cms-content ul li { list-style: circle; } .cms-content ol li { list-style: decimal; } 7. Save the file. SuiteCommerce Site Development Patch Instructions 450 8. Open your new copy of _product-details-information.scss and add the following lines to the end of file: .product-details-information-tab-content-container ul, .product-details-information-tab-content-container ol margin-left: $sc-margin-lv4; } { .product-details-information-tab-content-container ul li { list-style: outside; } .product-details-information-tab-content-container ol li { list-style: decimal; } 9. Save the file. Step 2: Prepare the Developer Tools For Your Customization 1. Open your Modules/extensions/BaseSassStyles@1.0.0 module. 2. Create a file in this directory titled ns.package.json. For example: Modules/extensions/BaseSassStyles@1.0.0/ns.package.json 3. Paste the following code in your new ns.package.json file: Important: You must replace the string X.Y.Z with the version of the module in your implementation of SuiteCommerce Advanced. { } "gulp": { "sass": [ "Sass/**/*.scss" ] }, "overrides": { "suitecommerce/BaseSassStyles@X.Y.Z/Sass/base/_base.scss" : "Sass/base/_base.scss" } 4. Save the file. 5. Open your Modules/extensions/ProductDetails@1.0.0 module. 6. Create a file in this directory titled ns.package.json. For example: Modules/extensions/ProductDetails@1.0.0/ns.package.json 7. Paste the following code in your new ns.package.json file: Important: You must replace the string X.Y.Z with the version of the module in your implementation of SuiteCommerce Advanced. { "gulp": { "sass": [ "Sass/**/*.scss" ] }, "overrides": { "suitecommerce/ProductDetails@X.Y.Z/Sass/_product-details-information.scss" : "Sass/_product-details-informa tion.scss" } } SuiteCommerce Site Development Patch Instructions 451 8. Open the distro.json file. This file is located in your root directory. 9. Add both custom modules to the modules object. Your code should look similar to: { "name": "SuiteCommerce Advanced Kilimanjaro", "version": "2.0", "isSCA": true, "buildToolsVersion": "1.3.1", "folders": { "modules": "Modules", "suitecommerceModules": "Modules/suitecommerce", "extensionsModules": "Modules/extensions", "thirdPartyModules": "Modules/third_parties", "distribution": "LocalDistribution", "deploy": "DeployDistribution" }, "modules": { "extensions/BaseSassStylesExtension": "1.0.0", "extensions/ProductDetailsExtension": "1.0.0", "extensions/MyExampleCartExtension1": "1.0.0", ... This step ensures that the Gulp tasks include your module when you deploy. In this example, the custom modules are added at the beginning of the list of modules. However, you can add the modules anywhere in the modules object. The order of precedence in this list does not matter. 10. Save the distro.json file. Step 3: Test and Deploy Your Customization 1. Test your source code customizations on a local server (see SCA on a Local Server) or deploy them to your NetSuite account (see Deploy to NetSuite). If you are currently running SCA on a local server, your changes should appear on your local site immediately. 2. Confirm your results. Upon successful deployment, the HTML list (<li> and <ul>) styles should display on your webstore. HTML List Styles Do Not Display (Elbrus and Vinson) Applies to: SuiteCommerce Advanced | Elbrus | Vinson Apply the changes in this patch using the override method, as described in this section. The following table lists the files to be overridden and their locations in the source code: Module Location File BaseSassStyles _base.scss ProductDetails _product-details-information.scss You can download the code samples described in this procedure here: HtmlListStylesNotDisplayingEbrus-Vinson.zip Step 1: Create the Override File 1. Create an extensions directory to store your custom module. Depending on your implementation, this directory might already exist. SuiteCommerce Site Development Patch Instructions 452 2. Within this directory, create a custom module with a name that is unique, but similar to each module being customized. Give these new modules a version of 1.0.0. Your implementation should look like this: ■ Modules/extensions/BaseSassStylesExtension@1.0.0 ■ Modules/extensions/ProductDetailsExtension@1.0.0 3. Create a subfolder for each new module titled Sass. Your file structure should look like: ■ Modules/extensions/BaseSassStylesExtension@1.0.0/Sass ■ Modules/extensions/ProductDetailsExtension@1.0.0/Sass 4. Copy the applicable source files and paste into the correct location, where X.Y.Z represents the version of the module in your implementation of SuiteCommerce Advanced: Copy This File: Place a Copy Here: Modules/suitecommerce/BaseSassStyles@X.Y.Z/Sass/_base.scss Modules/extensions/BaseSassStyles@1.0.0/ Sass Modules/suitecommerce/ProductDetails@X.Y.Z/Sass/_productdetails-information.scss Modules/extensions/ProductDetails@1.0.0/Sass 5. Open your new copy of _base.scss and add the following lines to the end of file: .cms-content ul, .cms-content ol { margin-left: $sc-margin-lv4; } .cms-content ul li { list-style: circle; } .cms-content ol li { list-style: decimal; } 6. Save the file. 7. Open your new copy of _product-details-information.scss and add the following lines to the end of file: .product-details-information-tab-content-container ul, .product-details-information-tab-content-container ol { margin-left: $sc-margin-lv4; } .product-details-information-tab-content-container ul li { list-style: outside; } .product-details-information-tab-content-container ol li { list-style: decimal; } 8. Save the file. Step 2: Prepare the Developer Tools For Your Customization 1. Create an ns.package.json file for each custom module. a. Open your Modules/extensions/BaseSassStyles@1.0.0 module. b. Create a file in this directory titled ns.package.json. For example: Modules/extensions/BaseSassStyles@1.0.0/ns.package.json SuiteCommerce Site Development Patch Instructions c. 453 Paste the following code in your new ns.package.json file: Important: You must replace the string X.Y.Z with the version of the module in your implementation of SuiteCommerce Advanced. { } "gulp": { "sass": [ "Sass/**/*.scss" ] }, "overrides": { "suitecommerce/BaseSassStyles@X.Y.Z/Sass/_base.scss" : "Sass/_base.scss" } d. Save the file. e. Open your Modules/extensions/ProductDetails@1.0.0 module. f. Create a file in this directory titled ns.package.json. For example: Modules/extensions/ProductDetails@1.0.0/ns.package.json g. Paste the following code in your new ns.package.json file: Important: You must replace the string X.Y.Z with the version of the module in your implementation of SuiteCommerce Advanced. { "gulp": { "sass": [ "Sass/**/*.scss" ] }, "overrides": { "suitecommerce/ProductDetails@X.Y.Z/Sass/_product-details-information.scss" : "Sass/_product-details-informa tion.scss" } } h. Save the file. 2. Edit your distro.json file. This step ensures that the Gulp tasks include your module when you deploy. In this example, the custom modules are added at the beginning of the list of modules. However, you can add the modules anywhere in the modules object. The order of precedence in this list does not matter. a. Open the distro.json file. This file is located in your root directory. b. Add both custom modules to the modules object. Your code should look similar to: { "name": "SuiteCommerce Advanced Elbrus", "version": "2.0", "buildToolsVersion": "1.3.0", "folders": { "modules": "Modules", "suitecommerceModules": "Modules/suitecommerce", "extensionsModules": "Modules/extensions", "thirdPartyModules": "Modules/third_parties", "distribution": "LocalDistribution", "deploy": "DeployDistribution" }, SuiteCommerce Site Development Patch Instructions 454 "modules": { "extensions/BaseSassStylesExtension": "1.0.0", "extensions/ProductDetailsExtension": "1.0.0", "extensions/MyExampleCartExtension1": "1.0.0", ... c. Save the distro.json file. Step 3: Test and Deploy Your Customization 1. Test your source code customizations on a local server (see SCA on a Local Server) or deploy them to your NetSuite account (see Deploy to NetSuite). If you are currently running SCA on a local server, your changes should appear on your local site immediately. 2. Confirm your results. Upon successful deployment, the HTML list (<li> and <ul>) styles should display on your webstore. HTML List Style Does Not Display (Theme) Applies to: SuiteCommerce | SuiteCommerce Advanced The instructions in the section apply to you if you are implementing themes and you are implementing a theme created using the SuiteCommerce Base Theme (2018.1 release) as a baseline. This topic explains how to correct the theme manually using the theme developer tools. Because you cannot patch a theme and you cannot make changes to a published theme, you have three options, depending on your implementation. ■ If the theme exhibiting this behavior is a published theme and you want to make the changes yourself, you must create a new theme using the theme developer tools, applying the new code as described in this section. ■ If the theme is owned by you, you can make changes to your theme using the theme developer tools as described in this section. ■ If this is a published theme and you do not want to make this change manually, you must wait until the theme publisher provides an update or use a different theme. This fix requires adding some code to the theme’s existing Sass files. This step is the same if you own the theme or not. If you do not own the theme, the developer tools prompt you to create a new one when you deploy your changes. You can download the code samples described in this procedure here: HtmlListStyleNotDisplayingThemes.zip Note: Any themes created using the SuiteCommerce Base Theme (2018.2 release and later) already include this fix. Step 1: Fetch the Active Theme To make the change, the first step is to fetch the theme files from NetSuite and place them in your local developer environment. This step assumes that you have already set up your local developer environment and are using the applicable theme developer tools. See Developer Environment for more details. To fetch the theme: 1. Ensure that the theme exhibiting this behavior is activated on a domain associated with your site. See the help topic Manage Themes and Extensions for details. 2. Open a command line or terminal. SuiteCommerce Site Development Patch Instructions 455 3. Access the top-level theme development directory you created when you downloaded the developer tools. 4. Enter the following command: gulp theme:fetch 5. Follow the prompts to access your account, website, and the domain that currently has the theme activated. Step 2: Customize the Theme The next step is to customize your theme by editing two .scss files. To customize the theme: 1. In your theme development source code, navigate to the following location: <THEME_DEV_TOOLS_DIRECTORY>/Workspace/<THEME_NAME>/Modules/BaseSassStyles@X.Y.Z/Sass/base In this example, X.Y.Z represents the version of the BaseSassStyles module in your theme. 2. Open _base.scss and add the following lines to the end of file: .cms-content ul, .cms-content ol { margin-left: $sc-margin-lv4; } .cms-content ul li { list-style: circle; } .cms-content ol li { list-style: decimal; } 3. Save the file. 4. Navigate to the following location: ../Modules/ProductDetails@X.Y.Z/Sass In this example, X.Y.Z represents the version of the ProductDetails module in your theme. 5. Open _product-details-information.scss and add the following lines to the end of file: .product-details-information-tab-content-container ul, .product-details-information-tab-content-container ol { margin-left: $sc-margin-lv4; } .product-details-information-tab-content-container ul li { list-style: outside; } .product-details-information-tab-content-container ol li { list-style: decimal; } 6. Save the file. Step 3: Deploy Your Changes This step involves deploying your changes to a NetSuite account and activating on a domain. The steps are the same, regardless of the state of your theme, but the developer tools perform different actions, as described below: SuiteCommerce Site Development Patch Instructions 456 ■ If you own the theme, the developer tools prompt you to include a new revision number. You can later update any bundles that include the theme for publication. ■ If you do not own the theme, the developer tools prompt you to create a new one. This process results in a new theme that is based on the original, but includes your customizations. These changes do not affect the existing theme. Important: After you deploy the theme, you must activate the update to apply your changes to a domain. To deploy changes: 1. In your local developer environment, open a command line or terminal and access the top-level theme directory. 2. Run the following command: gulp theme:deploy 3. Follow the prompts to confirm your account, website, and other information about your theme, as required. If you are customizing a published theme, the developer tools prompt you to create a new theme. 4. After deployment is completed, activate the theme on a domain. See the help topic Manage Themes and Extensions for details. 5. Confirm your results. Upon successful deployment, the HTML list (<li> and <ul>) styles should display on your webstore. For more information: ■ To use theme developer tools, see Theme Developer Tools. ■ To create bundles for a theme, see Theme and Extension SuiteApps. Item Search Displays Incorrect Results Applies to: SuiteCommerce Advanced | Elbrus In some implementations of the Elbrus release of SuiteCommerce Advanced, the application returns incorrect results when entering more than one term in the search criteria. The following patch corrects a problem in ItemsSearcher.View.js, which is part of the ItemsSearcher module. To implement this patch, create a custom module to change the defaultOptions.highlightFirst property. You can download the code samples described in this procedure here: ElbrusItemSearchResultsIncorrect.zip. Note: Before proceeding, familiarize yourself with Best Practices for Customizing SuiteCommerce Advanced. Step 1: Extend ItemsSearcher.View.js 1. Create an extensions directory to store your custom module. Depending on your implementation, this directory might already exist. 2. Within this directory, create a custom module with a name similar to the module being customized. For example: Modules/extensions/ItemsSearcherExtension@1.0.0. 3. In your new ItemsSearcherExtension@1.0.0 module, create a subdirectory called JavaScript. SuiteCommerce Site Development Patch Instructions For example: Modules/extensions/ItemsSearcherExtension/JavaScript 4. In your new JavaScript subdirectory, create a JavaScript file. Name this file according to best practices. For example: ItemsSearcher.View.Extend.js 5. Open this file and extend ItemsSearcher.View.js to customize the highlightFirst property from true to false, as shown in the following code snippet. define( 'ItemsSearcher.View.Extend' , [ 'ItemsSearcher.View' ] , function ( ItemsSearcherView ) { 'use strict'; ItemSearcherView.prototype.defaultOptions.highlightFirst = false }); 6. Save the file. Step 2: Prepare the Developer Tools For Your Customization 1. Open your new ItemsSearcherExtension@1.0.0 module directory. 2. Create a file in this directory and name it ns.package.json. Modules/extensions/ItemsSearcherExtension@1.0.0/ns.package.json 3. Paste the following code into your new ns.package.json file: { } "gulp": { "javascript": [ "JavaScript/*.js" ] } 4. Open the distro.json file. This is located in your root directory. 5. Add your custom module to the modules object. Your code should look similar to the following example: { "name": "SuiteCommerce Advanced Elbrus", "version": "2.0", "buildToolsVersion": "1.3.0", "folders": { "modules": "Modules", "suitecommerceModules": "Modules/suitecommerce", "extensionsModules": "Modules/extensions", "thirdPartyModules": "Modules/third_parties", "distribution": "LocalDistribution", "deploy": "DeployDistribution" }, "modules": { "extensions/ItemsSearcherExtension": "1.0.0", "extensions/MyExampleCartExtension1": "1.0.0", //... SuiteCommerce Site Development 457 Patch Instructions 458 This ensures that the Gulp tasks include your module when you deploy. In this example, the custom modules are added at the beginning of the list of modules. However, you can add the modules anywhere in the modules object. The order of precedence in this list does not matter. 6. Add ItemsSearcher.View.Extend as a dependency to SCA entry point within the SC.Shopping.Starter entrypoint of the JavaScript array. Your distro.js file should look similar to the following: "tasksConfig": { //... "javascript": [ //... { "entryPoint": "SC.Shopping.Starter", "exportFile": "shopping.js", "dependencies": [ //... "StoreLocator", "SC.CCT.Html", "ItemsSearcher.View.Extend" ], //... 7. Save the distro.json file. Step 3: Test and Deploy Your Customization 1. Test your source code customizations on a local server (see SCA on a Local Server) or deploy them to your NetSuite account (see Deploy to NetSuite). If you are currently running SCA on a local server, your changes should appear on your local site immediately. 2. Confirm your results. Upon successful deployment, item search strings should display correct results. Category Product Lists Return Page Not Found Applies to: SuiteCommerce Advanced | 2018.2 In some implementations of the 2018.2 release of SuiteCommerce Advanced, category product lists return Page Not Found when viewing a table or list. The following patch corrects a problem in Facets.Translator.js, which is part of the Facets module. To implement this patch, create a custom module to extend the prototype object for the FacetsTranslator function. You can download the code samples described in this procedure here: CategoryPageNotFound.zip. Note: Before proceeding, familiarize yourself with Best Practices for Customizing SuiteCommerce Advanced. Step 1: Extend the Facets.Translator.js File 1. Create an extensions directory to store your custom module. Depending on your implementation, this directory might already exist. 2. Create a custom module with a name similar to the module being customized. For example, Modules/extensions/FacetsExtension@1.0.0. 3. In your new FacetsExtension@1.0.0 directory, create a subdirectory called JavaScript. SuiteCommerce Site Development Patch Instructions 459 For example: Modules/extensions/FacetsExtension@1.0.0/JavaScript 4. In your new JavaScript subdirectory, create a JavaScript file to extend Facets.Translator.js. Name this file according to best practices. For example: Facets.Translator.Extension.js 5. Open this file and extend the FacetsTranslator() method as shown in the following code snippet: define('Facets.Translator.Extension' , [ 'Facets.Translator' , 'underscore' , 'jQuery' , 'SC.Configuration' , 'Utils' , 'UrlHelper' ] , function ( FacetsTranslator , _ , jQuery , Configuration ) { 'use strict'; _.extend(FacetsTranslator.prototype, { FacetsTranslator (facets, options, configuration, category) { // Enforces new if (!(this instanceof FacetsTranslator)) { return new FacetsTranslator(facets, options, configuration, category); } // Facets go Here this.facets = []; // Other options like page, view, etc. goes here this.options = {}; // This is an object that must contain a fallbackUrl and a lists of facet configurations this.configuration = configuration || default_config; // Get the facets that are in the sitesettings but not in the config. // These facets will get a default config (max, behavior, etc.) - Facets.Translator // Include facet aliases to be conisdered as a possible route var facets_data = Configuration.get('siteSettings.facetfield') , facets_to_include = []; _.each(facets_data, function(facet) { if (facet.facetfieldid !== 'commercecategory') { facets_to_include.push(facet.facetfieldid); // If the facet has an urlcomponent defined, then add it to the possible values list. facet.urlcomponent && facets_to_include.push(facet.urlcomponent); } // Finally, include URL Component Aliases... _.each(facet.urlcomponentaliases, function(facet_alias) { facets_to_include.push(facet_alias.urlcomponent); }); }); facets_to_include = _.union(facets_to_include, _.pluck(Configuration.get('facets'), 'id')); facets_to_include = _.uniq(facets_to_include); SuiteCommerce Site Development Patch Instructions this.facetsToInclude = facets_to_include; this.isCategoryPage = !!category; if (_.isBoolean(category) && category) { var index = facets.length , facetsToInclude = this.facetsToInclude.slice(0) , facets_delimiter = this.configuration.facetDelimiters.betweenDifferentFacets , facet_value_delimiter = this.configuration.facetDelimiters.betweenFacetNameAndValue; facetsToInclude.push(this.configuration.facetDelimiters.betweenFacetsAndOptions); _.each(facetsToInclude, function(facetname) { facetname = facets_delimiter + facetname + facet_value_delimiter; var i = facets.lastIndexOf(facetname); if (i !== -1 && i < index) { index = i; } }); var categoryUrl = facets.substring(0, index); facets = facets.substring(index); if (categoryUrl[0] !== '/') { categoryUrl = '/' + categoryUrl; } if (categoryUrl[categoryUrl.length - 1] === '/') { categoryUrl = categoryUrl.substring(0, categoryUrl.length - 1); } if (facets && facets[0] === facets_delimiter) { facets = facets.substring(1, facets.length); } this.categoryUrl = categoryUrl; } else if (_.isString(category)) { this.categoryUrl = category; } } // We cast on top of the passed in parameters. if (facets && options) { this.facets = facets; this.options = options; } else if (_.isString(facets)) { // It's a url this.parseUrl(facets); } else if (facets) { // It's an API option object this.parseOptions(facets); } }); }); 6. Save the file. SuiteCommerce Site Development 460 Patch Instructions 461 Step 2: Prepare the Developer Tools For Your Customization 1. Open your new FacetsExtension@1.0.0 module directory. 2. Create a file in this directory and name it ns.package.json. Modules/extensions/FacetsExtension@1.0.0/ns.package.json 3. Build the ns.package.json file using the following code: { } "gulp": { "javascript": [ "JavaScript/*.js" ] } 4. Open the distro.json file. This is located in your root directory. 5. Add your custom modules to the modules object. Your code should look similar to the following example: { "name": "SuiteCommerce Advanced 2018.2.0 (sc-2018.2.0)", "version": "2.0", "isSCA": true, "buildToolsVersion": "sc-2018.2.0", "folders": { "modules": "Modules", "suitecommerceModules": "Modules/suitecommerce", "extensionsModules": "Modules/extensions", "thirdPartyModules": "Modules/third_parties", "distribution": "LocalDistribution", "deploy": "DeployDistribution" }, "modules": { "extensions/FacetsExtension": "1.0.0", "suitecommerce/Account": "sc-2018.2.0", //... This step ensures that the Gulp tasks include your module when you deploy. In this example, the custom modules are added at the beginning of the list of modules. However, you can add the modules anywhere in the modules object. The order of precedence in this list does not matter. 6. Add Facets.Translator.Extension as a dependency to SCA entry point within the SC.Shopping.Starter entrypoint of the JavaScript array. Your distro.js file should look similar to: "tasksConfig": { //... "javascript": [ //... { "entryPoint": "SC.Shopping.Starter", "exportFile": "shopping.js", "dependencies": [ //... "Instrumentation.Cart", "SiteSearch", "Facets.Translator.Extension" ], //... 7. Save the distro.json file. SuiteCommerce Site Development Patch Instructions 462 Step 3: Test and Deploy Your Customization 1. Test your source code customizations on a local server (see SCA on a Local Server) or deploy them to your NetSuite account (see Deploy to NetSuite). If you are currently running SCA on a local server, your changes should appear on your local site immediately. 2. Confirm your results. Upon successful deployment, Commerce Categories filter based on the selected facet values. Cannot Test an Extension on a Local Server Applies to: SuiteCommerce Advanced | 2018.2 In some 2018.2 implementations of SuiteCommerce Advanced, developers might experience the following console error when testing an extension on a local server: TypeError: SC.addExtensionModule is not a function. The patch instructions described below correct this error. To implement this patch, you must create two custom modules to override different instances of index-local.ssp. These files are located in the Internals directory of the following modules (where X.Y.Z represents the version of the module in your implementation): ■ CheckoutApplication@X.Y.Z ■ MyAccountApplication@X.Y.Z You can download the code samples described in this procedure here: RunExtensionsOnALocalServer.zip. Note: In general, NetSuite best practice is to extend JavaScript using the JavaScript prototype object. This improves the chances that your customizations continue to work when migrating to a newer version of SuiteCommerce Advanced. However, this patch requires you to modify a file in a way that you cannot extend, and therefore requires you to use a custom module to override the existing module file. For more information, see Customize and Extend Core SuiteCommerce Advanced Modules. Step 1: Create the Override Files 1. Create an extensions directory to store each of your new custom modules. Depending on your implementation, this directory might already exist. Create two custom modules and give them names similar to the modules being customized. For example, create the following files: Modules/extensions/CheckoutApplicationExtension@1.0.0 Modules/extensions/MyAccountApplicationExtension@1.0.0 2. In each module, create a subdirectory called Internal. For example: ■ Modules/extensions/CheckoutApplicationExtension@1.0.0/Internal ■ Modules/extensions/MyAccountApplicationExtension@1.0.0/Internal 3. Copy the following source files and paste into the correct location: Copy This File: Place a Copy Here: Modules/suitecommerce/ Modules/extensions/CheckoutApplicationExtension@1.0.0/ CheckoutApplication@X.Y.Z/Internal/index-local.ssp Internal SuiteCommerce Site Development Patch Instructions Copy This File: Place a Copy Here: Modules/suitecommerce/ MyAccountApplication@X.Y.Z/Internal/indexlocal.ssp Modules/extensions/MyAccountApplicationExtension@1.0.0/ Internal In this example, X.Y.Z represents the version of the module in your implementation of SuiteCommerce Advanced. 4. For each new copy of index-local.ssp, add the following lines after the loadscript() function: SC.extensionModules = []; SC.addExtensionModule = function addExtensionModule(appModuleName) { SC.extensionModules.push(appModuleName); }; Each file should look similar to the following example: //... function loadScript (url) { 'use strict'; var reference_tag = document.getElementsByTagName("script")[0]; var new_script_tag = document.createElement("script"); new_script_tag.src = url; new_script_tag.type = "text/javascript"; new_script_tag.async = false; reference_tag.parentNode.insertBefore(new_script_tag, reference_tag); } SC.extensionModules = []; SC.addExtensionModule = function addExtensionModule(appModuleName) { SC.extensionModules.push(appModuleName); }; //... 5. Save each file. Step 2: Prepare the Developer Tools For Your Customization 1. Create a file called ns.package.json in each of your custom modules. For example: ■ Modules/extensions/CheckoutApplicationExtension@1.0.0/ns.package.json ■ Modules/extensions/MyAccountApplicationExtension@1.0.0/ns.package.json 2. Paste the following code in each ns.package.json file, as applicable: CheckoutApplication { } "gulp": { "ssp-files": [ "Internal/*.ssp" ] }, "overrides": { "suitecommerce/CheckoutApplication@X.Y.Z/Internal/index-local.ssp" : "Internal/index-local.ssp" } MyAccountApplication { SuiteCommerce Site Development 463 Patch Instructions } 464 "gulp": { "ssp-files": [ "Internal/*.ssp" ] }, "overrides": { "suitecommerce/MyAccountApplication@X.Y.Z/Internal/index-local.ssp" : "Internal/index-local.ssp" } Important: You must replace the string X.Y.Z with the version of the module in your implementation of SuiteCommerce Advanced. 3. Open the distro.json file. This file is located in your root directory. 4. Add both custom modules to the modules object. Your code should look similar to the following example: { "name": "SuiteCommerce Advanced 2018.2.0", "version": "2.0", "isSCA": true, "buildToolsVersion": "1.3.1", "folders": { "modules": "Modules", "suitecommerceModules": "Modules/suitecommerce", "extensionsModules": "Modules/extensions", "thirdPartyModules": "Modules/third_parties", "distribution": "LocalDistribution", "deploy": "DeployDistribution" }, "modules": { "extensions/CheckoutApplicationExtension": "1.0.0", "extensions/MyAccountApplicationExtension": "1.0.0", "suitecommerce/Account": "sc-2018.2.0", ... This step ensures that the Gulp tasks include your module when you deploy your code to NetSuite. In this example, the custom modules are added at the beginning of the list of modules. However, you can add the modules anywhere in the modules object. The order of precedence in this list does not matter. 5. Save the distro.json file. Step 3: Test and Deploy Your Customization 1. Deploy your changes to your NetSuite account (see Deploy to NetSuite). If you are currently running SCA on a local server, your changes should appear on your local site immediately. Note: Because this patch modifies an SSP library file, changes are not visible in your local environment until you first deploy the customizations to NetSuite. 2. Confirm your results. Upon successful deployment, you should be able to test your extensions on a local server. Secure Shopping for Site Builder Implementations Applies to: Site Builder | Vinson | pre-Denali A secure shopping domain creates an encrypted connection between your web server and your customer’s web browser. You can use an SSL certificate to secure the shopping portion of your web SuiteCommerce Site Development Patch Instructions 465 store under an HTTPS domain on your Site Builder sites. HTTPS is currently the industry standard for ecommerce services and consumers prefer seeing the secure icon in their browser address bar. Important: If setting up Secure Shopping on a Site Builder site, you must set up the shopping portion of your site to use an HTTPS domain. You cannot set up a single secure domain for Shopping and Checkout. Some Site Builder implementations must be patched to take advantage of this functionality. Refer to the following table to determine if you need this patch: Implementation Instructions Site Builder No patch required. See the help topic Set Up a Domain for instructions on setting up Secure Shopping for your site. ■ Site Builder Extensions Premium Kilimanjaro No patch required. See the help topic Set Up a Domain for instructions on setting up Secure Shopping for your site. ■ Site Builder Extensions Kilimanjaro ■ Site Builder Extensions Premium Elbrus ■ Site Builder Extensions Elbrus ■ Site Builder Extensions Premium Vinson ■ Site Builder Extensions Vinson ■ Reference Checkout 2.05 ■ Reference Checkout 2.04 Patch required. See Secure Shopping for Site Builder Extensions (Vinson) for instructions. Patch required. See Secure Shopping for Site Builder (Pre-Denali) for instructions. ■ Reference My Account Premium 1.06 ■ Reference My Account 1.06 ■ Reference My Account Premium 1.05 ■ Reference My Account 1.05 Secure Shopping for Site Builder Extensions (Vinson) Applies to: Site Builder This topic explains how to patch the following implementations of Site Builder to take advantage of Secure Shopping domains: ■ SiteBuilder Extensions Vinson ■ SiteBuilder Extensions Premium Vinson Note: Site Builder sites implementing the Kilimanjaro or Elbrus releases of Site Builder Extensions and Extensions Premium already include the ability to create a secure Shopping domain by default and do not require a patch. Denali and Mont Blanc Site Builder implementations cannot set up secure Shopping domains. Note: To patch pre-Denali reference implementations for Site Builder, see Secure Shopping for Site Builder (Pre-Denali). Follow these steps to set up a secure Shopping domain for your Site Builder Extensions implementation: SuiteCommerce Site Development Patch Instructions 466 1. Configure a Secure Shopping Domain 2. Apply Patch to Source Files 3. Deploy Files To leverage a secure shopping domain in your implementation of Site Builder Extensions, you need to introduce these changes as custom modules and deploy using the Core SCA developer tools. This patch is highly technical and involves customizing multiple files. Configure a Secure Shopping Domain Applies to: Site Builder Before can use an SSL certificate to secure the shopping portion of your web store under an HTTPS domain, you must set up a secure shopping domain in NetSuite. See the help topic Set Up a Domain for more information. When setting up a secure domain, be aware that sites implementing Site Builder can only secure the shopping portion of the web store under a separate HTTPS domain. Site Builder sites cannot implement a single secure domain for both Shopping and Checkout applications. When you have configured your domain, continue with the next step: Apply Patch to Source Files. Apply Patch to Source Files Applies to: Site Builder Apply the changes in this patch using the Override method, as described in this section. The following table lists the files to be overridden and their locations in the Vinson source code, where X.Y.Z represents the version of the module in your implementation: Module Subdirectory File CheckoutApplication@X.Y.Z /Internal /index-local.ssp /JavaScript /SC.Checkout.Configuration.js /SuiteScript /checkout.environment.ssp /SuiteScript/checkout.ssp CheckoutSkipLogin@X.Y.Z /JavaScript /CheckoutSkipLogin.js GoogleUniversalAnalytics@X.Y.Z /JavaScript /GoogleUniversalAnalytics.js LiveOrder@X.Y.Z /SuiteScript /LiveOrder.Model.js MyAccountApplication@X.Y.Z /Internal /index-local.ssp /SuiteScript /my_account.ssp /SuiteScript /myaccount.environment.ssp NavigationHelper@X.Y.Z /JavaScript /NavigationHelper.Plugins.DataTouchPoint.js ProductList@X.Y.Z /SuiteScript /ProductList.Model.js SuiteCommerce Site Development Patch Instructions Module Subdirectory File Profile@X.Y.Z /SuiteScript /ProductList.Model.js 467 /Profile.Model.js SiteSettings@X.Y.Z /SuiteScript /SiteSettings.Model.js SspLibraries@X.Y.Z /SuiteScript /Application.js /ServiceController.Validations.js /Utils.js Utilities@X.Y.Z /JavaScript /Utils.js jQueryExtras@X.Y.Z /JavaScript /jQuery.ajaxSetup.js /JavaScript /jQuery.ajaxSetup.noLoader.js Note: In general, NetSuite best practice is to extend JavaScript using the JavaScript prototype object. This improves the chances that your customizations continue to work when migrating to a newer version of SuiteCommerce Advanced. However, this patch requires you to modify files in a way that you cannot extend, and therefore requires you to use a custom module to override the existing module file. For more information, see Customize and Extend Core SuiteCommerce Advanced Modules. Create Override Files The first step is to create a space to contain your customized files. You set up your new files to override the existing code when you deploy to NetSuite. To create override files: 1. Open the Modules directory and create a subdirectory titled extensions to maintain your customizations. 2. In your extensions directory, create a new directory for each module according to the table above. Give these new modules a version of 1.0.0. For example: Modules/extensions/CheckoutApplication@1.0.0/ Modules/extensions/CheckoutSkipLogin@1.0.0/ Modules/extensions/GoogleUniversalAnalytics@1.0.0/ ... 3. In each new module directory, create the required subdirectories according to the table above. For example, the directory structure for your custom CheckoutApplication@1.0.0 module should look similar to the following: Modules/extensions/CheckoutApplication@1.0.0 /Internal /JavaScript /SuiteScript 4. Locate the files in your current implementation to be overridden according to the table. 5. Make a copy of each file and paste the copy into the applicable subdirectory. SuiteCommerce Site Development Patch Instructions 468 For example, your directory structure for your custom CheckoutApplication@1.0.0 module should look similar to the following: Modules/extensions/CheckoutApplication@1.0.0/ Internal/ index-local.ssp JavaScript/ SC.Checkout.Configuration.js SuiteScript/ checkout.environment.ssp 6. Repeat this procedure for each file you need to override. Implement the Patch Changes The next step is to implement the patch in each new override file. To implement the patch: 1. Download the .patch file associated with this patch guide here: HTTPS_SiteBuilder-Vinson.zip. This file includes all changes described in this procedure. 2. Open each new file within your extensions directory and add or remove lines (as applicable) according to the .patch file. See the help topic How to Apply .patch Files for instructions on how to understand .patch files and apply changes. The following example describes one scenario. Example The following code snippet comes from the Vinson Site Builder Extensions Premium .patch file: ... diff --git a/Modules/suitecommerce/CheckoutApplication@2.2.0/JavaScript/SC.Checkout.Configuration.js b/Modules/suitecommerce/Check outApplication@2.2.0/JavaScript/SC.Checkout.Configuration.js index 48cd87d..8dbc7eb 100644 --- a/Modules/suitecommerce/CheckoutApplication@2.2.0/JavaScript/SC.Checkout.Configuration.js +++ b/Modules/suitecommerce/CheckoutApplication@2.2.0/JavaScript/SC.Checkout.Configuration.js @@ -62,15 +62,15 @@ define( ,*/ + currentTouchpoint: _.isSecureDomain() ? 'checkout' : 'viewcart' currentTouchpoint: Utils.isInShopping() ? 'viewcart' : 'checkout' , ... modulesConfig: { 'ItemDetails': {startRouter: true} In this example, these lines specify that the file you need to customize is SC.Checkout.Configuration.js: diff --git a/Modules/suitecommerce/CheckoutApplication@2.2.0/JavaScript/SC.Checkout.Configuration.js b/Modules/suitecommerce/Check outApplication@2.2.0/JavaScript/SC.Checkout.Configuration.js The next lines in the example provide a reference point to locate the code in the file that needs updated. Two sets of @@ symbols specify that the code to be customized is located on line 62 of the file and that 15 lines of code are displayed. The code after this reference is included as a visual reference to help locate the code affected by this change: @@ -62,15 +62,15 @@ define( SuiteCommerce Site Development Patch Instructions 469 ,*/ Important: The line reference (@@) specifies the line in the original source code. If you have made any preexisting modifications to the file prior to this patch, the code needing customized code may be located on a different line. Any lines prepended with a – symbol indicate code to delete/remove as part of this patch. In this example, you remove the following line from SC.Checkout.Configuration.js: - currentTouchpoint: _.isSecureDomain() ? 'checkout' : 'viewcart' Lines prepended with a + symbol indicate code to add. In this example, you add the following line: + currentTouchpoint: Utils.isInShopping() ? 'viewcart' : 'checkout' Lines not prepended with a – or + symbol do not require change. See How to Apply .patch Files for more information on how to apply these changes manually. Deploy Files Applies to: Site Builder When all customizations are complete, you are ready to deploy your custom files to your Site Builder SSP Application in NetSuite. The following topics explain how to deploy custom files to the Custom implementation: ■ Prepare the Developer Tools For Your Customizations ■ Deploy Your Customizations to NetSuite Important: The customizations introduced by this patch are extensive. Always test changes in a sandbox account or other test site before deploying to a production account. Prepare the Developer Tools For Your Customizations Before you deploy your changes, you must prepare your Vinson developer tools to include your customizations. To do this: 1. Create an ns.package.json file for each new module in your extensions subdirectory. 2. Edit the distro.json file. To create an ns.package.json file for each new module: Note: Perform this procedure for each custom module in your extensions directory. 1. Create a new file for each custom module and title it: ns.package.json. You should end up with one unique ns.package.json file for each custom module. 2. Open each ns.package.json file and paste the following code: SuiteCommerce Site Development Patch Instructions 470 The following example includes <placeholders> that you must change within each ns.package.json file. { } "gulp": { "javascript": [ "JavaScript/*.js" ] }, "overrides": { "suitecommerce/<MODULE>@<X.Y.Z>/<SUBDIRECTORY>/<EXISTING_FILE>" : "<NEW_SUBDIRECTORY>/<NEW_FILE>.js" } 3. Edit the placeholders in the overrides object as described below: ■ <MODULE> represents the name of each module being changed. ■ <X.Y.Z> represents the module version in your implementation. ■ <SUBDIRECTORY> represents the subdirectory containing the original file you are overriding. ■ <EXISTING_FILE> represents the original file you are overriding. ■ <NEW_SUBDIRECTORY> represents the subdirectory according to the table in Apply Patch to Source Files. ■ <NEW_FILE> represents the new file according to the table in Apply Patch to Source Files. 4. Add the following as applicable: ■ Add an Internal, JavaScript, or SuiteScript array (as applicable) to the gulp object for each file type in the module. The table ■ Add a path to the overrides object for each file in the module. For example, the ns.package.json file for your custom CheckoutApplication@1.0.0 module should look similar to the following: { "gulp": { "internal": [ "Internal/*.ssp" ] , "javascript": [ "JavaScript/*.js" ] , "ssp-libraries": [ "SuiteScript/*.ssp" "SuiteScript/*.js" ] } , "overrides": { "suitecommerce/CheckoutApplication@2.2.0>/Internal/index-local.ssp" : "Internal/index-local.ssp" , "suitecommerce/CheckoutApplication@2.2.0>/JavaScript/SC.Checkout.Configuration.js" : "JavaScript/SC.Checkout.Con figuration.js" , "suitecommerce/CheckoutApplication@2.2.0>/SuiteScript/checkout.environment.ssp" : "SuiteScript/checkout.environmen t.ssp" } } 5. Repeat this procedure for each module, following the same basic structure. To edit the distro.json file: 1. Open the distro.json file. This is located in your root directory. SuiteCommerce Site Development Patch Instructions 471 2. Add each custom module to the modules object. Your code should look similar to the following example: { "name": "SuiteCommerce Site Builder 2.0", "version": "2.0", "buildToolsVersion": "1.2.1", "folders": { "modules": "Modules", "suitecommerceModules": "Modules/suitecommerce", "thirdPartyModules": "Modules/third_parties", "distribution": "LocalDistribution", "deploy": "DeployDistribution" }, "modules": { "suitecommerce/CheckoutApplication": "1.0.0", "suitecommerce/CheckoutSkipLogin": "1.0.0", "suitecommerce/GoogleUniversalAnalytics": "1.0.0", "suitecommerce/LiveOrder": "1.0.0", "suitecommerce/MyAccountApplication": "1.0.0", "suitecommerce/NavigationHelper": "1.0.0", "suitecommerce/ProductList": "1.0.0", "suitecommerce/Profile": "1.0.0", "suitecommerce/SiteSettings": "1.0.0", "suitecommerce/SspLibraries": "1.0.0", "suitecommerce/Utilities": "1.0.0", "suitecommerce/jQueryExtras": "1.0.0", "suitecommerce/Account": "2.2.0", //... This ensures that the Gulp tasks include your modules when you deploy. In this example, the custom modules are added at the beginning of the list of modules. However, you can add the modules anywhere in the modules object. The order of precedence in this list does not matter. 3. Save the distro.json file. Deploy Your Customizations to NetSuite The last step is to deploy your customizations. To deploy your customizations: 1. Deploy your source code customizations to your NetSuite account (see Deploy to NetSuite). 2. Confirm your results. Upon successful deployment, you should be able to take advantage of secure shopping domains on your Site Builder site. Secure Shopping for Site Builder (Pre-Denali) Applies to: Site Builder This topic explains how to patch the following implementations of Site Builder to take advantage of Secure Shopping domains: ■ Site Builder Reference Checkout 2.05 ■ Site Builder Reference Checkout 2.04 ■ Site Builder Reference My Account 1.06 ■ Site Builder Reference My Account Premium 1.06 SuiteCommerce Site Development Patch Instructions 472 ■ Site Builder Reference My Account 1.05 ■ Site Builder Reference My Account Premium 1.05 Follow these steps to allow for secure Shopping domains on your Site Builder site: 1. Configure a Secure Shopping Domain 2. Apply the Patch to Source Files 3. Deploy Files and Configure the Implementation Configure a Secure Shopping Domain Applies to: Site Builder Before you can use an SSL certificate to secure the shopping portion of your web store under an HTTPS domain, you must set up a secure shopping domain in NetSuite. See the help topic Set Up a Domain for more information. When setting up a secure domain for a site implementing Site Builder, be aware that sites implementing Site Builder can only implement SSL for the Shopping area of their site using a separate, secure shopping domain. Site Builder sites cannot implement a single secure domain for both Shopping and Checkout applications. When you have configured your domain, continue with the next step: Apply the Patch to Source Files. Apply the Patch to Source Files Applies to: Site Builder To leverage a secure shopping domain in your pre-Denali implementation of Site Builder, you need to introduce these changes as custom files and deploy to your Custom implementation. This patch is highly technical and involves customizing multiple files. Before you begin making changes, back up any custom files that already exist. Each .zip file listed in the procedure below includes a .patch file for a specific implementation. Launch the .patch file and introduce changes manually. For each file that needs updating, go to the SSP Application in NetSuite and copy the Reference files to the same location in the Custom folder: Documents > Files > File Cabinet > Web Site Hosting Files > Live Hosting Files > SSP Applications To implement the patch: 1. Download the correct patch .zip file, depending on you implementation. These files include all changes described in this procedure: Implementation Download Site Builder Reference Checkout 2.0.4 and 2.0.5 HTTPS_SiteBuilder-Reference-Checkout-2-0-4_and_2-0-5.zip Site Builder Reference My Account and My Account Premium 1.0.5 HTTPS_SiteBuilder-Reference-My-Account.1-0-5.zip SuiteCommerce Site Development Patch Instructions Implementation Download Site Builder Reference My Account and My Account Premium 1.0.6 HTTPS_SiteBuilder-Reference-My-Account-1-0-6.zip 473 2. Extract the .zip file and open the .patch file you find there. The .patch file describes each file and subsequent code to be customized. 3. If your implementation includes previous customizations, ensure that each file being patched is located in the custom folder and downloaded to your local environment. 4. If your implementation does not include any previous customizations, perform the following steps: a. Copy the corresponding source file located in the Reference implementation in NetSuite. If a preexisting file exists in the Custom implementation, then a customization has already been implemented on that file in the past. Back up this file and customize it instead. b. Create a local copy for development. 5. Access the root of your local development environment for this implementation. 6. Manually modify your files as instructed in the patch files to add or remove lines, as required. See How to Apply .patch Files for instructions on how to understand .patch files and apply changes. The following example describes one scenario. When you have successfully uploaded your customizations, continue with the next step: Deploy Files and Configure the Implementation. Patch Update Example The following code snippet comes from the Site Builder Reference Checkout 2.0.4 .patch file: diff --git a/index-local.ssp b/index-local.ssp index 3f974de..ac20076 100644 --- a/index-local.ssp +++ b/index-local.ssp @@ -30,11 +30,11 @@ login = true; } else if ( (SiteSettings.registration.registrationoptional !== 'T' && !session.isLoggedIn()) || (!SC.Configuration.checkout_skip_login && !session.isLoggedIn()) || (parameters.is && (parameters.is === 'login' || parameters.is === 'register') && !session.isLoggedIn()) + (SiteSettings.registration.registrationoptional !== 'T' && !session.isLoggedIn2()) + || (!SC.Configuration.checkout_skip_login && !session.isLoggedIn2()) + || (parameters.is && (parameters.is === 'login' || parameters.is === 'register') && !session.isLoggedIn2()) || (parameters.is && (parameters.is === 'login' || parameters.is === 'register') && session.getCustomer().isGuest()) || (SC.Configuration.checkout_skip_login && !session.isLoggedIn() && session.isRecognized()) + || (SC.Configuration.checkout_skip_login && !session.isLoggedIn2() && session.isRecognized()) ) { delete parameters.sitepath; In this example, these lines specify that the file you need to customize is index-local.ssp: diff --git a/index-local.ssp b/index-local.ssp The next lines in the example provide a reference point to locate the code in the file that needs updated. Two sets of @@ symbols specify that the code to be customized is located on line 30 of the file and that 11 lines of code are displayed. The code after this line reference provides a reference to help locate the area in the file affected by this change: @@ -30,11 +30,11 @@ login = true; SuiteCommerce Site Development Patch Instructions 474 } else if ( Important: The line reference (@@) specifies the line in the original source code. If you have made any preexisting modifications to the file prior to this patch, the code needing customized code may be located on a different line. Any lines prepended with a – symbol indicate code to delete/remove as part of this patch. In this example, you remove the following lines from index-local.ssp: - || || (SiteSettings.registration.registrationoptional !== 'T' && !session.isLoggedIn()) (!SC.Configuration.checkout_skip_login && !session.isLoggedIn()) (parameters.is && (parameters.is === 'login' || parameters.is === 'register') && !session.isLoggedIn()) Lines prepended with a + symbol indicate code to add: + + + || || (SiteSettings.registration.registrationoptional !== 'T' && !session.isLoggedIn2()) (!SC.Configuration.checkout_skip_login && !session.isLoggedIn2()) (parameters.is && (parameters.is === 'login' || parameters.is === 'register') && !session.isLoggedIn2()) Lines not prepended with a – or + symbol do not require change. See How to Apply .patch Files for more information on how to apply these changes manually. Deploy Files and Configure the Implementation Applies to: Site Builder When all customizations are complete, you are ready to deploy your custom files to your Site Builder SSP Application in NetSuite. The following topics explain how to deploy custom files to the Custom implementation: 1. Deploy Your Custom Files 2. Refresh Your Backend Environment 3. Configure the Models.js Script Path Important: The customizations introduced by this patch are extensive. Always test changes in a sandbox account or other test site before deploying to a production account. Deploy Your Custom Files The first task is to upload your changes to the correct location in the Custom implementation of your Site Builder SSP Application. Site Builder SSP Applications each have a locked Reference implementation that contains all source files and an unlocked Custom implementation, where you place your customizations. The Custom implementation directory (in the File Cabinet) is organized to match the structure of the Reference implementation. Upload your customized files to the Custom implementation in the location mirroring the original source location. Upload your customizations as a .zip file using the Advanced Add feature of the File Cabinet. Assuming that the location of each customized file in the Custom implementation mirrors the location in Reference, your customizations overwrite the source when your site compiles for runtime. SuiteCommerce Site Development Patch Instructions 475 For example, if you upload a custom version of index-local.ssp to a My Account Premium 1.05.0 implementation, the correct location for deployment is the root: Web Site Hosting Files > Live Hosting Files > SSP Applications > NetSuite Inc. - My Account Premium 1.05 > Custom My Account Premium To deploy customized files: 1. In your local developer environment, open your root implementation folder. 2. Select the entire contents of the folder and include all files within a local .zip file. Important: Include the root folder contents only. Do not include the root folder itself. 3. In NetSuite, navigate to the SSP Application folder for your implementation. For example: Web Site Hosting Files > Live Hosting Files > SSP Applications > NetSuite Inc. - My Account Premium 1.05 > Custom My Account Premium 4. Add your zip file to the File Cabinet using the Advanced Add feature. See the help topic Uploading Files to the File Cabinet for details. Refresh Your Backend Environment The next task is to update two configuration files in the NetSuite backend. These two files are: ■ Application.js ■ Templates.js These files must be automatically regenerated. You can force this action by editing two configuration files in your File Cabinet. To reset your environment: Note: Perform the following procedure for both combiner.config and templates.config. 1. In your NetSuite File Cabinet, navigate to Web Site Hosting Files > Live Hosting Files > SSP Applications > [APPLICATION] > [CUSTOM IMPLEMENTATION FOLDER] > js. 2. Click Edit next to combiner.config. 3. Locate the Media Item section and click Edit to preview the file. 4. Place your cursor at the very end of the code in this file. 5. Add a single space to the end of the code and click Save. This change forces a background process to generate a new, concatenated Application.js file. 6. Confirm that a new Application.js file is generated. The date in the Last Modified column should reflect an updated date and time when the process is complete. 7. Repeat this procedure for the templates.config file, located here: Web Site Hosting Files > Live Hosting Files > SSP Applications > NetSuite Inc. - My Account Premium 1.05 > Custom My Account Premium > templates. This action updates the Templates.js file. SuiteCommerce Site Development Patch Instructions 476 Configure the Models.js Script Path The last task to complete is updating the Models.js library script path and touch points. This file is generated when the Models.js script runs. Before this happens, you must update the script path manually to point to the Custom folder. To configure the Models.js script path: 1. In NetSuite, go to Setup > SuiteCommerce Advanced > SSP Applications. 2. Click Edit to modify the SSP Application associated with your implementation. 3. On the Library subtab under Scripts, locate the following library script: Web Site Hosting Files/Live Hosting Files/SSP Applications/[APPLICATION]/ssp_libraries/Models.js 4. Manually change this path to point to the Custom Files location: Web Site Hosting Files/Custom Files/SSP Applications/[APPLICATION]/ssp_libraries/Models.js In the above examples, [APPLICATION] equals the SSP Application of your current implementation. 5. Click Save. 6. Update touch points. See the help topic Select Supported Touch Points Upon successful deployment, you should be able to take advantage of secure shopping domains on your Site Builder site. Cannot Scroll Through Long Menu Lists Using iOS Applies to: SuiteCommerce Advanced | Denali | Mont Blanc | Vinson | Elbrus | Kilimanjaro In some cases, iOS users might encounter an issue where they cannot scroll through a long list of menu items if the list reaches beyond the device screen. If you experience this issue on your SuiteCommerce Advanced site, perform the updates described in the section corresponding to your implementation: ■ Elbrus Release and Earlier – Menu List Scrolling Patch (iOS) ■ Kilimanjaro – Menu List Scrolling Patch (iOS) In addition to making these changes, you must create an ns.package.json file and update your distro.json file for any custom modules you include. Elbrus Release and Earlier – Menu List Scrolling Patch (iOS) Applies to: SuiteCommerce Advanced | Denali | Mont Blanc | Vinson | Elbrus This section explains how to override the _mixins.scss to correct the iOS menu item scrolling issue for any Elbrus implementations of SuiteCommerce Advanced and earlier. Due to the structure of dependencies within these implementations, you cannot divide the entry point within the distro.json file. Therefore, you must override this file. You can download the code samples described in this procedure here: MixinsSassOverride-ElbrusAndEarlierSample.zip. Important: Be aware of any existing extensions or customizations to the existing file and familiarize yourself with the Best Practices for Customizing SuiteCommerce Advanced before proceeding with any customizations. Step 1: Override the _mixins.scss File 1. Create a directory to store your custom module. SuiteCommerce Site Development Patch Instructions 477 Following best practices, name this directory extensions and place it in your Modules directory. Depending on your implementation and customizations, this directory might already exist. 2. Open your extensions directory and create a custom module to maintain your customizations. Give this directory a unique name that is similar to the module being customized. For example: Modules/extensions/MixinsSassOverride@1.0.0/ 3. In your new module, create a subdirectory named Sass. 4. Copy the _mixins.scss file located in Modules > suitecommerce > BaseSassStyles@x.y.z and paste into your new Sass directory (where x.y.z represents the version of the module in your implementation of SuiteCommerce Advanced). For example, paste your copy of this into the following location: Modules/extensions/MixinsSassOverride@1.0.0/Sass/_mixins.scss 5. Open this file and remove the following line: -webkit-overflow-scrolling: touch; When you are finished, your file should match the following code snippet: /* © 2017 NetSuite Inc. User may not copy, modify, distribute, or re-bundle or otherwise make available this code; provided, however, if you are an authorized user with a NetSuite account or log-in, you may use this code subject to the terms that govern your access and use. */ @mixin border-radius($radius) { -webkit-border-radius: $radius; -moz-border-radius: $radius; -ms-border-radius: $radius; border-radius: $radius; } %scroll-y{ overflow-y: auto; } // avoid using BS mixin cause wont generate "-webkit-transform" @mixin transition-transform($duration...) { } -webkit-transition: -webkit-transform $duration; -moz-transition: -moz-transform $duration; -o-transition: -o-transform $duration; transition: transform $duration; @mixin appearance($appearance) { -webkit-appearance: $appearance; -moz-appearance: $appearance; appearance: $appearance; } //used for select arrow down @mixin angle-down-background($color){ $color-local: remove-hash-from-color($color); background-image:url("data:image/svg+xml;utf8,<svg width='2000px' height='2000px' fill='%23#{$color-local}' xmlns='http://www.w3.org/2000/svg'><path d='M1075 352q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-393 393l-393 -393q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l466 -466q10 -10 10 -23z'/></svg>"); } @function remove-hash-from-color($color) { @return str-slice(ie-hex-str($color), 4); } SuiteCommerce Site Development Patch Instructions //All placeholders equal @mixin placeholder { ::-webkit-input-placeholder :-moz-placeholder ::-moz-placeholder :-ms-input-placeholder } 478 {@content} {@content} {@content} {@content} 6. Save the file. Step 2: Prepare the Developer Tools for Your Override 1. Open the MixinsSassOverride@1.0.0 module. 2. Create a file in this module and name it ns.package.json. Modules/extensions/MixinsSassOverride@1.0.0/ns.package.json 3. Build the ns.package.json file using the following code { } "gulp": { "sass": [ "Sass/**/*.scss" ] }, "overrides": { "suitecommerce/BaseSassStyles@2.0.0/Sass/_mixins.scss" : "Sass/_mixins.scss" } Note: Replace the string x.y.z in the above example with the version of the module in your version of SuiteCommerce Advanced. 4. Save the ns.package.json file. 5. Open the distro.json file. This file is located in the top-level directory of your SuiteCommerce Advanced source code. 6. Add your module to the modules object to ensure that the Gulp tasks include it when you deploy. Your code should look similar to the following example: { "name": "SuiteCommerce Advanced Elbrus", "version": "2.0", "buildToolsVersion": "1.3.0", "folders": { "modules": "Modules", "suitecommerceModules": "Modules/suitecommerce", "extensionsModules": "Modules/extensions", "thirdPartyModules": "Modules/third_parties", "distribution": "LocalDistribution", "deploy": "DeployDistribution" }, "modules": { "extensions/MixinsSassOverride": "1.0.0", "extensions/MyExampleCartExtension1": "1.0.0", //... 7. Save the file. Step 3: Deploy Your Override 1. Deploy your source code customizations to your NetSuite account and test the functionality using a phone running iOS. See Deploy to NetSuite for details. SuiteCommerce Site Development Patch Instructions 2. Confirm your results. Upon successful deployment, iOS mobile users should be able to scroll through long menu lists. Kilimanjaro – Menu List Scrolling Patch (iOS) Applies to: SuiteCommerce Advanced | Kilimanjaro In your Kilimanjaro implementation of SuiteCommerce Advanced, you can extend the _mixins.scss file to overwrite the %scroll-y selector as described in this section. You can download the code samples described in this procedure here: MixinsSassExtension-KilimanjaroSample.zip Step 1: Extend the _mixins.scss File 1. If you have not done so already, create a directory to store your custom module. Following best practices, name this directory extensions and place it in your Modules directory. Depending on your implementation and customizations, this directory might already exist. 2. Open your extensions directory and create a custom module to maintain your customizations. Give this directory a unique name that is similar to the module being customized. For example: Modules/extensions/MixinsSassExtension@1.0.0/ 3. In your new module, create a subdirectory named Sass. 4. In your Sass subdirectory, create a new .scss file. Give this file a unique name that is similar to the file being modified. For example: Modules/extensions/mixinsSassExtension@1.0.0/Sass/_mixinsExtension.scss 5. Open this file and overwrite the %scroll-y selector. Your file should match the following code snippet: %scroll-y{ overflow-y: auto; } 6. Save the file. Step 2: Prepare the Developer Tools for Your Customizations 1. Open the MixinsSassExtension@1.0.0 module. 2. Create a file in this module and name it ns.package.json. Modules/extensions/MixinSassExtension@1.0.0/ns.package.json 3. Build the ns.package.json file using the following code { } "gulp": { "sass": [ "Sass/**/*.scss" ] } 4. Save the ns.package.json file. SuiteCommerce Site Development 479 Patch Instructions 5. Open the distro.json file. This file is located in the top-level directory of your SuiteCommerce Advanced source code. 6. Add your custom module to the modules object to ensure that the Gulp tasks include it when you deploy. Your code should look similar to the following example: { "name": "SuiteCommerce Advanced Kilimanjaro", "version": "2.0", "isSCA": true, "buildToolsVersion": "1.3.1", "folders": { "modules": "Modules", "suitecommerceModules": "Modules/suitecommerce", "extensionsModules": "Modules/extensions", "thirdPartyModules": "Modules/third_parties", "distribution": "LocalDistribution", "deploy": "DeployDistribution" }, "modules": { "extensions/MixinsSassExtension": "1.0.0", "extensions/MyExampleCartExtension1": "1.0.0", //... 7. Split the BaseSassStyle entry in the sass object of each application (Shopping, MyAccount, and Checkout) and add your custom module (MixinsSassExtension) between them. This ensures that the Sass variables are loaded in the correct order. Note: You do not need to wrap your custom module in an include array. The compiler adds all files within your new module by default. //... "sass": { //... "applications": [ { "name": "Shopping", "exportFile": "shopping.css", "dependencies": [ //... { "module": "BaseSassStyles", "include": [ "main-variables", "main-base" ] }, "MixinsSassExtension", { "module": "BaseSassStyles", "include": [ "main-atoms", "main-molecules", "molecules/datepicker" ] }, ] //... }, { "name": "MyAccount", "exportFile": "myaccount.css", "dependencies": [ //... SuiteCommerce Site Development 480 Patch Instructions { 481 "module": "BaseSassStyles", "include": [ "main-variables", "main-base" ] }, "MixinsSassExtension", { "module": "BaseSassStyles", "include": [ "main-atoms", "main-molecules", "molecules/datepicker" ] }, ] //... }, { "name": "Checkout", "exportFile": "checkout.css", "dependencies": [ //... { "module": "BaseSassStyles", "include": [ "main-variables", "main-base" ] }, "MixinsSassExtension", { "module": "BaseSassStyles", "include": [ "main-atoms", "main-molecules", "molecules/datepicker" ] }, ] }, //... ] //... 8. Save the distro.json file. Step 3: Deploy Your Extension 1. Deploy your source code customizations to your NetSuite account and test the functionality using a phone running iOS. See Deploy to NetSuite for details. 2. Confirm your results. Upon successful deployment, iOS mobile users should be able to scroll through long menu lists. Pages Not Indexed Using Google’s Mobile-First Indexing Applies to: SuiteCommerce Advanced | 2018.2 | Aconcagua | Kilimanjaro | Elbrus | Vinson | Mont Blanc | Denali In some cases, search engine crawlers discard content from the page generator and do not load all the required resources to render pages correctly. This results in SuiteCommerce pages not rendering content. Applying this patch corrects this issue by maintaining the SEO pre-render result. SuiteCommerce Site Development Patch Instructions 482 This patch uses the override method to replace shopping.ssp, located in the ShoppingApplication module. You can download the code samples described in this procedure here: MobileFirstIndexingPatch.zip. Note: In general, NetSuite best practice is to extend JavaScript using the JavaScript prototype object. This improves the chances that your customizations continue to work when migrating to a newer version of SuiteCommerce Advanced. However, this patch requires you to modify an SSP file, which requires that you use a custom module to override the existing module file. For more information, see Customize and Extend Core SuiteCommerce Advanced Modules. Step 1: Create the shopping.ssp Override File 1. Open the Modules/extensions directory and create a subdirectory to maintain your customizations and store your custom module. Give this subdirectory a name similar to the module being customized. For example: Modules/ extensions/ShoppingApplication.Extension@1.0.0. Note: If you are implementing the Elbrus release of SCA or later, the extensions directory already exists in your source code. If implementing Vinson release or earlier, you must add it manually. 2. In your new ShoppingApplication.Extension@1.0.0 directory, create a subdirectory called SuiteScript. For example: Modules/extensions/ShoppingApplication.Extension@1.0.0/SuiteScript 3. Find the following file in your existing source: Modules/suitecommerce/ShoppingApplication@X.Y.Z/shopping.ssp In this example, X.Y.Z represents the version of the module in your implementation of SuiteCommerce Advanced. 4. Copy this entire file and paste a copy in your new module’s SuiteScript directory. For example: Modules/extensions/ShoppingApplication.Extension@1.0.0/SuiteScript/ shopping.ssp 5. Open your new copy of shopping.ssp and locate the following line: document.getElementById("main").innerHTML = ''; 6. Replace this line with the following code: if (!navigator.userAgent.match(/googlebot/i)) { document.getElementById('main').innerHTML=''; } 7. Save the file. Step 2: Prepare the Developer Tools For Your Customization 1. Open your ShoppingApplication.Extension@1.0.0 module directory. 2. Create a file in this directory and name it ns.package.json. For example: Modules/extensions/ShoppingApplication.Extension@1.0.0/ns.package.json 3. Build the ns.package.json file using the following code: { "gulp": { "ssp-files": { SuiteCommerce Site Development Patch Instructions } } 483 "SuiteScript/shopping.ssp": "shopping.ssp" }, "overrides": { "suitecommerce/ShoppingApplication@X.Y.Z/SuiteScript/shopping.ssp" : "SuiteScript/shopping.ssp" } In your code, replace X.Y.Z with the version of the module in your implementation of SuiteCommerce Advanced. 4. Open the distro.json file. This is located in your root directory. 5. Add your custom module to the modules object. Your code should look similar to the following example: { "name": "SuiteCommerce Advanced 2018.2.0 (sc-2018.2.0)", "version": "2.0", "isSCA": true, "buildToolsVersion": "sc-2018.2.0", "folders": { "modules": "Modules", "suitecommerceModules": "Modules/suitecommerce", "extensionsModules": "Modules/extensions", "thirdPartyModules": "Modules/third_parties", "distribution": "LocalDistribution", "deploy": "DeployDistribution" }, "modules": { "extensions/ShoppingApplication.Extension": "1.0.0", "suitecommerce/Account": "sc-2018.2.0", ... This ensures that the Gulp tasks include your module when you deploy. In this example, the custom modules are added at the beginning of the list of modules. However, you can add the modules anywhere in the modules object. The order of precedence in this list does not matter. 6. Save the distro.json file. Step 3: Test and Deploy Your Customization 1. Test your source code customizations by deploying them to your NetSuite account (see Deploy to NetSuite). Note: Since this patch modifies a SuiteScript file, changes are not visible in your local environment. SuiteScript files run on the server and must be deployed to NetSuite to take effect. 2. Confirm your results. Disabling Display of SuiteCommerce Gift Wrap & Message Extension Transaction Line Fields Applies to: SuiteCommerce Advanced After installing the SuiteCommerce Gift Wrap & Message extension, the application adds the following transaction line item fields to all items in your account: ■ Gift Wrap Item ■ Gift Wrap Item ID ■ Gift Wrap Message From SuiteCommerce Site Development Patch Instructions 484 ■ Gift Wrap Message To ■ Gift Wrap Message Text After installing the extension, these added fields may display on your site, even if you do not activate the extension. Follow these instructions, depending on your implementation, to prevent these fields from displaying on your site: ■ SuiteCommerce and SuiteCommerce Advanced Aconcagua and Later ■ SuiteCommerce Advanced Denali through Kilimanjaro ■ SuiteCommerce Advanced Pre-Denali ■ Site Builder Websites SuiteCommerce and SuiteCommerce Advanced Aconcagua and Later Follow the steps below to disable the display of SuiteCommerce Gift Wrap & Message extension transaction line item fields on product display pages. Step 1: Activate the SuiteCommerce Gift Wrap & Message Extension. 1. If you have not done so already, install the SuiteCommerce Gift Wrap & Message extension into your NetSuite account. See the help topic Install Theme and Extension SuiteApps. 2. Activate the SuiteCommerce Gift Wrap & Message extension. See see the help topic Manage Themes and Extensions. Step 2: Update the Configuration Record for the Web Site and Domain 1. Go to Setup > SuiteCommerce Advanced > Configuration. 2. Select the web site and domain. 3. Click Configure. 4. Navigate to the My Extensions tab. 5. On the Gift Wrap & Message subtab, clear the Enable Gift Wrap box. 6. Click Save. Step 3: Clear the Domain Cache and Confirm Results 1. Go to Setup > SuiteCommerce Advanced > Cache Invalidation Requests. 2. Click New Invalidation Request. 3. Double-click on the domain for which you want to clear the cache. 4. Enable the Clear cache for the whole domain(s) option. 5. Click Submit. 6. Click OK. 7. Confirm your results. After a successful configuration, your site will not display the gift wrap transaction line item fields. SuiteCommerce Advanced Denali through Kilimanjaro This patch disables the display of the SuiteCommerce Gift Wrap & Message extension transaction line item fields on product display pages. You can download the code samples described in this procedure here: GiftWrap.itemOptionsExtension@1.0.0—KilimanjaroSample.zip SuiteCommerce Site Development Patch Instructions 485 Step 1: Create the Directory Structure to Store Your Custom Module 1. Open the Modules/extensions directory and create a subdirectory to maintain your customizations. Note: If you are implementing the Vinson release of SuiteCommerce Advanced or earlier, you might need to create the extensions directory manually. 2. In the extensions directory, create a subdirectory called GiftWrap.ItemOptionsExtension@1.0.0. When creating a new custom module, the module name must be unique. You must not have duplicate module names, even if those modules reside in different folders. 3. In your new module, create a subdirectory called Sass. 4. In your new Sass subdirectory, create a text file. Give this file a unique name that is similar to the module directory. For example: _giftWrap-item-options-extension.scss Step 2: Create a Sass File 1. In the Sass directory, create a new file called _giftWrap-item-options-extension.scss. 2. Add the following text to the _giftWrap-item-options-extension.scss file: [id*='custcol_ns_sc_ext_gw_item'], [name*='custcol_ns_sc_ext_gw_item'], [id*='custcol_ns_sc_ext_gw_id'], [name*='custcol_ns_sc_ext_gw_id'], [id*='custcol_ns_sc_ext_gw_message_from'], [name*='custcol_ns_sc_ext_gw_message_from'], [id*='custcol_ns_sc_ext_gw_message_to'], [name*='custcol_ns_sc_ext_gw_message_to'], [id*='custcol_ns_sc_ext_gw_message_text'], [name*='custcol_ns_sc_ext_gw_message_text'] { display: none; } Step 3: Create the ns.package.json File 1. Open the GiftWrap.ItemOptionsExtension@1.0.0 module. 2. Create a file in this module and name it ns.package.json. Modules/extensions/GiftWrap.ItemOptionsExtension@1.0.0/ns.package.json 3. Build the ns.package.json file using the following code: { } "gulp": { "sass": [ "Sass/**/*.scss" ] } 4. Save the ns.package.json file. Step 4: Update the distro.json File and Deploy Your Customizations to Your NetSuite Account 1. Open the distro.json file. This file is located in the top-level directory of your SuiteCommerce source code. 2. Add your custom module to the modules object to ensure that the Gulp tasks include it when you deploy. SuiteCommerce Site Development Patch Instructions 486 In this example, the extensions/GiftWrap.ItemOptionsExtension@1.0.0 , module is added at the beginning of the list of the other extensions modules. However, you can add the module anywhere in the modules object. The order of precedence in this list does not matter. { "name": "SuiteCommerce Advanced Kilimanjaro", "version": "2.0", "isSCA": true, "buildToolsVersion": "1.3.1", "folders": { "modules": "Modules", "suitecommerceModules": "Modules/suitecommerce", "extensionsModules": "Modules/extensions", "thirdPartyModules": "Modules/third_parties", "distribution": "LocalDistribution", "deploy": "DeployDistribution" }, "modules": { "extensions/GiftWrap.ItemOptionsExtension": "1.0.0", "extensions/QuoteToSalesOrderExtension": "1.0.0", "extensions/TransactionExtention": "1.0.0", "extensions/OrderWizardPaymentMethodExtension": "1.0.0", ... 3. Include the module definition (GiftWrap.ItemOptionsExtension) in the dependencies/applications array of the sass object within applications/dependencies/ for each application (Shopping, MyAccount, and Checkout). You must include this file after the module you are overriding. Your distro.json file should look similar to the following: //... "tasksConfig": { //... "sass": { //... "applications": [ { "name" "Shopping", "exportFile": "shopping.css", "dependencies": [ //... "Location.SCA", "GiftWrap.ItemOptionsExtension" ] } //... { "name" "MyAccount", "exportFile": "myaccount.css", "dependencies": [ //... "Location.SCA", "GiftWrap.ItemOptionsExtension" ] } //... { "name" "Checkout", "exportFile": "checkout.css", "dependencies": [ //... "Location.SCA", "GiftWrap.ItemOptionsExtension" ] } ] } //... 4. Save the distro.json file. SuiteCommerce Site Development Patch Instructions 487 5. Deploy your source code customizations to your NetSuite account. See Deploy to NetSuite for details. Step 5: Clear Your Domain Cache and Confirm Results 1. Go to Setup > SuiteCommerce Advanced > Cache Invalidation Requests. 2. Click New Invalidation Request. 3. Double-click on the domain for which you want to clear the cache. 4. Enable the Clear cache for the whole domain(s) option. 5. Click Submit. 6. Click OK. 7. Confirm your results. After a successful deployment, your site will not display the gift wrap transaction line item fields. SuiteCommerce Advanced Pre-Denali Follow the steps below to disable the display of SuiteCommerce Gift Wrap & Message extension transaction line item fields on product display pages. Step 1: Add code to your application stylesheet 1. Open any of the SuiteCommerce Advanced instance stylesheets located in your local development files. For example: Custom ShopFlow 1.07.0/skins/standard/styles.css 2. Paste the following code at the bottom of the file: [id*='custcol_ns_sc_ext_gw_item'], [name*='custcol_ns_sc_ext_gw_item'], [id*='custcol_ns_sc_ext_gw_id'], [name*='custcol_ns_sc_ext_gw_id'], [id*='custcol_ns_sc_ext_gw_message_from'], [name*='custcol_ns_sc_ext_gw_message_from'], [id*='custcol_ns_sc_ext_gw_message_to'], [name*='custcol_ns_sc_ext_gw_message_to'], [id*='custcol_ns_sc_ext_gw_message_text'], [name*='custcol_ns_sc_ext_gw_message_text'] { display: none; } Step 2: Upload the stylesheet to the File Cabinet and Compile the Change 1. Upload the file to the File Cabinet in the appropriate location. Example: CustomShopFlow 1.07.0/skins/standard/styles.css 2. Trigger the style’s combiner.config file to compile the change by editing and saving the styles.css file without making any changes. Step 3: Clear Your Domain Cache and Confirm Results 1. Go to Setup > SuiteCommerce Advanced > Cache Invalidation Requests. 2. Click New Invalidation Request. 3. Double-click on the domain for which you want to clear the cache. 4. Enable the Clear cache for the whole domain(s) option. 5. Click Submit. 6. Click OK. SuiteCommerce Site Development Patch Instructions 488 7. Confirm your results. After a successful deployment, your site will not display the gift wrap transaction line item fields. Site Builder Websites For Site Builder web sites, you only need to add some code to your Web Site Setup record and save the changes. After a successful configuration, your site no longer displays the gift wrap transaction line item fields. Adding Code to Your Web Site Setup Record 1. In NetSuite, go to Setup > SiteBuilder > Web Site Set Up. 2. Click Edit for the website you want to patch. 3. Go to the Analytics subtab and paste the following code into the Additional to <head> field: <style type="text/css"> [id*='custcol_ns_sc_ext_gw_item'], [name*='custcol_ns_sc_ext_gw_item'], [id*='custcol_ns_sc_ext_gw_id'], [name*='custcol_ns_sc_ext_gw_id'], [id*='custcol_ns_sc_ext_gw_message_from'], [name*='custcol_ns_sc_ext_gw_message_from'], [id*='custcol_ns_sc_ext_gw_message_to'], [name*='custcol_ns_sc_ext_gw_message_to'], [id*='custcol_ns_sc_ext_gw_message_text'], [name*='custcol_ns_sc_ext_gw_message_text'] { display: none; } </style> 4. Click Save. Users Not Redirected to External Payment System Applies to: SuiteCommerce Advanced | Vinson In Vinson releases of SCA, if a user chooses an external payment method during checkout, SuiteCommerce Advanced does not correctly open the third-party payment system. When a user clicks the Continue to External Payment button during checkout, instead of sending the user to the external payment system, SCA redirects the user to the beginning of the checkout process. This error occurs because SuiteCommerce Advanced deprecated the existing payment processing status result, HOLD, in 17.1. Instead, SCA uses a new status result, PENDING. As a result, any SCA sites implementing the Vinson release requires this patch to use third-party payment systems. To implement this patch, you must extend the prototype object for the ExternalPaymentModel function that includes the _isDone(), _validateRecordStatus(), and _validateStatusFromRequest() methods. This function is located in ExternalPayment.Model.js for the ExternalPayment module. You can download the code samples described in this procedure here: UsersNotRedirectedExternalPaymentSystem.zip. Step 1: Extend the ExternalPayment.Model.js File 1. If you have not done so already, create a directory to store your custom module. Give this directory a name similar to the module being customized. For example, create Modules/ extensions/ExternalPaymentExtension@1.0.0 2. In your new ExternalPaymentExtension@1.0.0 directory, create a subdirectory called JavaScript. For example: Modules/extensions/ExternalPaymentExtension@1.0.0/SuiteScript SuiteCommerce Site Development Patch Instructions 489 3. In your new JavaScript subdirectory, create a JavaScript file to extend ExternalPayment.Model.js. Name this file according to best practices. For example: ExternalPayment.Model.Extension.js 4. Open this file and extend the ExternalPaymentModel() function as shown in the following code snippet. define('ExternalPayment.Model.Extension' , [ 'ExternalPayment.Model' , 'underscore' ] , function ( ExternalPaymentModel , _ ) { 'use strict'; _.extend(ExternalPaymentModel.prototype, { _isDone: function (request, record_type) { var status = this._getStatusFromRequest(request, record_type) , status_accept_value = this._getConfiguration(record_type, 'statusAcceptValue','ACCEPT') , status_hold_value = this._getConfiguration(record_type, 'statusHoldValue', 'HOLD') } //Added by payment , status_pending_value = this._getConfiguration(record_type, 'statusPendingValue', 'PENDING') return status === status_accept_value || status === status_hold_value || status === status_pending_value; , _validateRecordStatus: function (record) { //Modified by Payment return record.getFieldValue('paymenteventholdreason') === 'FORWARD_REQUESTED'; } , _validateStatusFromRequest: function (request, record_type) { var status = this._getStatusFromRequest(request, record_type) , status_accept_value = this._getConfiguration(record_type, 'statusAcceptValue' , 'ACCEPT') , status_hold_value = this._getConfiguration(record_type, 'statusHoldValue' , 'HOLD') //Added by Payment , status_pending_value = this._getConfiguration(record_type, 'statusPendingValue', 'PENDING') , status_reject_value = this._getConfiguration(record_type, 'statusRejectValue' , 'REJECT'); //Modified by Payment return status === status_accept_value || status === status_pending_value || status === status_hold_value || status === status_reject_value; } }); }); 5. Save the file. Step 2: Prepare the Developer Tools For Your Customization 1. Open your new ExternalPaymentExtension@1.0.0 module directory. 2. Create a file in this directory and name it ns.package.json. Modules/extensions/ExternalPaymentExtension@1.0.0/ns.package.json 3. Build the ns.package.json file using the following code: { "gulp": { SuiteCommerce Site Development Patch Instructions } } 490 "ssp-libraries": [ "SuiteScript/*.js" ] 4. Open the distro.json file. This is located in your root directory. 5. Add your custom modules to the modules object. Your code should look similar to the following example: { "name": "SuiteCommerce Advanced Vinson Release", "version": "2.0", "buildToolsVersion": "1.2.1", "folders": { "modules": "Modules", "suitecommerceModules": "Modules/suitecommerce", "thirdPartyModules": "Modules/third_parties", "distribution": "LocalDistribution", "deploy": "DeployDistribution" }, "modules": { "extensions/ExternalPaymentExtension": "1.0.0", "suitecommerce/Account": "2.2.0", ... This ensures that the Gulp tasks include your module when you deploy. In this example, the custom modules are added at the beginning of the list of modules. However, you can add the modules anywhere in the modules object. The order of precedence in this list does not matter. 6. Add ExternalPaymentExtension as a dependency to SCA entry point within the SC.Shopping.Starter entrypoint of the JavaScript array. Your distro.js file should look similar to the following: "tasksConfig": { // ... "javascript": [ // ... { "entryPoint": "SC.Checkout.Starter", "exportFile": "checkout.js", "dependencies": [ "ExternalPaymentExtension", "Backbone.View.Plugins", "jQuery.html", // ... ], // ... 7. Save the distro.json file. Step 3: Test and Deploy Your Customization 1. Deploy your source code customizations to your NetSuite account and test the functionality. See Deploy to NetSuite for details. Note: Since this patch modifies a SuiteScript file, changes are not visible in your local environment. SuiteScript files run on the server and must be deployed to NetSuite to take effect. 2. Confirm your results. Upon successful deployment, the checkout process redirects to an external payment system when you click Continue to External Payment. SuiteCommerce Site Development Patch Instructions 491 Invoices Do Not Include the Request for a Return Button Applies to: SuiteCommerce Advanced | Vinson In Reference My Account v1.06, invoices do not include the Request for a Return button. As a result, a customer cannot request to return items on an invoice in NetSuite. However, this button does appear on invoices for Reference My Account Premium v1.06. To add this button, this patch overrides invoice_details.tpl, Invoice.Router.js, and Invoice.Details.View.js in the Invoice module. You can download the code samples described in this procedure here: RequestForAReturnButtonOnInvoices.zip Note: In general, NetSuite best practice is to extend JavaScript using the JavaScript prototype object. This improves the chances that your customizations continue to work when migrating to a newer version of SuiteCommerce Advanced. However, this patch requires you to modify files that you cannot extend, and therefore requires you to use a custom module to override the existing module file. For more information, see Customize and Extend Core SuiteCommerce Advanced Modules. Step 1. Override the JavaScript and Template Files 1. If you have not done so already, create a directory to store your custom module. Give this directory a name similar to the module being customized. For example, create Modules/ extensions/Invoice.Extension@1.0.0 2. In your new Invoice.Extension@1.0.0 directory, create subdirectories called JavaScript and Templates. For example: Modules/extensions/Invoice.Extension@1.0.0/JavaScript and Modules/extensions/ Invoice.Extension@1.0.0/Templates. 3. Copy the following files: Modules/suitecommerce/Invoice@X.Y.Z/JavaScript/Invoice.Router.js Modules/suitecommerce/Invoice@X.Y.Z/JavaScript/Invoice.Details.View.js Modules/suitecommerce/Invoice@X.Y.Z/Templates/invoice_details.tpl In this example, X.Y.Z represents the version of the module in your implementation of SuiteCommerce Advanced. 4. Paste a copy in your new module’s JavaScript and Templates directories. For example: Modules/extensions/Invoice.Extension@1.0.0/JavaScript/Invoice.Router.js or Modules/extensions/Invoice.Extension@1.0.0/Templates/invoice_details.tpl 5. Open your new copy of Invoice.Router.js and locate the showInvoice() method. Replace the existing showInvoice() method with the following code: showInvoice: function (invoice_id, referer) { var invoice = new InvoiceModel({internalid: invoice_id}) , view = new DetailsView({ application: this.application , model: invoice , referer: referer }); invoice .fetch({ killerId: AjaxRequestsKiller.getKillerId() }) .done(function() { view.isReturnable() SuiteCommerce Site Development Patch Instructions } }); .done(function() { view.showContent(); }) 6. Save the file. 7. Open your new copy of Invoice.Details.View.js and make the following changes. a. Find the following line: , 'underscore' Replace this line with the following code: , , , , , b. 'underscore' 'ReturnAuthorization.GetReturnableLines' 'OrderHistory.Model' 'AjaxRequestsKiller' 'jQuery' Find the following line: , _ Replace this line with the following code: , , , , , c. _ ReturnLinesCalculator OrderHistoryModel AjaxRequestsKiller JQuery Find the following lines: , makeAPayment: function () { LivePaymentModel.getInstance().selectInvoice(this.model.id); } Replace these lines with the following code: , makeAPayment: function () { LivePaymentModel.getInstance().selectInvoice(this.model.id); } , makeAPayment: function () { LivePaymentModel.getInstance().selectInvoice(this.model.id); } //@method isReturnable calculates a value based on the fulfillments and returns made, // if the invoice accepts returns , isReturnable: function () { var deferred = JQuery.Deferred(); var self = this; var model = new OrderHistoryModel(); model .fetch({ data: { internalid: this.model.get('createdfrom').internalid , recordtype: this.model.get('createdfrom').recordtype } , killerId: AjaxRequestsKiller.getKillerId() SuiteCommerce Site Development 492 Patch Instructions 493 }) .done(function() { var ret_calculator = new ReturnLinesCalculator(model, {notConsiderFulfillments: true}); self.validLines = ret_calculator.calculateLines().validLines.length; deferred.resolve(); }); } d. return deferred.promise(); Find the following line: , showOpenedAccordion: _.isTabletDevice() || _.isDesktopDevice() Replace this line with the following code: , showOpenedAccordion: _.isTabletDevice() || _.isDesktopDevice() //@property {Boolean} showRequestReturnButton , showRequestReturnButton: !!this.validLines e. Find the following line inside the initialize() function: this.navSource = options.referer === 'paidinvoices' ? '/paid-invoices' : '/invoices'; Replace this line with the following code: this.navSource = options.referer === 'paidinvoices' ? '/paid-invoices' : '/invoices'; this.model = options.model; this.validLines = 0; 8. Save the file. 9. Open your new copy of invoice_details.tpl and make the following change. Find the following lines: <a target="_blank" class="invoice-details-button-download-as-pdf" href="{{donwloadPdfUrl}}"> {{translate 'Download as PDF'}} </a> Replace these lines with the following code: <a target="_blank" class="invoice-details-button-download-as-pdf" href="{{donwloadPdfUrl}}"> {{translate 'Download as PDF'}} </a> {{#if showRequestReturnButton}} <a href="/returns/new/invoice/{{model.internalid}}" class="invoice-details-button-request" data-permissions="transaction s.tranRtnAuth.2"> {{translate 'Request a Return'}} </a> {{/if}} 10. Save the file. Step 2: Prepare the Developer Tools For Your Customization 1. Open your Modules/extensions/ module directory. 2. Create a file in this directory and name it ns.package.json. Modules/extensions/Invoice.Extension@1.0.0/ns.package.json 3. Build the ns.package.json file using the following code: SuiteCommerce Site Development Patch Instructions { } 494 "gulp": { "javascript": [ "JavaScript/*.js" ] }, "overrides": { "suitecommerce/Invoice@X.Y.Z/Javascript/Invoice.Router.js" : "JavaScript/Invoice.Router.js", "suitecommerce/Invoice@X.Y.Z/Javascript/Invoice.Details.View.js" : "JavaScript/Invoice.Details.View.js", "suitecommerce/Invoice@X.Y.Z/Templates/invoice_details.tpl" : "Templates/invoice_details.tpl" } Important: You must replace the string X.Y.Z with the version of the module in your implementation of SuiteCommerce Advanced. 4. Open the distro.json file. This is located in your root directory. 5. Add your custom modules to the modules object. Your code should look similar to the following example: { "name": "SuiteCommerce Advanced Vinson Release", "version": "2.0", "buildToolsVersion": "1.2.1", "folders": { "modules": "Modules", "suitecommerceModules": "Modules/suitecommerce", "thirdPartyModules": "Modules/third_parties", "distribution": "LocalDistribution", "deploy": "DeployDistribution" }, "modules": { "extensions/Invoice.Extension": "1.0.0", "suitecommerce/Account": "2.2.0", ... This ensures that the Gulp tasks include your module when you deploy. In this example, the custom modules are added at the beginning of the list of modules. However, you can add the modules anywhere in the modules object. The order of precedence in this list does not matter. 6. Save the distro.json file. Step 3: Test and Deploy Your Customization 1. Test your source code customizations on a local server (see SCA on a Local Server) or deploy them to your NetSuite account (see Deploy to NetSuite). If you are currently running SCA on a local server, your changes should appear on your local site immediately. 2. Confirm your results. Upon successful deployment, Invoice records under My Account contain a Request a Return button . Unable to Select Item Options Within the SuiteCommerce Configuration Record in NetSuite Applies to: SuiteCommerce Advanced | Elbrus In some implementations of Elbrus, site administrators cannot choose item options when configuring a domain using the SuiteCommerce Configuration record in NetSuite (Shopping Catalog tab, Item Options subtab). This can occur using Goggle Chrome with Mac OS. SuiteCommerce Site Development Patch Instructions 495 This patch extends the ProductDetails.Base.View.js file in the ProductDetails module to overwrite the optionBindEventByType object. This code change ensures that site administrators can select item options in the SutieCommerce Configuration record without error and then specify a default template to render the selected item option. Step 1: Extend the ProductDetails.Base.View.js File 1. Open the Modules/extensions directory and create a subdirectory to maintain your customizations. Give this directory a name similar to the module being customized. For example: Modules/extensions/ProductDetails.Extension@1.0.0 2. In your new ProductDetails.Extension@1.0.0 module, create a subdirectory called JavaScript. 3. In your new JavaScript subdirectory, create a JavaScript file to extend the JavaScript in ProductDetails.Base.View.js. Name this file according to best practices. For example: Modules/extensions/ProductDetails.Extension@1.0.0/JavaScript/ ProductDetails.Base.View.Extension.js 4. Open this file and extend the prototype of ProductDetailsBaseView with the optionBindEventByType object as shown in the following code snippet. define( 'ProductDetails.Base.View.Extension' , ['ProductDetails.Base.View' , 'jQuery' , 'underscore' ] , function ( ProductDetailsBaseView , jQuery , _ ) { 'use strict'; _.extend(ProductDetailsBaseView.prototype, {optionBindEventByType: { 'select': 'change' , 'text': 'blur' , 'date': 'change' } }); 5. Save the file. Step 2: Prepare the Developer Tools for Your Customization 1. Open the ProductDetails.Extension@1.0.0 module. 2. Create a file in this module and name it ns.package.json. For example: Modules/extensions/ProductDetails.Extension@1.0.0/ns.package.json 3. Build the ns.package.json file using the following code { } "gulp": { "javascript": [ "JavaScript/*.js" ] } 4. Save the file. SuiteCommerce Site Development Patch Instructions 496 5. Open the distro.json file. This file is located in the top-level directory of your SuiteCommerce Advanced source code. 6. Add your custom module to the modules object to ensure that the Gulp tasks include it when you deploy. Your code should look similar to the following example: { "name": "SuiteCommerce Advanced Elbrus", "version": "2.0", "buildToolsVersion": "1.3.0", "folders": { "modules": "Modules", "suitecommerceModules": "Modules/suitecommerce", "extensionsModules": "Modules/extensions", "thirdPartyModules": "Modules/third_parties", "distribution": "LocalDistribution", "deploy": "DeployDistribution" }, "modules": { "extensions/ProductDetails.Extension": "1.0.0", "extensions/MyExampleCartExtension1": "1.0.0", //... 7. Include the module definition (ProductDetails.Base.View.Extension) as a dependency within the JavaScript SC.Shopping.Starter entry point. Your distro.json file should look similar to the following: "tasksConfig": { //... "javascript": [ { "entryPoint": "SC.Shopping.Starter", "exportFile": "shopping.js", "dependencies": [ //... "StoreLocator", "ProductDetails.Base.View.Extension" ] //... } //... 8. Save the distro.json file. Step 3: Test and Deploy Your Customization 1. Test your source code customization on a local server (see SCA on a Local Server) or deploy them to your NetSuite account (see Deploy to NetSuite). If you are currently running SCA on a local server, your changes should appear on your local site immediately. 2. Confirm your results. Upon successful deployment, you should be able to configure item options using the SuiteCommerce Configuration record (Shopping Catalog tab, Item Options subtab). Incorrect Redirect URL for External Payments Applies to: SuiteCommerce Advanced | Elbrus | Vinson On releases of Elbrus and Vinson, the checkout process that uses an external payment system does not correctly cancel the process and return to the SuiteCommerce site. Instead, when you click Cancel while SuiteCommerce Site Development Patch Instructions 497 using an external payment system, a 404 error occurs. This error occurs due to an incorrect URL variable value in the OrderWizard.Module.PaymentMethod module. To implement this patch, you must extend the prototype object for the render() method in OrderWizard.Module.PaymentMethod.External.js for the OrderWizard.Module.PaymentMethod module. You can download the code samples described in this procedure here: IncorrectRedirectURLforExternalPaymentsElbrus.zip or IncorrectRedirectURLforExternalPaymentsVinson.zip. Note: Before proceeding, familiarize yourself with Best Practices for Customizing