Collaborate, Innovate, Automate

Building a Multilingual Custom Search Page with PnP Modern Search

Part 3 — Multilingual Tag Resolution and Card Updates

Part 1 covered the information architecture and prerequisites. Part 2 covered building the search page, configuring the web parts, and creating the card templates. This part covers the final layer — wiring up multilingual taxonomy tags so that filter labels and card pills switch language automatically based on the user's locale.

Note: This is a technical companion page to the PnP Modern Search multilingual blog series. Part 1 covers IA and prerequisites. Part 2 covers building the search page, web part configuration, and card templates.

What We Are Completing

At the end of Part 2 the search page was fully functional with content type scoping, card templates, and result types. The one remaining piece was the taxonomy filter and card pills — both were displaying term labels in the site default language regardless of the user's locale.

This part adds:


Step 1

The OrgClassification Site Column

Create a new managed metadata site column and bind it to your term set. The column name matters — use something clean and unambiguous.

Column Settings

Apply the column to the content types used by your pages — in this guide, the Policies and Process Manuals content types.

Tag your pages with values from the term set. In this guide the terms are: Travel, Onboarding, Data protection, Career and performance, Health, Training, Procurement — each with a French translation configured in the Term Store.


Step 2

Managed Property Mapping

Once pages are tagged and a crawl has run, two crawled properties are created automatically:

Crawled Property Contains
ows_OrgClassification Plain text term label (English only)
ows_taxId_OrgClassification Term GUID and locale label data — required for multilingual

Map both at tenant level in SharePoint Admin Center → More features → Search → Manage Search Schema:

Crawled Property Managed Property Purpose
ows_OrgClassification RefinableString110 Plain label — for display if needed
ows_taxId_OrgClassification RefinableString111 Multilingual refiner and card pills
Important: RefinableString111 must be the only mapped crawled property on that managed property. Multiple mappings on the same RefinableString prevent values from indexing correctly.

After saving the mappings, trigger a reindex of the Site Pages library:

Connect-PnPOnline -Url "https://yourtenant.sharepoint.com/sites/yoursite" -Interactive -ClientId "your-client-id"
Request-PnPReIndexList -Identity "Site Pages"

Allow time for the crawl to complete. Verify the mapping is working via the REST API:

https://yourtenant.sharepoint.com/sites/yoursite/_api/search/query?querytext='RefinableString111:"Onboarding"'&selectproperties='Title,RefinableString111'

A RowCount greater than zero confirms values are indexed correctly.


Step 3

Term Store Translations

For the multilingual filter labels to switch language, every term in the term set needs a translation configured in the Term Store.

Navigate to SharePoint Admin Center → Content services → Term store → your term group → term set → click each term → Translations and synonyms tab → add the French label.

The translations can be added manually for small term sets, or via PnP PowerShell for larger taxonomies using Set-PnPTerm:

Set-PnPTerm `
    -Identity  $term.Id `
    -TermSet   "SearchTest" `
    -TermGroup "SearchTest_Taxonomy" `
    -Name      "Intégration" `
    -Lcid      1036

LCID 1036 is French. Repeat for each term. A full scripted approach for provisioning multilingual term sets from a JSON configuration file is covered in the Create Multilingual Term Store script.


Step 4

Filter Web Part Configuration

In the Search Filters web part, update the filter to use RefinableString111:

With localization enabled in the Search Results data source and French translations in the Term Store, the filter labels switch automatically when ?Locale=fr-FR is appended to the URL.

Filter panel showing French labels — Approvisionnement, Formation, Intégration

Step 5

Tags Slot Configuration

In the Search Results web part data source, map the Tags slot to RefinableString111:

  1. Open the web part edit panel
  2. Go to Layout slots
  3. Find the Tags slot
  4. Change the slot field to RefinableString111

This makes RefinableString111 available in the card template via the Tags slot, and — critically — enables the {{AutoRefinableString111}} Handlebars helper.

Layout slots configuration showing Tags slot mapped to RefinableString111
Note: Also confirm Enable localization is toggled ON in the data source settings. This is required for AutoRefinableString111 to resolve locale-aware labels.

Step 6

Updated Card Templates

The AutoRefinableString111 Helper

{{AutoRefinableString111}} is a PnP Modern Search built-in Handlebars helper that:

  1. Reads the value of RefinableString111 from the search result
  2. Detects the current page locale
  3. Resolves the correct language label from the Term Store translation data
  4. Renders the label as text

It replaces the manual split/trim approach used in Part 2 for extracting labels from raw taxonomy values.

Base Card Template

The base card template used in the All vertical is updated to use {{AutoRefinableString111}} wrapped in a styled pill span:

{{#if (slot item @root.slots.Tags)}}
<div class="card-pills">
    <span class="card-pill">{{AutoRefinableString111}}</span>
</div>
{{/if}}

Policy Vertical Card (Green Border)

The inline card template for the Policies vertical uses a green left border and green pill styling:

<li style="background-color:#ffffff; border:1px solid #dee3e9; border-left:4px solid #166534; border-radius:4px; padding:16px 20px; display:flex; flex-direction:column; gap:8px; list-style:none;">
    <div style="font-size:16px; font-weight:600; color:#101d40;">
        <a href="{{slot item @root.slots.Path}}" target="_blank" rel="noopener noreferrer" style="color:#101d40; text-decoration:none;">
            {{slot item @root.slots.Title}}
        </a>
    </div>
    {{#if (slot item @root.slots.Tags)}}
    <div>
        <span style="display:inline-block; font-size:11px; font-weight:500; padding:2px 10px; border-radius:12px; line-height:1.6; white-space:nowrap; background-color:#dcfce7; color:#166534; border:1px solid #166534;">{{AutoRefinableString111}}</span>
    </div>
    {{/if}}
</li>

Process Manual Vertical Card (Purple Border)

The inline card template for the Process Manual vertical uses a purple left border and purple pill styling:

<li style="background-color:#ffffff; border:1px solid #dee3e9; border-left:4px solid #6b21a8; border-radius:4px; padding:16px 20px; display:flex; flex-direction:column; gap:8px; list-style:none;">
    <div style="font-size:16px; font-weight:600; color:#101d40;">
        <a href="{{slot item @root.slots.Path}}" target="_blank" rel="noopener noreferrer" style="color:#101d40; text-decoration:none;">
            {{slot item @root.slots.Title}}
        </a>
    </div>
    {{#if (slot item @root.slots.Tags)}}
    <div>
        <span style="display:inline-block; font-size:11px; font-weight:500; padding:2px 10px; border-radius:12px; line-height:1.6; white-space:nowrap; background-color:#f3e8ff; color:#6b21a8; border:1px solid #6b21a8;">{{AutoRefinableString111}}</span>
    </div>
    {{/if}}
</li>

These inline card templates are used in the individual Policies and Process Manual verticals — no result types needed since all results within those verticals are the same content type.


The End Result

With all steps complete, the search page delivers a fully multilingual experience:

Related Scripts