---
url: /en/docs/api/string-transformations.md
description: >-
  Register custom string transformations in Sveltia CMS to format values in
  summaries, slugs, Compute fields and more.
---

# Custom String Transformations

Sveltia CMS comes with built-in [string transformations](/en/docs/string-transformations) like `upper`, `truncate` and `date`, which format values in template tags such as `{{title | upper}}`. You can also register your own transformations with JavaScript and use them in the same way.

## Overview

To register a custom string transformation, use the `registerStringTransformation` method on the [`CMS` object](/en/docs/api#accessing-the-cms-object):

```js
CMS.registerStringTransformation(name, transform);
```

### Parameters

* `name` (string): The name of the transformation, used in template tags like `{{title | name}}`. It can contain letters, digits and underscores, and cannot start with a digit. The names of the built-in transformations, such as `upper` and `default`, are reserved and cannot be used. Registering a transformation with the same name again replaces the previous one.
* `transform` (function): A function that transforms a value. See below for details.

An error is thrown if the name is invalid or reserved, or if `transform` is not a function.

### Transform Function

The `transform` function receives two arguments and returns the transformed string:

```js
const transform = (value, { args, locale }) => {
  // Return the transformed value
};
```

* `value`: The value of the template tag, or the output of the previous transformation if transformations are chained. It’s usually the field’s display value, such as the label of a selected option in a [Select](/en/docs/fields/select) or [Relation](/en/docs/fields/relation) field, but it’s not always a string: a [Boolean](/en/docs/fields/boolean) field value may come as a boolean, and a missing value as `undefined`. Convert it with `String(value)` if you need a string.
* `args`: An array of the arguments given to the transformation in the template tag. A quoted argument comes as a string, and an unquoted one as a number. For example, `{{title | pad(10, '-')}}` gives `[10, '-']`. The array is empty if no arguments are given.
* `locale`: The locale code of the entry content being processed, such as `en` or `ja`, which is useful for locale-aware formatting. It’s `undefined` if [internationalization](/en/docs/i18n) is not enabled for the collection.

The function must return the result synchronously; async functions are not supported. A return value other than a string is converted to a string, with `null` and `undefined` resulting in an empty string.

If the function throws an error or returns a Promise, the original value is used as is, so a broken transformation doesn’t break the CMS. The error is logged to the browser console the first time it happens for each transformation.

## Using Custom Transformations

Once registered, a custom transformation can be used in [all the contexts](/en/docs/string-transformations#available-contexts) where the built-in ones are supported, including the collection `summary`, `slug`, `path` and `preview_path` options, and the Compute field’s `value` option. The same [syntax rules](/en/docs/string-transformations#syntax) apply:

* String arguments must be enclosed in single quotes, while numeric arguments should not be quoted. Other kinds of arguments, such as `true` or a field name without quotes, are not supported; the transformation is ignored if it has any of them.
* Custom transformations can be chained with each other and with the built-in ones, e.g. `{{title | reverse | upper | truncate(20)}}`.

Like the `default` and `ternary` transformations, a string argument can contain [nested template tags](/en/docs/string-transformations#default) to use other field values, e.g. `{{title | wrap('[', ' {{fields.subtitle}}]')}}`.

A transformation that isn’t registered is ignored, and the value is used as is.

### Missing Values

Like the built-in `default` transformation, a custom transformation also runs when the field has no value, so it can provide a fallback value. In entry slugs and file paths, a template tag without a value is usually replaced with a random ID, and in the `preview_path` option, the preview link is not shown. With a custom transformation, its result is used instead, unless it’s an empty string.

In List and Object field summaries and editor component summaries, however, a missing value results in an empty string without running any transformations.

### When to Register

Register custom transformations before or right after the CMS is initialized, in the same script, so they are available when entry summaries and field values are first rendered. Entry summaries are cached, so a transformation registered later, e.g. after a delayed callback, may not be applied to the entries that have already been displayed.

## Examples

### Simple Transformation

The following example registers a `reverse` transformation that reverses the characters of a string:

```js
CMS.registerStringTransformation('reverse', (value) => [...String(value)].reverse().join(''));
```

It can be used like this:

```yaml
summary: '{{title | reverse}}'
```

### Transformation with Arguments

The following example registers a `replace` transformation that replaces all occurrences of a string with another string:

```js
CMS.registerStringTransformation('replace', (value, { args: [search, replacement] }) =>
  String(value).replaceAll(search, replacement),
);
```

For example, use it to show a slug-like field value with spaces in the entry summary:

```yaml
summary: "{{fields.code | replace('-', ' ') | upper}}"
```

### Locale-Aware Formatting

The following example registers a `locale_upper` transformation that converts a string to uppercase using the rules of the entry locale. Unlike the built-in `upper` transformation, it converts the Turkish `i` to `İ` rather than `I` when the locale is `tr`:

```js
CMS.registerStringTransformation('locale_upper', (value, { locale }) =>
  String(value).toLocaleUpperCase(locale),
);
```

```yaml
summary: '{{title | locale_upper}}'
```

### Fallback Value

The following example registers a `fallback` transformation that works like the built-in `default` transformation, but also treats a value consisting only of whitespace as empty:

```js
CMS.registerStringTransformation(
  'fallback',
  (value, { args: [fallbackValue] }) => String(value ?? '').trim() || fallbackValue,
);
```

```yaml
slug: "{{fields.slug | fallback('{{fields.title}}')}}"
```

### Compute Field

Custom transformations are especially useful in the [Compute](/en/docs/fields/compute) field’s `value` option to save a derived value. The following example saves the initials of the `name` field value:

```js
CMS.registerStringTransformation('initials', (value) =>
  String(value ?? '')
    .split(/\s+/)
    .filter(Boolean)
    .map((word) => word[0].toUpperCase())
    .join(''),
);
```

```yaml
fields:
  - name: name
    label: Name
  - name: initials
    label: Initials
    widget: compute
    value: '{{fields.name | initials}}'
```
