> For the complete documentation index, see [llms.txt](https://docs.fact-finder.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.fact-finder.com/webcomponents-overview/guides/essentials/formatting-and-localization.md).

# Formatting and Localization

Formatting happens at the display level in the Web Components' HTML templates. It is done by adding a formatter function to your regular data bindings.

These formatters only affect the visual output and leave the original data unchanged. Formatters are ordinary functions and may take multiple parameters or none at all.

There are several pre-defined formatters, but you also have the option to define your own.

Unformatted:

```html
<ff-record>{{variantValues.0.Price}}</ff-record>
```

Formatted with `$`, the pre-defined price formatter function:

```html
<ff-record>{{$ variantValues.0.Price}}</ff-record>

<!-- With a second parameter to override default formatting precision to zero decimals. -->
<ff-record>{{$ variantValues.0.Price 0}}</ff-record>
```

Formatters can be used in all data bindings.

## Setup

The formatters use the web platform's native localization API. See [documentation at MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat).

For them to work correctly, you have to configure your required locale.

During app initialization, you configure *locale* and *formatting options* in `appConfig`'s `formatting` parameter. This is an object with two properties: `locale` and `formatOptions`.

These are the same values that you would pass to the platform-native `Intl.NumberFormat(locales, options)` constructor. See [MDN for details](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat).

Example:

```js
document.addEventListener(`ffCoreReady`, ({ factfinder, init, initialSearch }) => {
    init({
        appConfig: {
            formatting: {
                locale: `en-GB`,
                formatOptions: {
                    style: `currency`,
                    currency: `GBP`,
                },
            },
        },
    });
});
```

## Built-in formatters

Web Components offers several default formatters for currency and generic decimal numbers, but you may also specify your own in case the default formatters don't satisfy your requirements.

The following are the built-in formatters:

### `$` (number, fractionDigits)

Formats its first parameter according to the **currency** configuration.

The second parameter is optional and allows you to override your global settings for the number of decimal places.

```html
<ff-record>
  <span>{{$ variantValues.0.Old_price 0}}</span>
  <span>{{$ variantValues.0.Price}}</span>
</ff-record>
```

### `$dec` (number, fractionDigits)

Formats **numbers** according to your *locale* settings without any units.

The second parameter is optional.

```html
<ff-record>Tolerance: {{$dec variantValues.0.Tolerance 3}} mm</ff-record>
```

### `$bctFilter`

This **currency** formatter takes no arguments and only works in `ff-breadcrumb-trail-item` elements with `type="filter"`.

It takes its input automatically from the HTML template context. This specialized formatter is necessary because of the special data structure provided in the `ff-breadcrumb-trail-item` template context.

{% hint style="warning" %}
It formats only items that are related to facets with a `unit` set.

You configure a facet's `unit` in your FactFinder UI. It must be identical to the currency unit that your Web Components formatting configuration produces.

If your `formatOptions` are configured to render a `€` symbol, your `unit` settings in the FactFinder UI must also be `€` for this particular facet.
{% endhint %}

```html
<ff-breadcrumb-trail-item type="filter">{{$bctFilter}}</ff-breadcrumb-trail-item>
```

If `$bctFilter` cannot detect how to format the received value, it will simply output the unformatted value. You can therefore use it safely even when the breadcrumb trail item displays a non-currency filter value.

### `$facetElement`

This **currency** formatter takes no arguments and only works in `ff-filter-cloud` and `ff-asn-group-element`.

It formats eligible numeric values that it receives from the HTML template context. Ineligible values are output unchanged.

{% hint style="warning" %}
Like `$bctFilter`, it only formats values related to a facet with its `unit` set to the currency symbol that your `formatOptions` produce.
{% endhint %}

```html
<ff-filter-cloud>
  <span data-template="filter">[x] {{facet.name}}: {{$facetElement}}</span>
</ff-filter-cloud>

<ff-asn>
  <ff-asn-group for-group="price">
    <ff-asn-group-element>
      <div slot="unselected">{{$facetElement}} ({{element.totalHits}})</div>
      <div slot="selected">{{$facetElement}}</div>
    </ff-asn-group-element>
  </ff-asn-group>
</ff-asn>
```

### `ff-hitHighlight` (text)

This formatter is available in elements `ff-suggest` and `ff-asn`.

It takes one argument of type String. When a search query, available in contexts of `ff-suggest` and `ff-asn`, matches part of the text, the matched portion is wrapped in a `<span class="ffw-query">` element for highlighting via CSS.

No wrapping occurs if there is no match. Always use it together with triple curly braces.

Suppose the passed text is `Gardening` and the context's search term is `garden`.

Template setup:

```html
<p>{{{ff-hitHighlight element.text}}}</p>
```

Rendered output:

```html
<p><span class="ffw-query">Garden</span>ing</p>
```

## Custom formatters

If the default formatters don't meet your requirements, you have the option to define your own formatters.

Use the `factfinder.utils.formatters.add(name, fn)` method to register them. Note that you cannot overwrite existing formatters.

The function that you pass as the second argument receives all values that are passed to it from the HTML template. The `this` keyword will be a reference of the data object available in the HTML template context.

Use the `function` keyword instead of an arrow function if you want to use `this`.

```js
factfinder.utils.formatters.add(`allCaps`, function(str) {
    return str.toUpperCase();
});
```

```html
<ff-record>{{allCaps variantValues.0.Title}}</ff-record>
```

If you use the `allCaps` formatter inside `ff-record` like in the example above, then inside the `allCaps` *function* the `this` keyword would point to the *Record* object that you can also access inside the `ff-record` HTML template itself.

### Reminder to explore

Remember that you can always place a `debugger` statement in your custom formatter functions and investigate the received parameters.

```js
factfinder.utils.formatters.add(`allCaps`, function(str) {
    debugger
    // Inspect parameters, `this`, `arguments`, etc.

    return str.toUpperCase();
});
```

### Alternative approach

As an alternative to custom formatters, you can also use the `factfinder.response.transform___` API to directly manipulate data fields and display them without any further formatting.

{% hint style="warning" %}
There are scenarios, however, where the unmodified original data is required by other actions such as tracking.

Use this approach with care. Generally, it is best to avoid cosmetic tweaks to business data.
{% endhint %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.fact-finder.com/webcomponents-overview/guides/essentials/formatting-and-localization.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
