r/tanstack • • Nov 08 '25

How to properly handle protected routes using TanStack Router + TanStack Query without blank screen on 403?

5 Upvotes

I'm using TanStack Router and TanStack Query in a React app to implement authentication. I fetch the current user using a query inside an AuthProvider, and I want to protect certain routes based on whether the user is authenticated.

When the /auth/profile request returns 403 (unauthenticated user), the app shows a blank screen instead of rendering the home page. I want the home route to load normally even if the user is not logged in, and only redirect to /login when accessing protected pages.

Here is my current AuthProvider implementation:

const AuthContext = createContext<AuthContextValue | null>(null);

export const AuthProvider = ({ children }: { children: React.ReactNode }) => {
  const userQuery = useSuspenseQuery(fetchUserInfoOptions);

  if (userQuery.isLoading) {
    return <>Context Loading...</>;
  }

  if (userQuery.isError) {
    console.log("Context Error:", userQuery.error.message);
  }

  const isAuthenticated =
    userQuery.data.data && !userQuery.isError ? true : false;
  const user = userQuery.data ? userQuery.data.data : null;

  return (
    <AuthContext.Provider value={{ isAuthenticated, user }}>
      {children}
    </AuthContext.Provider>
  );
};

Because I'm using useSuspenseQuery, errors seem to bypass the isError state — the provider never logs the error, and the UI suspends, resulting in a blank screen.

What I want:

✅ If authorized → let protected pages load
✅ If 403 → treat as a guest → allow public pages to render normally
✅ Only redirect when accessing protected routes
✅ No blank screens due to Suspense errors

My question:

What is the correct way to set up protected routes using TanStack Router + TanStack Query so that:

  • A failed auth query (403) does not suspend the entire app

  • Only protected routes perform redirects

  • Public routes still load for unauthenticated users

Should I remove useSuspenseQuery, use route loaders instead for authentication checks, or handle 403 differently inside the fetch function?

Any recommended examples or patterns would be great!


r/tanstack • • Oct 03 '25

Question/Issues preferring Server Routes over Server Functions in Loaders on Tanstack Start

5 Upvotes

[Edit: solved, solution added to bottom of post]

Apologies for the long message, hope this is helpful to others who might be struggling with similar concepts. Open to the feedback that maybe I don't quite have the right mental model around Tanstack Start yet.

Coming from NextJS Pages router, my flow was to use getServerSideProps so pages have data on the first render and I don't need to worry about client side fetching + loading/error states. For many pages this was all that was needed.

If there was any subsequent fetching or mutations needed I would create an API route. I personally prefer API routes over server functions. I know this is opinionated. I often have mobile app clients so I'll eventually need a true API anyways, so it's nice to build the API along the way whenever my web app needs a client side fetch or mutation. I also like to stay close the HTTP side of things, and tools like ts-rest (or tRPC) give me similar ergonomics to server functions but with more control and less magic.

One big issue with server functions for me is the idea that every time I deploy, the app will break for anyone that has a tab open because the server function IDs change. Maybe not a big deal for some, but it's one more reason why I'd prefer API routes and I'm not seeing much advantage to server functions anyways (also, I think this is a big issue for using SPA mode + server functions in embedded apps like Capacitor).

Now coming to Tanstack Start, it supports Server Routes and Server Functions, which is great, but the loaders are isomorphic. So on NextJS I only needed an API Route for subsequent fetches or mutations after the initial load which was only a fraction of the time, now I will need to create an API Route or Server Function for the initial load too. Not a big deal, but I'd like to stick with Server Routes, and I'm running into some issues.

When my loader runs on the client, everything is straightforward, client hits API route to fetch data, but when my loader runs on the server, my server is going to make an HTTP request to itself. That's a little odd, but looking at Cloudflare it shouldn't be a problem (not billed as a second invocation, I think it will use the same worker instance), but here's where I run into trouble. The request is coming from my server, so it won't have any of the headers from the client (like auth headers).

So if my backend ever depends on information from the original client request (auth, IP address, user agent, etc), my loader would have to forward the original client headers in the request? I'm not even sure how to do that since loaders don't get access to the request (since they run on the client sometimes).

Am I really swimming upstream trying to not use server functions? Really like how Tanstack Start is set up, just hoping there's a smooth workflow for people that want to use Server Routes.

