Skip to content

NetSuite PDF/HTML Template Customization Guide

Every invoice, packing slip, and purchase order that leaves your NetSuite account is a representation of your brand. The default templates look generic at best and unprofessional at worst—plain text,...

10 min read
NetSuite PDF/HTML Template Customization Guide

Affiliate Disclosure: This page contains affiliate links. We may earn a commission when you purchase through these links, at no extra cost to you.

Disclosure: NetSuiteForge may earn a commission through affiliate links in this article. We only recommend solutions we've personally implemented for ecommerce clients. Our editorial process is independent, and our recommendations are based on hands-on experience.

Every invoice, packing slip, and purchase order that leaves your NetSuite account is a representation of your brand. The default templates look generic at best and unprofessional at worst—plain text, no logo, basic formatting that screams "we just implemented new software."

For ecommerce brands, transaction templates matter even more than traditional businesses because your customers see them: order confirmations, invoices, packing slips in the box, and credit memos for returns. These documents are brand touchpoints, and they should look the part.

NetSuite uses FreeMarker (an open-source Java templating engine) to generate PDF and HTML documents from transaction data. The system is powerful but has a steep learning curve—the documentation is scattered, the debugging experience is painful, and common formatting issues waste hours if you don't know the workarounds.

This guide covers everything you need to customize NetSuite PDF/HTML templates for ecommerce, from FreeMarker basics through branded invoice templates, packing slip design, and solutions for the most common formatting problems.

Key Takeaways

  • NetSuite uses the FreeMarker templating language for PDF/HTML generation—learning basic FreeMarker syntax is essential for template customization
  • Advanced PDF/HTML Templates must be enabled before you can customize transaction documents (Setup → Company → Enable Features → SuiteCloud → Advanced PDF/HTML Templates)
  • The most common ecommerce templates to customize are invoices, packing slips, sales order confirmations, and credit memos
  • Image embedding, table formatting, and page breaks are the three areas where most customization time is spent
  • Test templates with real transaction data before deploying—edge cases (long product names, many line items, international addresses) break layouts

How Do You Get Started with Template Customization?

Enabling Advanced Templates

  1. Navigate to Setup → Company → Enable Features
  2. Go to the SuiteCloud tab
  3. Check Advanced PDF/HTML Templates
  4. Save

Once enabled, you can create and edit templates under Customization → Forms → Advanced PDF/HTML Templates.

Understanding the Template Architecture

NetSuite templates have three layers:

1. HTML/CSS: The structure and styling of the document 2. FreeMarker: Dynamic data insertion and logic (loops, conditionals) 3. BFO (Big Faceless Organization) PDF renderer: Converts HTML to PDF

The BFO renderer is important because it doesn't support all CSS features. Flexbox, Grid, and many modern CSS properties don't work. You're essentially designing for a limited HTML-to-PDF converter that supports roughly CSS 2.1 with some CSS3 features.

FreeMarker Basics

FreeMarker uses ${} for variable output and <#...> for directives:

Variable output:

${record.tranid}           <!-- Transaction number -->
${record.entity}           <!-- Customer name -->
${record.trandate}         <!-- Transaction date -->
${record.total}            <!-- Total amount -->

Conditional logic:

<#if record.shipmethod?has_content>
  Shipping: ${record.shipmethod}
</#if>

Looping through line items:

<#list record.item as item>
  <tr>
    <td>${item.item}</td>
    <td>${item.quantity}</td>
    <td>${item.rate}</td>
    <td>${item.amount}</td>
  </tr>
</#list>

Null handling (critical—unhandled nulls crash templates):

${record.memo!""}          <!-- Output empty string if memo is null -->
${record.custbody_field!"N/A"}  <!-- Output "N/A" if custom field is null -->

Common FreeMarker Gotchas

  1. Null values crash the template. Always use the !"" or ! default operator for fields that might be empty.
  2. Number formatting: Use ${item.amount?string(",##0.00")} to format numbers with commas and 2 decimal places.
  3. Date formatting: Use ${record.trandate?string("MM/dd/yyyy")} for US date format.
  4. HTML encoding: Use ${record.memo?html} to escape HTML characters in user-entered text.

How Do You Create a Branded Invoice Template?

Starting with the Default Template

Rather than building from scratch, copy the default template and modify it:

  1. Navigate to Customization → Forms → Advanced PDF/HTML Templates
  2. Find the default Invoice template
  3. Click Customize to create a copy
  4. Name it (e.g., "Branded Invoice - [Your Brand]")

Adding Your Logo

Image embedding in NetSuite templates is one of the most common customization tasks—and one of the most frustrating.

