# Configure Smart Strings

> Set up a project-wide default formatter and customize Smart Strings formatting in code.

Set up a project-wide default formatter and customize Smart Strings formatting in code.

A Smart String is formatted by a [`SmartFormatter`](/engine/6000.7/script-reference/unity/smartstrings/smartformatter.md), which holds an ordered list of sources and formatters. You configure the formatter once for the whole project in a settings asset, or build a custom formatter in code and call it directly.

## Set a project-wide default formatter

Create a Smart Strings settings asset to define the default formatter for the project and include it in player builds:

1. Open Editor > **Smart Strings**.
2. Select **Create** and choose where to save the asset.
3. Edit the **Smart Formatter** field on the asset to add, remove, or reorder sources and formatters.

The asset is a [`SmartStringsSettings`](/engine/6000.7/script-reference/unity/smartstrings/smartstringssettings.md) [ScriptableObject](https://docs.unity3d.com/ScriptReference/ScriptableObject.html). Its `SmartFormatter` property is initialized with [`Smart.CreateDefaultSmartFormat()`](/engine/6000.7/script-reference/unity/smartstrings/smart/createdefaultsmartformat.md). The active asset is stored as an [EditorBuildSettings](https://docs.unity3d.com/ScriptReference/EditorBuildSettings.html) config object and added to the player's preloaded assets at build time, so it ships in the player and registers itself at startup.

For details on the asset's properties, refer to [Smart Strings settings](/engine/6000.7/manual/scripting/smart-strings/settings.md).

## Customize the formatter in code

[`Smart.Default`](/engine/6000.7/script-reference/unity/smartstrings/smart/default.md) is the default `SmartFormatter` used by the static [`Smart.Format`](/engine/6000.7/script-reference/unity/smartstrings/smart/format.md) methods. It is created on first use from `Smart.CreateDefaultSmartFormat()`, which registers all core sources and formatters.

`Smart.Default` is marked `[ThreadStatic]`, so each thread gets its own instance. Configure it on every thread that uses it.

To start from a fresh formatter with the core extensions registered, call `Smart.CreateDefaultSmartFormat()`:

```cs
var formatter = Smart.CreateDefaultSmartFormat();
```

### Add, remove, and reorder extensions

Sources and formatters are tried in list order, so the order changes which one handles a placeholder. Configure the lists on a `SmartFormatter` with these methods:

| Method                                                               | Description                                                                                                                                            |
| -------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `AddExtensions(params ISource[])`                                    | Adds source extensions. Well-known sources are inserted at their recommended position; others go at the end. A type that's already present is skipped. |
| `AddExtensions(params IFormatter[])`                                 | Adds formatter extensions, with the same insertion and deduplication rules.                                                                            |
| `InsertExtension(int, ISource)` / `InsertExtension(int, IFormatter)` | Inserts a single extension at an explicit position in the list.                                                                                        |
| `RemoveSourceExtension<T>()` / `RemoveFormatterExtension<T>()`       | Removes the extension of type `T`. Returns `true` if it was found and removed.                                                                         |
| `GetSourceExtension<T>()` / `GetFormatterExtension<T>()`             | Returns the extension of type `T`, or `null` if it isn't registered.                                                                                   |

Refer to [`Smart.Format`](/engine/6000.7/script-reference/unity/smartstrings/smart/format.md) for API reference. An extension that implements both [`ISource`](/engine/6000.7/script-reference/unity/smartstrings/core/extensions/isource.md) and [`IFormatter`](/engine/6000.7/script-reference/unity/smartstrings/core/extensions/iformatter.md) is registered in both lists automatically. The `AddExtensions` and `InsertExtension` methods return the same `SmartFormatter`, so you can chain calls.

```cs
// Remove a source and a formatter.
            formatter.RemoveSourceExtension<DictionarySource>();
            formatter.RemoveFormatterExtension<PluralLocalizationFormatter>();

            // Add a custom source at the front so it's tried first.
            formatter.InsertExtension(0, new MySource());

            // Look up an existing extension.
            var properties = formatter.GetSourceExtension<PropertiesSource>();
```

## Format a Smart String

Call the static `Smart.Format` to format with `Smart.Default`. Pass an [IFormatProvider](https://learn.microsoft.com/en-us/dotnet/api/system.iformatprovider) (such as a [CultureInfo](https://learn.microsoft.com/en-us/dotnet/api/system.globalization.cultureinfo)) to control culture-dependent formatting:

```cs
// "Total: 1,234.5"
            Smart.Format("Total: {0}", 1234.5);

            // Format with a specific culture.
            Smart.Format(CultureInfo.GetCultureInfo("de-DE"), "Total: {0}", 1234.5);
```

The [`SmartExtensions`](/engine/6000.7/script-reference/unity/smartstrings/smartextensions.md) class adds convenience methods that use the same semantics as `Smart.Format`:

| Method                                                   | Description                                                 |
| -------------------------------------------------------- | ----------------------------------------------------------- |
| `string.FormatSmart(params object[])`                    | Formats the string as a template and returns the result.    |
| `StringBuilder.AppendSmart(string, params object[])`     | Appends the formatted result to the `StringBuilder`.        |
| `StringBuilder.AppendLineSmart(string, params object[])` | Appends the formatted result followed by a line terminator. |
| `TextWriter.WriteSmart(string, params object[])`         | Writes the formatted result to the `TextWriter`.            |
| `TextWriter.WriteLineSmart(string, params object[])`     | Writes the formatted result followed by a line terminator.  |

```cs
var result = "Hello {Name}.".FormatSmart(new Character { Name = "Lara" });

            var sb = new StringBuilder();
            sb.AppendSmart("Score: {0}", 42);
```

To write directly into a `StringBuilder` or `TextWriter` without allocating an intermediate string, call [`SmartFormatter.FormatInto(IOutput, ...)`](/engine/6000.7/script-reference/unity/smartstrings/smartformatter/formatinto.md). The convenience methods above wrap an [`IOutput`](/engine/6000.7/script-reference/unity/smartstrings/core/output/ioutput.md) around the target for you.

## Additional resources

* [Smart Strings](/engine/6000.7/manual/scripting/smart-strings.md)
* [Smart Strings settings](/engine/6000.7/manual/scripting/smart-strings/settings.md)
* [Create a custom formatter](/engine/6000.7/manual/scripting/smart-strings/formatters/create-a-custom-formatter.md)
