next/form does not normalize newlines in GET submissions after hydration
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 142k
- Forks
- 32.4k
- Avg merge
- 2d 14h
- Merged PRs (30d)
- 351
Description
Link to the code that reproduces this issue
https://github.com/Tnalxmsk/next-form-newline-repro
To Reproduce
- Clone the linked repository and open its directory.
- Run
npm ci, thennpm run build, followed bynpm run start. - Open
http://localhost:3000/newlineand wait for Hydrated: true. - Leave the textarea unchanged and click Submit native. Inspect
serverSearch.texton the result page. - Return to
/newline, wait for Hydrated: true, and click Submit next without changing the textarea. - Compare
serverSearch.textbetween the two submissions.
The same steps can also be run with npm run dev instead of the production build and start commands.
Both forms contain the same textarea with defaultValue={'line1\nline2'}. The submit buttons have no name or value attributes. No environment variables, external APIs, or account access are needed to run the reproduction.
Current vs. Expected behavior
Current behavior**
The native HTML form and hydrated next/form submit different strings for the same textarea content:
| Submission | Server-received text |
Encoded query value |
|---|---|---|
| Native HTML form | "line1\r\nline2" |
line1%0D%0Aline2 |
| Hydrated Next.js Form | "line1\nline2" |
line1%0Aline2 |
The difference is present in the server's searchParams, not just the address bar. The single-line control value is preserved in both submissions.
Expected behavior
A string-action Next.js Form should normalize line endings to CRLF, matching a native HTML GET form.
The Next.js Form documentation describes string actions as behaving like native GET forms. The HTML form submission algorithm normalizes standalone CR and LF characters in field names and values to CRLF before URL encoding.
Provide environment information
Operating System:
Platform: darwin
Arch: arm64
Version: Darwin Kernel Version 25.5.0: Mon Apr 27 20:40:51 PDT 2026; root:xnu-12377.121.6~2/RELEASE_ARM64_T8112
Available memory (MB): 16384
Available CPU cores: 8
Binaries:
Node: 24.2.0
npm: 11.3.0
Yarn: 1.22.22
pnpm: 11.24.0
Relevant Packages:
next: 16.4.0-canary.22 // Latest available version is detected (16.4.0-canary.22).
eslint-config-next: N/A
react: 19.2.1
react-dom: 19.2.1
typescript: N/A
Next.js Config:
output: N/A
Which area(s) are affected? (Select all that apply)
Form (next/form)
Which stage(s) are affected? (Select all that apply)
next dev (local), next start (local)
Additional context
- Previous report: #98404. It was automatically closed after the reproduction checker received HTTP 403 from the CodeSandbox URL. This report uses a public GitHub reproduction repository instead.
- Locally reproduced with Next.js 16.3.4 and 16.4.0-canary.22, React/ReactDOM 19.2.1, and Node 24.2.0, in both development and production. Both production builds succeeded.
- The optional CodeSandbox preview was separately verified in production with Next.js 16.4.0-canary.22, React/ReactDOM 19.2.1, and Node 20.12.0.
- Browser used for verification: Chromium-based ego-browser on macOS, with a Chrome/150.0.0.0 user agent.
- In a separate local production check, blocking
/_next/static/*requests and confirming Hydrated: false before submission caused Next.js Form to submit CRLF, like the native form. The LF result occurs after hydration. - The relevant implementation creates
new FormData(formElement)and then appends the entries directly toURLSearchParams, without normalizing line endings: form-shared.tsx. - The first affected release has not been identified.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with packages/next/src/client/form-shared.tsx at the FormData-to-URLSearchParams implementation, then run the linked reproduction using the documented npm commands. Done means hydrated string-action next/form GET submissions normalize textarea line endings to CRLF like native forms, while preserving single-line values.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, nextjs, react
- Domain
- frontend, web-dev
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 74/100