# `Ash.Type.String`
[🔗](https://github.com/ash-project/ash/blob/v3.33.1/lib/ash/type/string.ex#L5)

Stores a string in the database.

A built-in type that can be referenced via `:string`.

By default, values are trimmed and empty values are set to `nil`.
You can use the `allow_empty?` and `trim?` constraints to change these behaviors.

### Constraints

* `:max_length` (`t:non_neg_integer/0`) - Enforces a maximum length on the value

* `:min_length` (`t:non_neg_integer/0`) - Enforces a minimum length on the value

* `:length_count` - The unit used by `min_length` and `max_length`. Defaults to the unit implied by
  `config :ash, :default_string_length_count` (`:codepoints`, or `:graphemes` for `:mixed`).  
  `:graphemes` matches `String.length/1`. `:codepoints` matches how most SQL data layers count
  string length. `:bytes` matches `byte_size/1`.  
  A single grapheme may contain an unbounded number of codepoints (a base character followed by
  many combining marks), so `:graphemes` places no effective limit on the size of a value.
  Prefer `:codepoints` or `:bytes` when `max_length` is used as a storage or safety limit.  
  Data layers cannot count graphemes, so with an explicit `:graphemes` the length constraints
  can only be applied to literal values, not atomically to expressions.
   Valid values are :graphemes, :codepoints, :bytes

* `:match` (`t:Regex.t/0`) - Enforces that the string matches a passed in regex

* `:trim?` (`t:boolean/0`) - Trims the value. The default value is `true`.

* `:allow_empty?` (`t:boolean/0`) - If false, the value is set to `nil` if it's empty. The default value is `false`.

# `default_length_count`

```elixir
@spec default_length_count() :: :graphemes | :codepoints
```

The default unit for counting string length, derived from
`config :ash, :default_string_length_count`.

- `:codepoints` (recommended, set by the installer) counts codepoints, matching
  SQL data layers and bounding the size of values.
- `:mixed` keeps the previous behavior: graphemes are counted in Elixir, while
  atomic expressions defer to the data layer's own length function.

The configuration is required. See the backwards compatibility guide for more.
Individual attributes and validations can still choose any unit.

# `handle_change?`

# `prepare_change?`

---

*Consult [api-reference.md](api-reference.md) for complete listing*
