June 14, 2026
Leak-proof components
In a Server Components world, the boundary between server and client is a single prop away. Pass the wrong object across it and you serialize secrets straight into the HTML. On a social app the obvious danger is the session object, which often carries an auth token right next to the harmless display name.
The accidental leak
async function ProfileHeader() {
const session = await getSession()
// FollowButton is a Client Component
return <FollowButton session={session} />
}
The whole session object, including session.token, gets serialized and shipped to the browser so a client component can read one field. The token is now sitting in the page payload for anyone to grab.
The fix
React’s experimental taint APIs mark a value as server only. If anything tries to send it to the client, React throws instead of silently serializing it.
import { experimental_taintUniqueValue } from 'react'
async function ProfileHeader() {
const session = await getSession()
experimental_taintUniqueValue(
'Do not pass the session token to the client.',
session,
session.token,
)
// Pass only what the client actually needs
return <FollowButton viewerId={session.userId} />
}
Tainting turns a quiet data leak into a loud build time error. The safest secret is the one the framework refuses to let you ship.