T
TanStack2d ago
manual-pink

Why do I get a flash of unstyled content (FOUC) when SSR is enabled in TanStack Start?

Hey everyone! I migrated a project from Next TanStack Start and I noticed something confusing with SSR. • When I set ssr: false for a route/component, the page loads normally and fully styled, even on refresh. (expected) • But when ssr: true, the page first loads without any styles (unstyled HTML), and then after hydration the styles appear. It feels like a flash of unstyled content. I always thought SSR will send fully styled HTML from the server, so the page appears complete immediately. Is this expected behavior with TanStack Start? Probably a dumb question, anyway what’s the recommended way to properly include/extract CSS during SSR to avoid this flicker?
5 Replies
ambitious-aqua
ambitious-aqua2d ago
how are you adding the css ? if you're loading the css to late (that is to say after the loading of the js modules), it's gonna cause a FOUC
manual-pink
manual-pinkOP2d ago
import { Outlet, createRootRoute, HeadContent, Scripts, } from "@tanstack/react-router" import "./globals.css" import { QueryClient, QueryClientProvider } from '@tanstack/react-query' import { lazy, Suspense, useState } from 'react' import { Toaster } from "sonner" import { DestinationsProvider } from "@/contexts/DestinationsContext" import { ReactQueryDevtools } from "@tanstack/react-query-devtools" above is my __root.tsx importing style is in the second line ?? Or is it suppose to be somewhere even lower in the component three ?
ambitious-aqua
ambitious-aqua2d ago
that's you're issue you're importing the styles via js on the client side what you want is macro-import the url of the css file like this
import appCss from "./global.css?url" // notice ?url

export const Route = createRootRoute({
head: () => ({
...
links: [{ rel: 'stylesheet', href: appCss }]
}),
...
})
import appCss from "./global.css?url" // notice ?url

export const Route = createRootRoute({
head: () => ({
...
links: [{ rel: 'stylesheet', href: appCss }]
}),
...
})
@Nakumbo ?url is like a macro it converts it into a static asset url at bundle time which lets it be sent during ssr
deep-jade
deep-jade2d ago
as far as I know, this only happens in dev mode, while in prod, after build, the assets are served via the manifest and the CSS should be extracted as well. i.e those are added to head script regardless
manual-pink
manual-pinkOP2d ago
Fix it! thank you for education me on this

Did you find this page helpful?