14 minutes Read

Published On

NetSuite Advanced PDF/HTML Templates: The Complete Guide to FreeMarker, Multilingual Setup, and Custom Branding

Key Takeaways

  • NetSuite Advanced PDF/HTML templates use a combination of HTML, CSS, FreeMarker scripting, and BFO rendering to give you full control over every transaction document your business sends.
  • Multilingual templates do not require a separate file per language. The @translations directive and conditional FreeMarker logic let a single template serve multiple languages automatically based on customer or subsidiary locale.
  • The most common template errors follow a predictable pattern. Knowing the five usual causes before you build saves hours of debugging after go-live.

When did you last open one of the transaction documents your business sends out and actually read it the way a customer would? Not to check if the numbers are right, but to check if it looks like it came from your company. Has your logo been there since day one, or did someone add it two years ago and call it done? Does it show a PO reference number that your customer needs to match to their purchase records, or does that still require a phone call? 

If any of those questions gave you pause, the invoice your business sends today is probably doing less work than it should. It may be technically accurate with the right numbers, but it carries no brand identity, misses the customer’s language, omits the fields your industry requires, and looks identical to every other NetSuite user’s invoice. 

According to PwC, 65% of online shoppers find a positive customer experience more influential than advertising. Every document you send to your customer is part of that experience. An invoice in the wrong language, missing the customer’s PO reference, with a generic header and no logo, is not a neutral transaction. It is a small signal that your business did not think about the person receiving it.

NetSuite’s Advanced PDF/HTML templates are what you use to fix that. This guide covers everything you need to build templates that represent your brand, serve your customers in the right language, and include every field your business and your industry actually need.

What Are NetSuite Advanced PDF/HTML Templates?

Before you open the template editor, it helps to understand exactly what you are working with and how it differs from the basic alternative.

A NetSuite Advanced PDF/HTML template is a fully customizable document definition that controls the layout, content, and logic of printed and emailed transaction documents. This applies to invoices, sales orders, purchase orders, packing slips, customer statements, and more.

NetSuite gives you two options for PDF output:

  • Basic PDF templates: Fixed layouts with drag-and-drop field placement. Limited flexibility, no conditional logic, no dynamic content. Found under Customization > Forms > Transaction Form PDF Layouts.
  • Advanced PDF/HTML templates: Full HTML, CSS, FreeMarker, and BFO rendering. Pixel-level control, conditional logic, dynamic data, multilingual support, barcodes, and custom fonts. Found under Customization > Forms > Advanced PDF/HTML Templates.

If you are reading this guide, you need Advanced templates. Basic layouts run out of capability the moment your requirements go beyond field placement.

To enable the feature: Go to Setup > Company > Enable Features, open the SuiteCloud tab, and check the Advanced PDF/HTML Templates box under SuiteBuilder. Until this is enabled, the option does not appear in the Customization menu.

The Four Technologies Behind Every Advanced Template

Think of building a NetSuite PDF template like building a house. Each material serves a different structural purpose, and using the wrong one for the wrong job is where most problems start.

  1. HTML is the frame. It defines the document structure: tables, headers, footers, sections, and rows. If you want two columns on a page or a table of line items, that is HTML work.
  2. CSS handles the finishing. Fonts, colors, borders, spacing, and visual alignment. Most CSS2 properties are supported, though some CSS3 properties are not rendered by the BFO engine.
  3. FreeMarker is the plumbing. It is the templating language that bridges NetSuite’s data and your HTML structure. FreeMarker pulls field values from the transaction record, runs conditional logic, loops over line items, and formats numbers and dates. Every dynamic element in your template goes through FreeMarker.
  4. BFO (Big Faceless Organization) is the rendering engine that converts everything into a PDF file. It handles PDF-specific capabilities that HTML and CSS cannot: custom font loading, barcode and QR code generation, page numbering, watermarks, and multi-page layout management.

Understanding which layer handles which job prevents the most common build errors: developers who try to use CSS to do what FreeMarker does, or HTML to do what BFO does.

How to Create Your First Advanced PDF Template

When you first open the template list at Customization > Forms > Advanced PDF/HTML Templates, you will see a set of standard templates. The right starting point is almost always to clone an existing standard template rather than build from scratch.

Why clone rather than build fresh:

  • The DOCTYPE declaration and BFO wrapper are already correct. Advanced PDF templates require a specific XML declaration on line one and a BFO DOCTYPE declaration on line two before any HTML content begins. If either is missing or incorrectly formatted, the template fails to render entirely and NetSuite returns a generic error rather than a useful one. Cloning an existing standard template means these two structural requirements are already in place and verified.
  • The basic field structure is already in place. Standard templates include the core transaction fields, header information, line item table, totals, and footer already wired to the correct NetSuite field references. Rather than building those connections from scratch and risking incorrect internal IDs, you start with a working template and modify what you need to change rather than rebuilding what already works.
  • You avoid the blank-page problem. A template built from scratch that is missing a required structural element, an unclosed HTML tag, a missing BFO wrapper, an incorrect XML namespace produces a completely blank PDF when printed. That error is difficult to diagnose because NetSuite does not always indicate where the structural problem is. Cloning guarantees the structural skeleton is valid before you write a single line of custom code.