Method 1: File Cabinet URL (recommended)

  1. Upload your logo to Documents → Files → File Cabinet
  2. Get the file's Internal ID
  3. Reference it in the template:
<img src="${nsfont.src('your-logo.png')}" style="width: 200px; height: auto;" />

Or using the File Cabinet URL directly:

<img src="https://system.netsuite.com/core/media/media.nl?id=INTERNAL_ID&c=ACCOUNT_ID&h=FILE_HASH" 
     style="width: 200px;" />

Method 2: Base64 encoded image For logos that must always render (even offline):

<img src="data:image/png;base64,iVBORw0KGgo..." style="width: 200px;" />

Convert your logo to base64 using an online tool. This makes the template file larger but eliminates external URL dependencies.

Troubleshooting logo display:

  • If the logo doesn't appear in the PDF, check the file permissions in File Cabinet (must be "Available Without Login")
  • Base64 encoding is the most reliable method for PDF generation
  • Keep logos under 500KB for fast rendering

Invoice Layout Structure

A professional ecommerce invoice template structure:

<table style="width: 100%;">
  <!-- Header: Logo + Company Info + Invoice Number -->
  <tr>
    <td style="width: 50%;"><img src="..." /></td>
    <td style="width: 50%; text-align: right;">
      <strong>Invoice #${record.tranid}</strong><br/>
      Date: ${record.trandate}<br/>
      Due Date: ${record.duedate!""}
    </td>
  </tr>
</table>

<!-- Bill To / Ship To -->
<table style="width: 100%; margin-top: 20px;">
  <tr>
    <td style="width: 50%;">
      <strong>Bill To:</strong><br/>
      ${record.billaddress?html}
    </td>
    <td style="width: 50%;">
      <strong>Ship To:</strong><br/>
      ${record.shipaddress?html}
    </td>
  </tr>
</table>

<!-- Line Items -->
<table style="width: 100%; margin-top: 20px; border-collapse: collapse;">
  <thead>
    <tr style="background-color: #f0f0f0;">
      <th style="padding: 8px; text-align: left;">Item</th>
      <th style="padding: 8px; text-align: center;">Qty</th>
      <th style="padding: 8px; text-align: right;">Price</th>
      <th style="padding: 8px; text-align: right;">Amount</th>
    </tr>
  </thead>
  <tbody>
    <#list record.item as item>
    <tr>
      <td style="padding: 8px; border-bottom: 1px solid #eee;">${item.item}</td>
      <td style="padding: 8px; border-bottom: 1px solid #eee; text-align: center;">${item.quantity}</td>
      <td style="padding: 8px; border-bottom: 1px solid #eee; text-align: right;">${item.rate}</td>
      <td style="padding: 8px; border-bottom: 1px solid #eee; text-align: right;">${item.amount}</td>
    </tr>
    </#list>
  </tbody>
</table>

<!-- Totals -->
<table style="width: 40%; margin-left: auto; margin-top: 10px;">
  <tr><td>Subtotal:</td><td style="text-align: right;">${record.subtotal}</td></tr>
  <tr><td>Tax:</td><td style="text-align: right;">${record.taxtotal}</td></tr>
  <tr><td>Shipping:</td><td style="text-align: right;">${record.shippingcost!"0.00"}</td></tr>
  <tr style="font-weight: bold;">
    <td>Total:</td><td style="text-align: right;">${record.total}</td>
  </tr>
</table>

Adding Brand Colors

Use inline CSS with your brand colors:

