Open
Description
Describe the bug
When explicitly setting type="text" on the component, a hydration mismatch occurs in a Next.js 14 App Router project. The error disappears when the type prop is removed entirely. It seems that explicitly passing type="text" causes the rendered HTML on the server and client to differ, possibly due to double application of default values or prop spreading.
Affected component/components
Input
How to reproduce
Here’s a clear "How to reproduce" section you can use:
- Set up a Next.js 14 project using the App Router and
shadcn/ui
. - Create a Client Component (e.g.,
SearchInput.tsx
) that uses the<Input />
component from@/components/ui/input
. - Explicitly pass
type="text"
to the<Input />
component. - Render the component on a server-rendered page.
- Run the app and open the browser console.
- You will see the following hydration error:
Hydration failed because the server rendered HTML didn't match the client.
- Remove
type="text"
and rerun — the error disappears.
Codesandbox/StackBlitz link
No response
Logs
Error: Hydration failed because the server rendered HTML didn't match the client. As a result this tree will be regenerated on the client. This can happen if a SSR-ed Client Component used:
- A server/client branch `if (typeof window !== 'undefined')`.
- Variable input such as `Date.now()` or `Math.random()` which changes each time it's called.
- Date formatting in a user's locale which doesn't match the server.
- External changing data without sending a snapshot of it along with the HTML.
- Invalid HTML tag nesting.
It can also happen if the client has a browser extension installed which messes with the HTML before React loaded.
https://react.dev/link/hydration-mismatch
...
<InnerLayoutRouter url="/login" tree={[...]} cacheNode={{lazyData:null, ...}} segmentPath={[...]}>
<ClientPageRoot Component={function LoginPage} searchParams={{}} params={{}}>
<LoginPage params={Promise} searchParams={Promise}>
<div className="min-h-scre...">
<motion.div initial={{opacity:0,y:20}} animate={{opacity:1,y:0}} transition={{duration:0.5}}>
<div style={{opacity:0, ...}} ref={function}>
<_c className="w-full max...">
<div ref={null} className="rounded-lg...">
<_c2>
<form onSubmit={function onSubmit}>
<_c8 className="space-y-4">
<div ref={null} className="p-6 pt-0 s...">
<div className="space-y-2">
<_c>
<div className="relative">
<Mail>
<_c id="email" name="email" type="text" required={true} className="pr-10" ...>
<input
type="text"
className="flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 t..."
ref={null}
id="email"
name="email"
required={true}
placeholder="أدخل بريدك الإلكتروني"
- simplified-sapling-textarea-id="simplified-sapling-1744082780087-0"
- simplified-sapling-id="simplified-sapling-1744082780088-1"
>
- <div
- is-simplified-sapling-overlay="true"
- style={{pointer-events:"none",position:"absolute",top:"457.5px",left:"341.547px",width:"276.922px",height:"...", ...}}
- >
...
...
...
at throwOnHydrationMismatch (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom-client.development.js:13311:11)
at popHydrationState (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom-client.development.js:13449:9)
at completeWork (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom-client.development.js:13744:17)
at runWithFiberInDEV (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom-client.development.js:1511:30)
at completeUnitOfWork (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom-client.development.js:15256:19)
at performUnitOfWork (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom-client.development.js:15137:11)
at workLoopConcurrentByScheduler (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom-client.development.js:15114:9)
at renderRootConcurrent (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom-client.development.js:15089:15)
at performWorkOnRoot (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom-client.development.js:14410:13)
at performWorkOnRootViaSchedulerTask (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom-client.development.js:16275:7)
at MessagePort.performWorkUntilDeadline (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/compiled/scheduler/cjs/scheduler.development.js:45:48)
at div (<anonymous>)
at LoginPage (webpack-internal:///(app-pages-browser)/./app/(auth)/login/page.tsx:151:120)
at ClientPageRoot (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/client-page.js:20:50)
System Info
OS: macOS
Browser: Chrome 123.0
Node.js: 20
Next.js: 14
shadcn/ui: latest
React: 18
Tailwind CSS: 3.4
Before submitting
- I've made research efforts and searched the documentation
- I've searched for existing issues