Once you have your cloned template, click Customize/Edit. You will see two editing modes:

WYSIWYG mode

A visual editor is optimal for layout previewing. Useful for getting a rough sense of structure, but limited in what it can do and prone to adding unwanted code when you drag elements around.

Source Code mode

The source code mode is where real customization happens. Click the Source Code button, confirm the warning, and you are now working directly with the HTML, CSS, and FreeMarker that define the template.

Finding field internal IDs: Every field you want to print needs its internal ID. Two ways to find these:

  • Go to Home > Set Preferences and enable Show Internal IDs. NetSuite will then display field IDs in tooltips when you hover over field labels.
  • Use the NetSuite Records Browser (available in SuiteAnswers) to browse all fields for any record type.

Field syntax:

  • ${record.fieldname} for standard transaction fields
  • ${result.fieldname} for saved search results
  • ${record.fieldname!””} for null safety — this prevents the template from throwing an error when a field has no value

Saving and attaching: Once your template is saved, go to the transaction form it should apply to (Customization > Forms > Transaction Forms), click Customize on the relevant form, and set your template as the preferred PDF template. From that point, any transaction using that form will print using your template.

FreeMarker Essentials for NetSuite Templates

FreeMarker is what makes an Advanced template genuinely useful rather than just a styled static layout. Here are the five capabilities you will use most often, each with the syntax pattern that makes them work.

Printing a field value:

${record.tranid}

Prints the transaction number. Replace tranid with the internal ID of any field you want to display.

Conditional logic:

<#if record.custbody_vatnumber?has_content>

  VAT Reg: ${record.custbody_vatnumber}

</#if>

Shows the VAT registration number only if the field contains a value. This pattern applies to any field you want to show or hide based on a condition.

Looping over line items:

<#list record.item as line>

  <tr>

    <td>${line.item}</td>

    <td>${line.quantity}</td>

    <td>${line.rate}</td>

  </tr>

</#list>

Generates one table row per line item on the transaction. This is how every line item table in a NetSuite PDF is built.

Formatting a currency value:

${record.total?string.currency}

Formats a number as currency using the transaction’s currency symbol and formatting rules.

Null safety:

${record.ponumber!”N/A”}

Prints the PO number if it exists, or “N/A” if it does not. Without this, an empty field throws a FreeMarker error, and the PDF fails to generate.

Creating Templates in Other Languages

This is where NetSuite’s Advanced templates become genuinely powerful for international businesses, and where almost no other guide goes far enough.

When did you last open one of your transaction PDFs and check how it reads for a customer in Germany, the UAE, or Mexico? If the answer is “not recently” or “I assumed it was handled,” it is worth checking.

NetSuite gives you two approaches to multilingual templates:

Approach 1: Separate template per language

Create a distinct template file for each language, translate the static labels manually, and assign the correct template to customers or subsidiaries based on their locale. This is straightforward to set up but creates a maintenance overhead: when your invoice layout changes, you have to update every language version.

Approach 2: Single template with conditional language logic

The more sustainable approach. Use FreeMarker conditionals based on the customer’s language or subsidiary locale to switch label text within a single template file:

<#if record.custbody_language == “es”>

  <td>Cantidad</td>

<#elseif record.custbody_language == “de”>

  <td>Menge</td>

<#else>

  <td>Quantity</td>

</#if>

This keeps layout changes in one file. Update the design once, and every language version reflects it immediately.

Right-to-left language support

For Arabic, Hebrew, or Urdu, add the CSS direction property to your body or table elements:

css

body { direction: rtl; text-align: right; }

This flips the document flow correctly for RTL scripts. Combined with a custom Arabic font loaded via BFO’s @font-face declaration, you get a properly formatted Arabic invoice from the same NetSuite template.

Character encoding

For non-Latin scripts, ensure your template’s XML declaration specifies UTF-8 encoding:

<?xml version=”1.0″ encoding=”UTF-8″?>

Without this, characters outside the Latin set may render as garbled text or question marks in the PDF output.

Common Template Errors and How to Fix Them

If your template looks right in the editor but breaks when you print a real transaction, one of these five things is almost certainly why.

1. Empty field output

The PDF renders, but a field you expected shows as blank. Almost always caused by an incorrect internal ID or a missing null safety operator. Verify the field’s internal ID in Show Internal IDs mode and add the !”” null safety pattern to the field reference.