<style>
  .header { background-color: #1a365d; color: white; padding: 20px; }
  .accent { color: #2b6cb0; }
  .total-row { background-color: #ebf4ff; }
</style>

Important: The BFO renderer has limited CSS support. Stick with:

  • Inline styles (most reliable)
  • Basic properties: color, background-color, font-size, font-weight, padding, margin, border
  • Table-based layouts (not flexbox or grid)
  • Avoid: float, position, flexbox, grid, box-shadow, border-radius (limited support)

How Do You Create Ecommerce Packing Slips?

Packing slips are the document your warehouse team uses to pick and pack orders, and the document your customer sees when they open the box. They need to serve both purposes.

Packing Slip Design Principles

For warehouse (picking):

  • Large, clear item names and SKUs
  • Prominent quantities
  • Bin/location information (if using WMS)
  • Order number and shipping method clearly visible

For customer (in-box):

  • Branded header with logo
  • No pricing information (standard for ecommerce packing slips)
  • Return instructions
  • Customer service contact
  • Optional: promotional message or coupon code

Hiding Prices on Packing Slips

Ecommerce packing slips typically don't show prices (the customer already has a receipt):

<!-- Only show item and quantity, no pricing -->
<#list record.item as item>
<tr>
  <td>${item.item}</td>
  <td>${item.description!""}</td>
  <td style="text-align: center;">${item.quantity}</td>
</tr>
</#list>

Adding Return Instructions

Add a footer section to your packing slip template:

<div style="margin-top: 30px; padding: 15px; border: 1px solid #ddd; font-size: 10px;">
  <strong>Returns & Exchanges</strong><br/>
  To initiate a return, visit yourstore.com/returns or email returns@yourstore.com<br/>
  Please include your order number: ${record.tranid}<br/>
  Returns accepted within 30 days of delivery.
</div>

What Are the Most Common Template Formatting Issues?

Issue 1: Page Breaks in the Middle of Tables

Problem: Long invoices with many line items split awkwardly across pages, sometimes cutting a row in half.

Fix:

<tr style="page-break-inside: avoid;">
  <!-- row content -->
</tr>

Or force a page break before a section:

<div style="page-break-before: always;">
  <!-- This section starts on a new page -->
</div>

Issue 2: Images Not Rendering in PDF

Problem: Logo or product images appear in HTML preview but not in the generated PDF.

Fix:

  • Ensure images are uploaded to File Cabinet with "Available Without Login" checked
  • Use absolute URLs, not relative paths
  • Consider base64 encoding for critical images
  • Keep image files under 500KB
  • Use PNG or JPEG format (SVG has limited support)

Issue 3: Fonts Not Displaying Correctly

Problem: Custom fonts don't render in PDF.

Fix: The BFO renderer supports a limited set of fonts. Safe choices:

  • Helvetica / Arial
  • Times / Times New Roman
  • Courier
  • Symbol
  • ZapfDingbats

For custom fonts, you can embed them, but it's complex. Most brands use Helvetica or Arial for PDF templates and save custom fonts for web-only communications.

Issue 4: Currency Formatting

Problem: Currency amounts display without proper formatting.

Fix:

${item.amount?string(",##0.00")}     <!-- 1,234.56 -->
$${record.total?string(",##0.00")}   <!-- $1,234.56 -->

For multi-currency:

${record.currencysymbol}${record.total?string(",##0.00")}

Issue 5: Long Product Names Breaking Layout

Problem: Long item descriptions overflow table cells and break the layout.

Fix:

<td style="word-wrap: break-word; max-width: 300px; overflow: hidden;">
  ${item.description!""}
</td>

Or truncate long descriptions:

<#if (item.description!"")?length gt 80>
  ${(item.description!"")?substring(0, 80)}...
<#else>
  ${item.description!""}
</#if>

Issue 6: Address Formatting for International Orders

Problem: International addresses don't format correctly (different country formats).

Fix: Use NetSuite's built-in address formatting:

${record.billaddress?html}

This outputs the address formatted for the country. For custom formatting:

${record.billaddressee!""}<br/>
${record.billaddr1!""}<br/>
<#if record.billaddr2?has_content>${record.billaddr2}<br/></#if>
${record.billcity!""}, ${record.billstate!""} ${record.billzip!""}<br/>
${record.billcountry!""}

How Do You Test and Deploy Templates?

Testing Process

  1. Preview with sample data: In the template editor, click "Preview" and select a real transaction to render
  2. Test edge cases: Preview with transactions that have:
    • 1 line item (minimal)
    • 50+ line items (multi-page)
    • Long product names
    • International addresses
    • Discounted items
    • Tax-exempt transactions
  3. Test PDF generation: Click "Download PDF" and check the actual PDF output (sometimes different from HTML preview)
  4. Test email delivery: Send a test email with the template attached to verify it renders correctly in email

Deploying Templates

  1. Create the template under Customization → Forms → Advanced PDF/HTML Templates
  2. Assign the template to the appropriate transaction form:
    • Navigate to Customization → Forms → Transaction Forms
    • Edit the form for the relevant transaction type
    • Under the "Printing & Email" tab, select your custom template
  3. Test in production by previewing a live transaction before emailing to customers

Template Version Control

NetSuite doesn't have built-in version control for templates. Best practices:

  • Keep a copy of each template version in your local repository or document storage
  • Name templates with version numbers: "Invoice Template v2.3"
  • Document changes in a changelog (what changed and why)
  • Keep the previous version active as a fallback until the new version is verified

Frequently Asked Questions

Can I use CSS Grid or Flexbox in NetSuite PDF templates?

No. The BFO PDF renderer supports approximately CSS 2.1 with some CSS3 additions. Use table-based layouts for reliable PDF rendering. HTML preview may show flexbox/grid correctly, but the PDF output will break.

How do I add a barcode to a packing slip?

Use a barcode font or generate barcode images. For Code 128 barcodes, upload a barcode font to the File Cabinet and reference it in your template. Alternatively, use a barcode generation service URL that returns an image based on the value passed.

Can I create different templates for different customers?

Yes. You can assign templates to custom forms, and custom forms can be assigned by customer category, sales channel, or subsidiary. For example, wholesale invoices can use a different template than DTC invoices.

How do I include product images on invoices or packing slips?

If your items have images uploaded to the File Cabinet, reference them in the template:

<#if item.itemimageurl?has_content>
  <img src="${item.itemimageurl}" style="width: 50px; height: 50px;" />
</#if>

Note: This slows PDF generation significantly if you have many line items. Use small thumbnail images (under 50KB each).

Is there a way to preview template changes without affecting live documents?

Yes. Create a copy of your template, make changes on the copy, and preview it with real transactions. Only assign the copy to your transaction forms once you're satisfied with the result. The original template continues to serve live documents until you switch.

Can I generate templates in multiple languages?

Yes. Use FreeMarker conditionals with the customer's language preference:

<#if record.entity.language == "fr_FR">
  Facture
<#else>
  Invoice
</#if>

For full multi-language support, consider creating separate templates per language and assigning them based on customer region.

Ready to Brand Your NetSuite Documents?

Professional, branded transaction documents elevate your ecommerce brand experience. Your invoices, packing slips, and order confirmations should look as polished as your website.

Start with your highest-volume document (usually the packing slip for ecommerce), get it right, then apply the same design language to invoices, credit memos, and purchase orders.

Take our free NetSuite readiness assessment → to evaluate your current template setup and get a prioritized list of documents to customize for your ecommerce brand.

Featured Products

Acumatica Cloud ERP

Acumatica is a modern cloud ERP platform with modules for financials, distribution, manufacturing, and field service. Uniquely priced by resource consumption (not per-user), making it cost-effective for growing teams. Strong for product-based businesses moving off QuickBooks.

View Deal

Microsoft Dynamics 365 Business Central

Microsoft Dynamics 365 Business Central is the leading ERP for small and mid-market businesses, deeply integrated with Microsoft 365, Teams, and Azure. Includes financials, supply chain, sales, and project management. A natural upgrade path for QuickBooks Desktop users.

View Deal
Oracle NetSuite ERP

Oracle NetSuite ERP

Oracle NetSuite is the world's leading cloud ERP, trusted by 40,000+ organizations. Purpose-built for ecommerce with native multi-channel inventory, automated revenue recognition, and real-time financial consolidation. Submit the quote form to be matched with a verified Oracle NetSuite specialist. Same-day response, no spam.

View Deal

Xero Accounting Software

Xero is a cloud-based accounting platform and leading QuickBooks alternative. Handles invoicing, bank reconciliation, payroll, inventory, and reporting. Over 3.5 million subscribers globally. Offers a free 30-day trial with no credit card required.

View Deal

Zoho Books

Zoho Books is a full-featured online accounting solution for small and growing businesses. Part of the Zoho One ecosystem with 50+ integrated apps including CRM, inventory, HR, and project management. Significantly more affordable than QuickBooks with comparable features.

View Deal

Sage Intacct

Sage Intacct is a cloud-based financial management solution designed for mid-market companies outgrowing QuickBooks. Features include multi-entity management, advanced reporting, and automated revenue recognition. AICPA preferred financial management solution.

View Deal

FreshBooks

FreshBooks is cloud accounting software designed for service-based small businesses and freelancers. Offers invoicing, time tracking, expense tracking, project management, and automated recurring billing. A popular QuickBooks alternative praised for its ease of use.

View Deal

Wave Accounting (Free)

Wave is a free cloud accounting software designed for freelancers, consultants, and small service businesses. Includes unlimited invoicing, expense tracking, and financial reporting at no cost. Earns revenue on payroll and payment processing add-ons. The top free QuickBooks alternative.

View Deal

Odoo ERP

Odoo is an open-source ERP platform with 50+ integrated business apps covering accounting, inventory, manufacturing, CRM, eCommerce, HR, and more. Available as community (free) or enterprise edition. A cost-effective QuickBooks alternative for businesses needing full ERP capabilities.

View Deal

SAP Business One

SAP Business One is a comprehensive ERP designed for small and mid-size businesses. Covers financials, CRM, inventory, operations, and analytics in a single system. Available on-premise or cloud. Used by 80,000+ companies in 170 countries as their growth platform beyond QuickBooks.

View Deal

Related Articles