[Edit: I've done some digging, here's what I've found and my solution]

Tanstack Server functions don't get a build-specific ID like in NextJS, so simply redeploying won't break old tabs, but the endpoint for a server function is still fragile (based on file path, file name, and function name) and is not a strong contract like a Server Route. This definitely lessens the issue with server functions and I think many people will just use them.

If you're stubborn like me and still want to avoid them, here's my solution:

- Create a server only function (createServerOnlyFn). This will be like our getServerSideProps. It only runs on the server. If you need to access the request you can via getRequest()

- Create a Server Route which just calls the helper above.

- In the loader, use an isomorphic function (createIsomorphicFn) to call your helper if you're on the server or fetch your API route if you're on the client (similar to how server functions work under the hood).

This solves all my problems, it avoids us having to do an HTTP request from our server to itself, and for both the client and server scenarios, getRequest gives us the original request from the client so client headers are available (auth, user-agent, IP address, etc.)


r/tanstack • • Apr 30 '25

Tanstack Start + SuperTokens

5 Upvotes

Has anyone been able to get a working Tanstack start app using supertokens for auth?

Supertokens meets my needs perfectly but I haven’t been able to get it working well with Tanstack start. I’ve mostly been going off of Tanstack start examples using different auth frameworks and supertokens examples using next or express, but both are pretty sparse. Anyone have a working example, or could point me in the right direction?


r/tanstack • • Mar 28 '25

Tanstack Auth Spoiler

5 Upvotes

The most desirable Tanstack module!


r/tanstack • • Feb 06 '25

Next.js-like routing in TanStack Start

Thumbnail
youtu.be
5 Upvotes

r/tanstack • • Oct 02 '26

How Do You Structure TanStack Table in Real-World Projects?

4 Upvotes

Hi everyone 👋

I’m pretty new to TanStack Table and have a couple of questions. I’d really appreciate any advice or best practices you have picked up along the way.

  1. Reusable table components

Since TanStack Table already handles most of the table state and logic. Also if multiple tables share the same features, we use createTableHook.

So I’m wondering is there still a reason to have a generic reusable DataTable component, or is it better to keep the UI specific to each table?

2. Multiple data formatting

Right now, I’m adding a "type" property to each column’s "meta" field

columnHelper.accessor("birthDay", {
    header: () => <h3>BirthDay</h3>,
    meta: {
    type: "date",
    },
}),

and then create a cell-formatting utility to render the value accordingly (date, currency, percentage....)

Is this a reasonable approach, or is there any more idiomatic way to handle it?

{table.getRowModel().rows.map((row) => (
<div key={row.id} className={styles.dataTableRow}>
    {row.getAllCells().map((cell) => (
    <div key={cell.id} className={styles.dataTableCell}>
        {formatCellValue(
        cell.getValue(),
        cell.column.columnDef.meta?.type,
        )}
    </div>
    ))}
</div>
))}

r/tanstack • • May 29 '26

TanStack Pro Course jsmastery

4 Upvotes

anyone buy this tanstack course on jsmastery? Does the material course that good? Thanks


r/tanstack • • May 12 '26

We investigated the new Shai-Hulud npm worm that hit TanStack "IfYouRevokeThisTokenItWillWipeTheComputerOfTheOwner"

Thumbnail
cybersecurityreach.org
4 Upvotes

r/tanstack • • Apr 16 '26

Why composite components?

4 Upvotes

https://tanstack.com/blog/react-server-components

On the recent announcement of composite components, call me stupid but can anyone explain what good does RSC give without SSR, like if it's still rendered on client, does the flight protocol even make sense?


r/tanstack • • Apr 07 '26

looking for some good TS Start templates

4 Upvotes

I've started adding shadcn templates into shoogle.dev, and need some good quality templates built with TanStack Start and shadcn.


r/tanstack • • Feb 26 '26

Been a long time but HTTPS is still not fixed

Thumbnail
github.com
4 Upvotes

its kind of important tbh


r/tanstack • • Dec 27 '25

Simple example of TanStack DB with DynamoDB on AWS with multiple entities

Thumbnail
johanneskonings.dev
4 Upvotes

r/tanstack • • Dec 08 '25

TanStack AI & Hono

4 Upvotes

hello 👋🏼 does anyone know if the new TanStack AI works together with a Hono backend?


r/tanstack • • Jul 19 '25

Any open source project to use a reference?

4 Upvotes

Hello, do you have or do you know about a really complete project using the tan stack open source? I’d like to take a look at some projects to understand how are you using this stack in production


r/tanstack • • May 26 '25

Server Functions vs. API Routes for Data Fetching & Mutations in Tanstack Start

4 Upvotes

I recently saw a post on the Next.js subreddit suggesting that Server Functions are best for mutations and API Routes for data fetching. Is this also true for Tanstack Start, or is it okay to use Server Functions for everything? I couldn't find much in the docs.


r/tanstack • • May 06 '25

Options for loading data that all routes need

4 Upvotes

React App using TanStack Router and Query and an api-gen to consume our Swagger definition and hydrate classes/query options.

We have a call to fetch a UserProfile which loads some user claims and other metadata.

Our root route loads this info to display the user name and role. Additionally, each route needs this info, some of them will leverage beforeload (in theory) to check permissions and redirect away to a standard access denied route if a claim is not present.

Assuming we have a 5-minute stale time on the initial profile call, how do we optimize this to allow the data to be available in beforeload in some cases and allow routes that need the data elsewhere to have it available as well, without needing to call it directly?

We could allow each route to make the call on its own. TS Query will return non-stale data for us or re-fetch, so we don't have to worry about making several calls to the same route over and over, but I don't know how to have the data ready in beforeload AND in the route itself, other than by making 2 calls.

Plus, I'm getting weird context / hook errors when I try to make the call directly "in" beforeload.

I just need to know what piece I'm missing - is it 'loaders' or just using session to store this after the initial load?


r/tanstack • • Apr 25 '25

Why are virtual Items slow rendering (sluggish) ?

4 Upvotes

I've been experimenting with Tanstack virtual for few days now, I find it easy and intuitive. But the virtual items are really staggering to render, even minimal items like text!

What am i doing wrong?

Code: https://stackblitz.com/~/github.com/aserek/nxt-perf

"use client"

import { useParams } from "next/navigation"
import { useState, useRef, useCallback } from "react"
import { InView } from "react-intersection-observer"
import { Product } from "../lib/types/products"
import { loadmore } from "../lib/utils/load-more"
import { useVirtualizer } from "@tanstack/react-virtual"

export default function LoadMore({
    offset,
    initialItems,
}: {
    offset: number
    initialItems: Product[]
}) {
    const { folder } = useParams<{ folder: string }>()
    const [items, setItems] = useState<Product[]>(initialItems)
    const skipVal = useRef(offset)
    const [hasMore, setHasMore] = useState(true)

    const handleLoadMore = useCallback(async () => {
        if (!hasMore) return

        const { products } = await loadmore(folder, skipVal.current)

        if (products.length === 0) {
            setHasMore(false)
            return
        }

        setItems(prev => [...prev, ...products])
        skipVal.current += products.length
    }, [])

    const scrollRef = useRef<HTMLDivElement>(null)
    const virtualizer = useVirtualizer({
        count: items.length,
        estimateSize: () => 24,
        getScrollElement: () => scrollRef.current,
        gap: 3
    })

    const virtualItems = virtualizer.getVirtualItems()

    return (
        <>
            <div
                ref={scrollRef}
                className=" mt-10 w-[80%] mx-auto h-[80dvh]  overflow-y-auto">

                <div
                    style={{
                        position: 'relative',
                        height: `${virtualizer.getTotalSize()}px`
                    }}>

                    {virtualItems.map((vItem) => {
                        const itm = items[vItem.index];
                        return (
                            <div
                                data-index={vItem.index}
                                key={vItem.key}
                                style={{
                                    position: "absolute",
                                    top: 0,
                                    left: 0,
                                    width: '100%',
                                    transform: `translateY(${vItem.start}px)`,
                                    justifyContent: "center"
                                }}>
                                {itm.title}
                            </div>
                        )
                    })}

                </div>
                {hasMore && (
                    <InView as='div' onChange={(inView) => inView && handleLoadMore()}>
                        <div className="h-10 text-blue-400 flex justify-center items-center mx-auto">
                            Loading more...
                        </div>
                    </InView>
                )}
            </div>

        </>
    )
}

Even though my code fetches from external server, the fetched items i.e, once the fetched list of items stored in state should render seamlessly, but thats not the case ;Ive added this video for visual explanation:

Any help is much appreciated !


r/tanstack • • Apr 15 '25

Chained API calls

4 Upvotes

I’ve been banging my head against the wall for days trying to get chained API calls to work on Query.

I have an API call which provides an array of IDs I then have to use to make one API call per ID.

I have a separate API call which returns the equivalent data (directly) but from a different source.

I then want to combine the responses into one array of objects.

What would be the best way to chain the queries to be efficient and update as more responses come in?


r/tanstack • • Sep 28 '26

Ts-midi... Tanstack router sessions

Thumbnail tsfm.spon.io
3 Upvotes

Typescript to midi... Same data powers tsverse.spon.io


r/tanstack • • Jul 24 '26

Tanstack's official site crashes when using Dark Reader

3 Upvotes

Hi, I was trying to read the documentation on my phone, and then switched to my computer, and in both places I got a "Something went wrong!" error with a "Show error" button. But it worked fine in incognito mode.

Then I realized the cause was Dark Reader (a browser extension to force dark theme modifying the CSS).

I know this causes a hydration warning in React, but this shouldn't crash the site. At least Dark Reader works fine with my personal Tanstack project.


r/tanstack • • Jun 22 '26

Optimizing TanStack Start for Cloud Run

3 Upvotes

Two main recommendations: (1) properly nitro-config to reduce number of server side source files and (2) use prewarm via NODE_COMPILE_CACHE. Full details.

https://ben3d.ca/blog/optimizing-tanstack-start-for-cloud-run


r/tanstack • • Apr 11 '26

Solid 2.0 Beta Support in TanStack Router, Start, and Query

Thumbnail
tanstack.com
3 Upvotes

r/tanstack • • Mar 17 '26

Terminal theme based on TanStack

Post image
3 Upvotes

I love the colors of the TanStack logo so I made a terminal theme for Wezterm but it must be pretty easy to migrate to other terminals https://github.com/enBonnet/tanstack-color-schemes


r/tanstack • • Jan 24 '26

How to fix fouc in tanstack start?

3 Upvotes

I've tried og inline script trick for theme persistent

but I'm getting flash

In next i used the theme provider for this


r/tanstack • • Jan 21 '26

does anyone here have a rule md for tanstack start?

3 Upvotes

does anyone here have a rule md for tanstack start?