2. DOCTYPE error on save

The template fails to save or throws an error on the first line. The XML declaration <?xml version=”1.0″?> and the BFO DOCTYPE declaration must be the first two lines of the template. If either is missing or the DOCTYPE syntax is wrong, the file is invalid before FreeMarker even runs.

3. FreeMarker null pointer exception

The PDF generation fails with a FreeMarker error message referencing a null value. A field reference is returning null for the transaction being printed. Add ?if_exists or the !”” null safety pattern to every field reference that might be empty on some records.

4. PDF layout breaking on certain transactions

The template works for most transactions but breaks for specific ones. The most common cause is a #list loop hitting an empty sublist. Wrap the loop with <#if record.item?has_content> before iterating.

5. Custom font not rendering

The PDF displays a fallback font instead of your branded typeface. The font file must be uploaded to NetSuite’s file cabinet, and the BFO @font-face declaration in the template must reference the exact file path. Check both the file path and the BFO font-face syntax in the template header.

Industry-Specific Template Patterns Worth Knowing

The right template for your business depends on what your customers and your industry expect to see. Here are the most common patterns across the verticals Folio3 works with.

Manufacturing

Part numbers sit in a dedicated column separate from the item description, because procurement teams on the receiving end match by part number, not product name. The ship-to address appears distinct from the bill-to, the PO reference number sits prominently in the header, and a barcode runs in the footer for warehouse scanning of packing slips. The barcode is generated via BFO’s barcode element rather than HTML, which means it is a single attribute in the template rather than a third-party script.

Professional Services

The SOW reference number belongs in the header so the client can match the invoice to the agreement without opening a separate document. The line item table shows deliverable name, percentage complete, and amount due for that milestone. Consultant name and billing rate appear per line. A FreeMarker conditional hides the rate column automatically when the client record is flagged as a fixed-fee arrangement, which avoids the awkward manual edit before every invoice goes out.

Retail and E-commerce

A promotional message block appears only when the customer record carries an active promotion code, which keeps the invoice clean for standard transactions and personalized when a promotion applies. The return policy sits in the footer as static text. A QR code links directly to the online returns portal. BFO generates it from a single element attribute set to the return URL; no external image generation is required.

Multi-Entity and Multinational

A FreeMarker conditional block checks which subsidiary issued the transaction and loads the corresponding logo from the file cabinet. Subsidiary registration numbers and tax IDs populate in the footer from the subsidiary record rather than hardcoded text, so adding a new entity does not require a template update. The currency symbol matches the transaction currency automatically, and column headers switch language based on the customer’s locale as covered in the multilingual section above.

Apparel

Size and color variant information needs its own column on the packing slip and invoice, separate from the base item description. Return and exchange policy text is standard footer content for most apparel businesses. For brands with a seasonal collection structure, a collection or season code field in the line item table helps buyers and warehouse teams reference the correct product batch.

Automotive

Part condition (new, remanufactured, or used) needs a dedicated column because it affects pricing, warranty terms, and customer expectations. VIN or vehicle reference numbers on sales orders and invoices are standard requirements for parts businesses. Warranty terms per line item, shown conditionally based on the part type, reduce the back-and-forth that happens when a customer queries their coverage after purchase.

Wholesale Distribution

Customer-specific pricing tiers need to be visible on the invoice so buyers can verify they received the contracted rate without calling their account manager. Freight and handling charges appear as separate line items rather than buried in totals. For multi-location distributors, the ship-from warehouse appears alongside the ship-to address, because returns and queries go back to the originating warehouse rather than the head office.

Agriculture

Lot number and harvest date fields on delivery notes and invoices are standard compliance requirements for most agricultural produce. Weight-based billing, where the invoice quantity and unit price reflect the actual weighed delivery rather than the estimated order quantity, requires a FreeMarker conditional that pulls from the actual weight field rather than the ordered quantity field. Seasonal pricing that changes by crop cycle can be handled through conditional logic that checks the transaction date against a configured season parameter.

Getting Your NetSuite Templates to the Standard Your Business Deserves

Your transaction documents are not back-office paperwork. They are the last thing your customer sees before they pay you, and often the first thing they reference when they have a question. A template that shows the right information, in the right language, with the right branding, is a straightforward investment in how your business is perceived.

The technical foundation is not as complex as it looks once you understand which layer (HTML, CSS, FreeMarker, or BFO) handles which job. The multilingual architecture requires some upfront design but pays back in maintenance savings every time your layout changes. And the five common errors that trip up most template builds are all predictable and preventable with the right patterns.

If your current NetSuite templates do not represent your brand or serve your customers the way they should, Folio3’s NetSuite customization services cover template development as part of broader customization engagements.

For companies that need a one-off template build or a full template audit across all transaction types, Folio3’s NetSuite consulting services cover that as a standalone engagement.

