# Encoding

The `TextEncoder` and `TextDecoder` interfaces of Azion Runtime convert between strings and bytes. A `TextEncoder` turns a string into UTF-8 bytes, and a `TextDecoder` turns bytes back into a string of code points. For more information, refer to [TextEncoder](https://developer.mozilla.org/en-US/docs/Web/API/TextEncoder) and [TextDecoder](https://developer.mozilla.org/en-US/docs/Web/API/TextDecoder) on MDN Web Docs.

> **Note**
>
> Under `azion dev`, the two error messages differ from the deployed ones listed in Errors: an unsupported label throws `RangeError: The "nope" encoding is not supported`, and a `fatal` decoder throws `TypeError: The encoded data was not valid for encoding utf-8`.

---

## Constructors

The `TextEncoder()` constructor returns an encoder that produces UTF-8 bytes. It takes no parameters:

```javascript
let encoder = new TextEncoder();
```

The `TextDecoder()` constructor returns a decoder for the encoding that `utfLabel` names:

```javascript
let decoder = new TextDecoder(utfLabel, options);
```

| Parameter  | Type   | Required | Default | Description                                                       |
| ---------- | ------ | -------- | ------- | ----------------------------------------------------------------- |
| `utfLabel` | String | No       | `utf-8` | Label of the encoding to decode, such as `utf-8` or `iso-8859-1`. |
| `options`  | Object | No       | —       | Options of the decoder: `fatal` and `ignoreBOM`.                  |

The `options` object takes these properties:

| Option      | Type    | Description                                                                               |
| ----------- | ------- | ----------------------------------------------------------------------------------------- |
| `fatal`     | Boolean | When `true`, `decode()` throws a `TypeError` on bytes that are not valid in the encoding. |
| `ignoreBOM` | Boolean | Byte order mark (BOM) option of the decoder. It is `false` when the option is not set.    |

The decoder accepts these labels. The `encoding` property of the decoder reports the encoding name each label resolves to:

| Label          | `encoding`     |
| -------------- | -------------- |
| `utf-8`        | `utf-8`        |
| `utf-16le`     | `utf-16le`     |
| `utf-16be`     | `utf-16be`     |
| `latin1`       | `windows-1252` |
| `iso-8859-1`   | `windows-1252` |
| `windows-1252` | `windows-1252` |
| `shift_jis`    | `shift_jis`    |
| `gbk`          | `gbk`          |

For example, a decoder created with `iso-8859-1` decodes the bytes `[0x6f, 0x6c, 0xe1]` as `olá`.

---

## Properties

| Property    | Interface     | Type    | Description                                                          |
| ----------- | ------------- | ------- | -------------------------------------------------------------------- |
| `encoding`  | `TextEncoder` | String  | Encoding of the encoder: `utf-8`.                                    |
| `encoding`  | `TextDecoder` | String  | Encoding the label resolved to, such as `windows-1252` for `latin1`. |
| `fatal`     | `TextDecoder` | Boolean | Value of the `fatal` option.                                         |
| `ignoreBOM` | `TextDecoder` | Boolean | Value of the `ignoreBOM` option.                                     |

---

## Methods

| Method                                   | Description                                                                                                                                             |
| ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `encoder.encode(string)`                 | Encodes `string`, a USVString that holds the text, and returns its UTF-8 bytes as a `Uint8Array`. `encode('Azion')` returns `[65, 122, 105, 111, 110]`. |
| `encoder.encodeInto(string, uint8Array)` | Writes the UTF-8 bytes of `string` into `uint8Array` and returns an object with `read` and `written`.                                                   |
| `decoder.decode(buffer, options)`        | Decodes `buffer` with the encoding of the decoder and returns the text as a string.                                                                     |

The `encodeInto()` method does not write a character whose bytes do not fit. Encoding `olá` into a 3-byte `Uint8Array` returns `read` `2` and `written` `2`, and leaves the array as `[111, 108, 0]`, because `á` takes two bytes.

The `decode()` method takes its two parameters in any of these three forms:

```javascript
decoder.decode(buffer, options);
decoder.decode(buffer);
decoder.decode();
```

| Parameter | Type                               | Required | Default | Description                                                                         |
| --------- | ---------------------------------- | -------- | ------- | ----------------------------------------------------------------------------------- |
| `buffer`  | `ArrayBuffer` or `ArrayBufferView` | No       | —       | Bytes of the text to decode. Called without it, `decode()` returns an empty string. |
| `options` | Object                             | No       | —       | Decode options with one property, `stream`.                                         |

The `stream` option is a Boolean that defaults to `false`. Set it to `true` when you decode data in chunks and more data follows in later calls to `decode()`. Set it to `false`, or leave it out, for the final chunk and for data that is not split. A decoder that receives the first two bytes of a four-byte character with `stream: true` returns the full character when the next call passes the remaining two bytes.

---

## Errors

| Error                                                          | Cause                                                                                   | Fix                                                      |
| -------------------------------------------------------------- | --------------------------------------------------------------------------------------- | -------------------------------------------------------- |
| `RangeError: The encoding label provided ('nope') is invalid.` | `new TextDecoder()` received a label it does not support, here `nope`.                  | Pass a supported label, such as one in the label table.  |
| `TypeError: The encoded data is not valid`                     | A decoder created with `fatal: true` received bytes that are not valid in its encoding. | Check that the bytes match the encoding the label names. |

---

## Example

This listener decodes four UTF-8 bytes into one character, logs it, and returns it as the response body:

```javascript
addEventListener("fetch", (event) => {
  event.respondWith(handleRequest(event.request, event.console))
})

async function handleRequest(request, console_from_event) {
  let utf8decoder = new TextDecoder()
  let u8arr = new Uint8Array([240, 160, 174, 183]);
  let decoded_str = utf8decoder.decode(u8arr)

  console_from_event.log(decoded_str)

  return new Response(decoded_str)
}
```

The function logs `𠮷` and returns this status, these headers, and this body:

```json
{
 "status": 200,
 "statusText": "",
 "headers": {
  "content-type": "text/plain;charset=UTF-8"
 },
 "body": "𠮷"
}
```

---

## Related resources

- [Response](/en/documentation/devtools/runtime/api-reference/response.md): How a function returns the text it encodes or decodes as a response body.
- [FetchEvent](/en/documentation/devtools/runtime/api-reference/fetch-event.md): The event the example receives, and its `console` object.
- [node:string\_decoder](/en/documentation/devtools/runtime/node/string-decoder.md): The Node.js module for decoding bytes in multibyte chunks.
- [Web APIs](/en/documentation/devtools/runtime/api-reference/javascript.md): The other Web APIs that Azion Runtime supports.
