T
TanStack•2w ago
harsh-harlequin

Selectors (such as in useLoaderData) cannot return objects that are known to be serializable

Indeed, for example, if I try to return an object that contains a Date (which is serializable, and is supported by useLoaderData without selectors), Typescript complains saying
The types of date.toString are incompatible between these types.
Type `() => string` is not assignable to type `"Function is not serializable"`
The types of date.toString are incompatible between these types.
Type `() => string` is not assignable to type `"Function is not serializable"`
18 Replies
harsh-harlequin
harsh-harlequinOP•2w ago
Route.useLoaderData({
select: () => ({ date: new Date() })
})
Route.useLoaderData({
select: () => ({ date: new Date() })
})
genetic-orange
genetic-orange•2w ago
is this in router or start?
harsh-harlequin
harsh-harlequinOP•2w ago
since this is related to non-start APIs (like useLoaderData) i would say this is more of a router issue than start; i'll try spinning up a quick repro
harsh-harlequin
harsh-harlequinOP•2w ago
No description
harsh-harlequin
harsh-harlequinOP•2w ago
yup, router issue
harsh-harlequin
harsh-harlequinOP•2w ago
GitHub
GitHub - notKamui/tsrouter-selector-serialization
Contribute to notKamui/tsrouter-selector-serialization development by creating an account on GitHub.
harsh-harlequin
harsh-harlequinOP•2w ago
the error is in src/routes/index.tsx
genetic-orange
genetic-orange•2w ago
without start being present the serializability check should not happen at all ah the issue here is that you have defaultStructuralSharing: true structuralSharing only works with serializable data
genetic-orange
genetic-orange•2w ago
Render Optimizations | TanStack Router React Docs
TanStack Router includes several optimizations to ensure your components only re-render when necessary. These optimizations include: structural sharing TanStack Router uses a technique called "structu...
genetic-orange
genetic-orange•2w ago
No description
genetic-orange
genetic-orange•2w ago
No description
harsh-harlequin
harsh-harlequinOP•2w ago
i have not though :0 unless it's the default ah yes
genetic-orange
genetic-orange•2w ago
it is not the default, by default 😄 but in the example you shared you configured the default to be true
harsh-harlequin
harsh-harlequinOP•2w ago
good find this was generated by create tsrouter app although i'd argue this does not solve the underlying problem selectors should automatically support serializable data even when structural sharing is true otherwise it would ban a category of selectors from using this (using start especially)
genetic-orange
genetic-orange•2w ago
it just doesn't work though in start we could try to serialize again potentially in router we dont have a serializer that is capable of that you can opt out of structural sharing per hook usage I just remembered. we don't really serialize at all. we just use the term "Json serializable" to represent plain objects/arrays
harsh-harlequin
harsh-harlequinOP•2w ago
yep, that's what written in the docs indeed. But, Date IS JSON serializable, but is not accepted, this is actually the sentence that prompted me to try with Date specifically not too big of a deal anyway, but this does limit selectors thanks for your time though, and great work as always
genetic-orange
genetic-orange•2w ago
we should improve the wording in the docs here
continuing-cyan
continuing-cyan•2w ago
FWIW dates aren't json serializable
> JSON.parse(JSON.stringify({ date: new Date() }))
{ date: '2025-11-13T17:14:22.165Z' }
> JSON.parse(JSON.stringify({ date: new Date() }))
{ date: '2025-11-13T17:14:22.165Z' }
they're stringifyable, but parsing them back doesn't yield a date back

Did you find this page helpful?