People Also Ask

What are NetSuite Advanced PDF/HTML templates?

NetSuite Advanced PDF/HTML templates are fully customizable document definitions that control the layout, content, and logic of printed and emailed transaction documents, including invoices, sales orders, purchase orders, packing slips, and customer statements. They use a combination of HTML, CSS, FreeMarker scripting, and BFO rendering to give developers and administrators full control over document output, including dynamic data, conditional logic, custom branding, and multilingual content.

What is the difference between basic and Advanced PDF templates in NetSuite?

Basic PDF templates use a fixed drag-and-drop editor with limited field placement options and no conditional logic or dynamic content.

Advanced PDF/HTML templates use HTML, CSS, FreeMarker, and BFO to support pixel-level layout control, conditional field visibility, line item loops, multilingual labels, custom fonts, barcodes, and dynamic content based on transaction data. Advanced templates require the feature to be enabled in Setup > Company > Enable Features.

How do I enable Advanced PDF/HTML templates in NetSuite?

Go to Setup > Company > Enable Features and open the SuiteCloud tab. Under the SuiteBuilder section, check the Advanced PDF/HTML Templates box and save. Once enabled, the option appears at Customization > Forms > Advanced PDF/HTML Templates, where you can view, clone, and customize templates.

What is FreeMarker and how is it used in NetSuite templates?

FreeMarker is an open-source templating language that NetSuite uses to inject dynamic data and logic into Advanced PDF/HTML templates. It pulls field values from transaction records using the ${record.fieldname} syntax, runs conditional logic with #if/#else directives, loops over line items with the #list directive, formats numbers and dates, and handles null safety. FreeMarker documentation is available at freemarker.apache.org for full syntax reference.

How do I print a field value in a NetSuite PDF template?

Use the syntax ${record.fieldname} where fieldname is the internal ID of the field you want to print. For standard transaction fields, use record.fieldname. For saved search results, use result.fieldname. To prevent errors when a field has no value, use the null safety pattern: ${record.fieldname!””}, which prints an empty string instead of throwing an error when the field is blank.

How do I create a NetSuite Advanced PDF template in another language?

There are two approaches. The first is to create a separate template file per language with manually translated labels, then assign each template to customers or subsidiaries based on their locale. The second, more maintainable approach is to use FreeMarker conditional logic within a single template to switch label text based on the customer’s language field or subsidiary locale. For right-to-left languages like Arabic or Hebrew, add direction: rtl; text-align: right to the CSS and load a compatible font via BFO’s @font-face declaration.

What are the most common NetSuite Advanced template errors?

The five most common errors are: empty field output caused by incorrect internal IDs or missing null safety operators; a DOCTYPE error on save caused by missing or incorrect XML and BFO DOCTYPE declarations on the first two lines; a FreeMarker null pointer exception when a field reference returns null; a PDF layout breaking on specific transactions when a #list loop hits an empty sublist; and a custom font not rendering because the BFO font-face declaration references an incorrect file path. All five are preventable with the correct syntax patterns.

How do I add a barcode or QR code to a NetSuite PDF template?

Barcodes and QR codes in NetSuite PDF templates are generated through BFO, the PDF rendering engine. BFO provides a dedicated barcode element that accepts a value attribute and an encode attribute specifying the barcode type. For a QR code, set the encode type to QR and provide the URL or string value you want encoded. The barcode element is placed in the template HTML where you want the code to appear and renders automatically when the PDF is generated.

Can I use saved searches to add additional data to a NetSuite PDF template?

Yes. Saved searches can be referenced within Advanced templates to display data that does not exist directly on the transaction record. Define a saved search against the relevant record type, reference it in the template, and use the ${result.fieldname} syntax to print values. The #list directive iterates over saved search results to generate table rows. This is useful for printing related records, open balance summaries, warranty details, or any custom data that the transaction record itself does not carry.

Meet the Author

Ahmed Noman

Digital Marketing Associate

Ahmed is a B2B digital marketer at Folio3, where he crafts content around NetSuite ERP to help businesses cut through the complexity. Through his blogs, he simplifies the latest NetSuite trends and updates, empowering businesses to stay informed and make the most of their ERP investment.

Table of Contents

Contact Us

By submitting this form, you agree to our privacy policy and terms of service.

Related resources you might be interested in

We'd love to help you with all your NetSuite needs

Folio3 Your Top Choice:

Middle East Partner 2025
education award 2025
Winner Award
Software and IT Services 2024
Financial-Services-2023
SuiteCommerce 2023

Let's discuss your NetSuite needs

Hello, How can we help you?

Get a 45-Minute
NetSuite Consulting Session

Worth $2,000 for Free

Grab the opportunity to speak with one of our top-rated consultants to get expert guidance on your NetSuite needs.