Skip to main content

NetSuite Portlets

Portlets are dashboard widgets that display customized content, reports, and interactive elements on the NetSuite home page.


Portlet Types​

TypeDescriptionUse Case
Form PortletDisplay a form for data entryQuick order entry, search forms
List PortletDisplay tabular dataPending approvals, recent records
HTML PortletCustom HTML contentCharts, embeds, formatted content
Links PortletGrouped navigation linksQuick links, shortcuts

Architecture​

PORTLET ARCHITECTURE
─────────────────────────────────────────────────────────

┌─────────────────────────────────────────────────────────┐
│ DASHBOARD │
├───────────────────┬─────────────────┬───────────────────┤
│ LEFT COLUMN │ CENTER COLUMN │ RIGHT COLUMN │
│ │ │ │
│ ┌─────────────┐ │ ┌───────────┐ │ ┌─────────────┐ │
│ │ List │ │ │ Form │ │ │ HTML │ │
│ │ Portlet │ │ │ Portlet │ │ │ Portlet │ │
│ │ │ │ │ │ │ │ │ │
│ │ Pending │ │ │ Quick │ │ │ KPI │ │
│ │ Approvals │ │ │ Order │ │ │ Dashboard │ │
│ └─────────────┘ │ └───────────┘ │ └─────────────┘ │
│ │ │ │
│ ┌─────────────┐ │ ┌───────────┐ │ ┌─────────────┐ │
│ │ Links │ │ │ List │ │ │ Form │ │
│ │ Portlet │ │ │ Portlet │ │ │ Portlet │ │
│ └─────────────┘ │ └───────────┘ │ └─────────────┘ │
└───────────────────┴─────────────────┴───────────────────┘

Script Structure​

Portlet Script Type​

/**
* @NApiVersion 2.1
* @NScriptType Portlet
*/
define(['N/search', 'N/ui/serverWidget'],
(search, serverWidget) => {

/**
* Render portlet content
* @param {Object} params
* @param {serverWidget.Portlet} params.portlet - Portlet object
* @param {number} params.column - Dashboard column (1, 2, or 3)
* @param {string} params.entityid - Entity context (if any)
*/
const render = (params) => {
const portlet = params.portlet;

portlet.title = 'My Custom Portlet';

// Add content based on portlet type
// ...
};

return { render };
});

Portlet Parameters​

ParameterTypeDescription
params.portletPortletThe portlet object to populate
params.columnnumberColumn position (1=left, 2=center, 3=right)
params.entityidstringEntity ID if on record dashboard

Deployment​

Script Record​

Customization → Scripting → Scripts → New

FieldValue
TypePortlet
Script FileSuiteScripts/portlet_script.js

Script Deployment​

Customization → Scripting → Script Deployments

FieldDescription
Applied ToEntity dashboard or general
StatusReleased
Role RestrictionsWho can see the portlet

Adding to Dashboard​

Home → Personalize Dashboard → Custom Portlets


Quick Examples​

List Portlet​

const render = (params) => {
params.portlet.title = 'Pending Approvals';

// Add columns
params.portlet.addColumn({ id: 'tranid', type: 'text', label: 'Transaction', align: 'LEFT' });
params.portlet.addColumn({ id: 'entity', type: 'text', label: 'Customer', align: 'LEFT' });
params.portlet.addColumn({ id: 'total', type: 'currency', label: 'Amount', align: 'RIGHT' });

// Add rows from search
search.create({
type: 'salesorder',
filters: [['status', 'is', 'pendingApproval']],
columns: ['tranid', 'entity', 'total']
}).run().each(result => {
params.portlet.addRow({
tranid: result.getValue('tranid'),
entity: result.getText('entity'),
total: result.getValue('total')
});
return true;
});
};

Form Portlet​

const render = (params) => {
params.portlet.title = 'Quick Search';

params.portlet.addField({
id: 'custpage_search',
type: 'text',
label: 'Search Term'
});

params.portlet.addField({
id: 'custpage_type',
type: 'select',
label: 'Record Type',
source: 'customlist_record_types'
});

params.portlet.setSubmitButton({ label: 'Search' });
};

HTML Portlet​

const render = (params) => {
params.portlet.title = 'KPI Summary';

params.portlet.html = `
<div style="display: flex; justify-content: space-around; padding: 20px;">
<div style="text-align: center;">
<div style="font-size: 32px; color: #27ae60; font-weight: bold;">$125K</div>
<div>Orders Today</div>
</div>
<div style="text-align: center;">
<div style="font-size: 32px; color: #3498db; font-weight: bold;">47</div>
<div>Pending Fulfillment</div>
</div>
<div style="text-align: center;">
<div style="font-size: 32px; color: #e74c3c; font-weight: bold;">12</div>
<div>Overdue Invoices</div>
</div>
</div>
`;
};

Best Practices​

Performance​

  • Cache search results when possible
  • Limit rows displayed (use pagination)
  • Avoid complex calculations on render

User Experience​

  • Keep portlets focused on single purpose
  • Use appropriate column widths
  • Provide clear labels and formatting

Security​

  • Respect user permissions
  • Filter data based on role
  • Validate form submissions