T
TanStack6mo ago
harsh-harlequin

Disabling SSR

If I disable SSR in TanStack Start, can I safely access browser APIs like localStorage inside a route’s beforeLoad() function? Or does beforeLoad() ever run on the server even when SSR is off?
export const Route = createFileRoute('/_dashboard/_company')({
component: CompanyLayout,
ssr: false,
validateSearch: search => searchSchema.parse(search),
beforeLoad({ context }) {
const companyForm = storage.get<FormType>(import.meta.env.FORM_KEY);
return {
...context,
companyForm: companyForm,
};
},
onLeave() {
storage.remove(import.meta.env.FORM_KEY);
},
});`
export const Route = createFileRoute('/_dashboard/_company')({
component: CompanyLayout,
ssr: false,
validateSearch: search => searchSchema.parse(search),
beforeLoad({ context }) {
const companyForm = storage.get<FormType>(import.meta.env.FORM_KEY);
return {
...context,
companyForm: companyForm,
};
},
onLeave() {
storage.remove(import.meta.env.FORM_KEY);
},
});`
sometimes not able to access data from browser storage.
19 Replies
unwilling-turquoise
unwilling-turquoise6mo ago
right now beforeLoad and loader run on the server even with SSR:false we will fix this soon
harsh-harlequin
harsh-harlequinOP6mo ago
Great. Thank you Any idea on how you will handle this; Access the const companyForm = storage.get<FormType>(import.meta.env.FORM_KEY); in useEffect. And update context such that child routes can have access to the context from the parent with const context = Route.useRouteContext() storage content is updated from child routes. so router is invalidated such that other child routes can have access to new storage data.
unwilling-turquoise
unwilling-turquoise6mo ago
don't do it in an effect read from localstorage in beforeLoad once we are not running them on the server
useful-bronze
useful-bronze6mo ago
Is this still the case? I was hoping to evaluate TSS for our use-cases, but if it's currently "impossible" to make loaders run on client-only, then that sounds like we can't just yet @Manuel Schiller sorry to ping you
unwilling-turquoise
unwilling-turquoise6mo ago
on it we had a quite big refactor going on but now this can be tackled
useful-bronze
useful-bronze6mo ago
Awesome
other-emerald
other-emerald6mo ago
watching this as well 🙂
stormy-gold
stormy-gold5mo ago
Keeping an eye on this as well. For now I'm just escaping out of loaders on the server
loader: async ({ context }) => {
if (typeof window === "undefined") {
// Running on the server
// Termporarily disable server-side loading
return;
}
...Do Data Fetching...
},
loader: async ({ context }) => {
if (typeof window === "undefined") {
// Running on the server
// Termporarily disable server-side loading
return;
}
...Do Data Fetching...
},
This method only works because I'm not actually returning data from the loader and just ensuring query data for react query hooks down the line
unwilling-turquoise
unwilling-turquoise5mo ago
it's almost done
unwilling-turquoise
unwilling-turquoise5mo ago
GitHub
Release v1.125.0 · TanStack/router
Version 1.125.0 - 7/5/25, 12:36 PM Changes Feat ssr setting per route (#4565) (d728d69) by Manuel Schiller Packages @tanstack/router-core@1.125.0 @tanstack/solid-router@1.125.0 @tanstack/react-r...
stormy-gold
stormy-gold5mo ago
Just tested it out and the update is working perfect for my use case. Thank you so much! Amazing work as always
unwilling-turquoise
unwilling-turquoise5mo ago
cool! what are you building with it?
stormy-gold
stormy-gold5mo ago
I'm using tanstack start deployed to cloudflare workers. I'm working on a POC of a realtime voice and text chat app using Cloudflare's workers, durable objects, R2, and the new RealtimeKit that they just put into beta. Now I can ssr the majority of my pages and just client render the chat app for better loading UX 🙌 . I'm using BetterAuth which unfortunately has some weird gotchas with Start server-side that I'm still working through, so disabling the beforeLoad and loader on the server was vital to getting it working for now.
national-gold
national-gold5mo ago
Hi @ExtremeChunk really cool concept! How did you add durable objects bindings for cloudflare? I can't make it work ..
stormy-gold
stormy-gold5mo ago
I followed the instructions for workers in Cloudflare's docs https://developers.cloudflare.com/workers/framework-guides/web-apps/tanstack/#using-cloudflare-bindings Step 2 is the key, you have to create a getBindings util function that grabs the bindings. You can then use the getBindings function in any of your server code. Just make sure you have your bindings configured in your wrangler.jsonc and generate your binding types. This is the script I use: wrangler types ./src/types/cloudflare.d.ts --env-interface Env
Cloudflare Docs
TanStack
Create a TanStack Start application and deploy it to Cloudflare Workers with Workers Assets.
stormy-gold
stormy-gold5mo ago
Once the bindings are working it's a great DX because it also works with local development even when you're not running through wrangler
rival-black
rival-black3mo ago
how do you export the durable object though @ExtremeChunk ? nitro / tanstack start doesn't expose main file right?
unwilling-turquoise
unwilling-turquoise3mo ago
yet. soon this will be possible

Did you find this page helpful?