# Serialize form data

Turn a form’s fields into an object; repeated names become arrays.

Canonical: https://1loc.dev/dom/serialize-form-data/
Version: 1.0.0
Runtime: JavaScript · modern browsers (DOM)
Verification: Usage lines executed in headless Chromium against the fixture markup; no external services
Updated: 2026-10-28

## Implementation

```javascript
function serialize(form) {
  const groups = new Map();
  for (const [key, value] of new FormData(form)) groups.set(key, [...(groups.get(key) ?? []), value]);
  return Object.fromEntries([...groups].map(([key, values]) => [key, values.length > 1 ? values : values[0]]));
}
```

## Usage

Markup:

```html
<form id="signup">
  <input name="email" value="ana@example.com">
  <input name="alias" value=""><input name="alias" value="ana.s">
  <input type="checkbox" name="topic" value="product" checked>
  <input type="checkbox" name="topic" value="security" checked>
  <input type="checkbox" name="topic" value="events">
</form>
```

Script:

```javascript
serialize(document.querySelector('#signup')); // → { email: 'ana@example.com', alias: ['', 'ana.s'], topic: ['product', 'security'] }
```

Lines marked → were executed in headless Chromium against the markup above, and each result was compared with the value shown. Lines marked e.g. are illustrative.

## Limits

- The original tested the first value for truthiness, so an empty first value was dropped: alias would have been "ana.s".
- Unchecked checkboxes and disabled fields are not submitted, so they are absent, like the events topic. File inputs produce File objects, which JSON cannot carry; send the FormData itself for uploads.
- Object.fromEntries keeps a field named __proto__ as ordinary data.

The function does not validate its arguments. Add checks where it receives untrusted input.

## Source and license

Original: https://github.com/phuocng/1loc/blob/14b481cf60dff1620ab1bb99a43b1f68068cdd9b/contents/serialize-form-data.mdx
Author: Nguyen Huu Phuoc and original contributors
Contributors: See original repository history
Source commit: 14b481cf60dff1620ab1bb99a43b1f68068cdd9b
Copyright (c) 2020 phuoc-ng
License: MIT — https://1loc.dev/licenses/
Maintainer: Oveyon
Modifications: Keeps empty first values and __proto__ field names; the original dropped an empty first value. Executed in Chromium. Original MDX retained as inert source evidence.
