SEO in TanStack Router
Hey there, can anyone help me with the right approach for SEO in TanStack Router, please?
I mostly want SPA for my app, but then there are some parts like the public course page (https://learn.self-host.tech/courses/83311579-014d-4b50-ab58-d8e78d576426
-
https://github.com/catalinpit/learn-platform/blob/main/client/src/routes/courses/%24courseId.tsx) that I want to appear in search engines.
How should I go about this? Or should I "upgrade" to TanStack Start?35 Replies
other-emerald•4w ago
Hey, are you familiar with the
head
prop in createFileRoute()
and createRootRoute()
?
https://tanstack.com/router/v1/docs/framework/react/guide/document-head-management
You want to do all your API calls in the loader (such as fetching the image, title and description). Then you can get the loaderData
in your head
params
Document Head Management | TanStack Router React Docs
Document head management is the process of managing the head, title, meta, link, and script tags of a document and TanStack Router provides a robust way to manage the document head for full-stack appl...
other-emerald•4w ago
Open Graph protocol
The Open Graph protocol enables any web page to become a rich object in a social graph.
other-emerald•4w ago
For the
og:url
prop, you can even add query params if your different views are dependent on search params. From what I understand, the url prop's job is to provide a clean, canonical url that search engines should use to identify the page, without any extra query params that might come from all sorts of filters or the likestormy-gold•4w ago
But you still need tanstack start for it right? Otherwise it will still be server as SPA
other-emerald•4w ago
Google crawlers do render components and crawl pages even in a SPA - but I'm not sure what exactly is the threshold between "this is ok to render" and "man, this is too expensive, I give up".
For SEO, beware of any errors from network calls, regardless of whether the app is purely client or server side rendered - for a really long time my production application used
sessionStorage
in server rendered components, and I couldn't find a nice way to handle it properly. I got the classic "window/localStorage/sessionStorage is not defined" that you'll run into in apps with SSR. This results in a 500 status code from the server. But from the user's perspective, there have been zero problems. App is usable exactly as intended. However, the crawler sees the 500 and thinks "damn, that sucks, guess I'll just come back later", and doesn't even index the pagegenetic-orangeOP•4w ago
Thanks for the messages! Waiting to see more opinions to decide
vicious-gold•4w ago
there are a few options
1. SSR
this can be done with start or with just router alone (see https://tanstack.com/router/latest/docs/framework/react/guide/ssr)
you can also choose which routes to SSR, see https://tanstack.com/start/latest/docs/framework/react/selective-ssr
2. prerender
this can be done out of the box with start: https://tanstack.com/start/latest/docs/framework/react/static-prerendering
depends on how static your data is
can be nicely combined with SPA mode: https://tanstack.com/start/latest/docs/framework/react/spa-mode
genetic-orangeOP•4w ago
Thank you! So the best bet would be to use TanStack Start?
vicious-gold•4w ago
Start is Router with SSR and some server addons such as API routes, server functions etc
if you dont need the server addons, router with SSR could work too
genetic-orangeOP•4w ago
Dumb question, but if I have a separate backend, Router with SSR should be enough, right? Or?
vicious-gold•4w ago
not dumb at all
and yes, that's what I meant. if you dont need a "backend" then router should be enough
there are a few niceties in start such as createIsomorphicFn for example that makes you life easier
and you can also just use start without using any of the "backend" things
genetic-orangeOP•4w ago
I'm tempted to pick TanStack Start then. My only worry is the changes that will happen once it goes stable
Sorry to bother you so much, but I can't really wrap my head around doing this while keeping the auth context and all that stuff I had previously in main https://github.com/catalinpit/learn-platform/pull/20/files
vicious-gold•4w ago
there will be changes in the vite configuration, but nothing major really
genetic-orangeOP•4w ago
If I'm not able to solve the above issue, I'll simply move to TSS then
genetic-orange•4w ago
I use TanstackRouter and for the moment
createHtmlPlugin
for Vite to inject some tile, description and image. My SPA should only be able to look nice when links are shared within socials like WhatsApp messages or the og:image should be visible when a link is shared via Facebook or anything else.
I tried to move my Router to <HeadContent/>
but this does not seem to work - when I share now links the infos are not available.
Using both, <HeadContent/>
and createHtmlPlugin
results in duplication of Head data.
Is only Start possible to make this work? Would the SPA mode make it still possible to have the head section filled with data?vicious-gold•4w ago
you can only use head content really if you render the whole html with react and do full document hydration
genetic-orange•4w ago
Thanks for your answer - does this mean Start is the answer? At least I am not awar how to do full document hydration with Tanstack Router alone?
vicious-gold•4w ago
did you have a look at https://tanstack.com/router/latest/docs/framework/react/guide/ssr ? you need SSR for this
SSR | TanStack Router React Docs
[!WARNING] While every effort has been made to separate these APIs from changes to Tanstack Start, there are underlying shared implementations internally. Therefore these can be subject to change and...
vicious-gold•4w ago
but not necessarily start
maybe it's possible without SSR even
genetic-orange•4w ago
Ok this would mean I would need a server proxy and serve my SPA similar to how Prerender.io would work
that would be my goal - I simply just want that the initial page render includes the HTML head correctly that shared links getting the bare necessary data to look nice being shared
vicious-gold•4w ago
sounds like prerendering yes. have a look at static prerenderig and spa mode in start
both combined should do what you need
genetic-orange•4w ago
is there a migration doc out there for users of Router moving to Start? I didnt find it last time I looked for it. This is my current config
I guess moving to Start first I have to adjust my file structure for it?
I only found the one for NextJS
vicious-gold•4w ago
we don't have that yet. you could try this and skip the parts you already did
https://tanstack.com/start/latest/docs/framework/react/build-from-scratch
Build a Project from Scratch | TanStack Start React Docs
[!NOTE] If you chose to quick start with an example or cloned project, you can skip this guide and move on to the guide. So you want to build a TanStack Start project from scratch? This guide will hel...
vicious-gold•4w ago
file structure does not need to be changed, you just need to expose router creation in a separate file
genetic-orange•4w ago
where does the config of quoteStyle and generatedRouteTree goes? Do I keep the tanstackRouter config just inside the vite config beside the Start config?
vicious-gold•4w ago
inside
tsr
of the start vite plugingenetic-orange•4w ago
Ok thanks I will give it a try
I got one more question about this topic: as all my routes are behind authentication I want to only open one very specific route to be SSR rendered. The initial and shared SEO related things can be within ENV variables - only this one specific route should be sending fetched data from the server to the client.
Is that a perfect example for selective SSR? Would
defautlSsr:false
in the router config and only one one specific route ssr: true
work for this? Would that work with the Vercel plugin of TSS?genetic-orangeOP•4w ago
I'm writing one as I'm doing the migration right now
vicious-gold•4w ago
would love to have that in the start docs!
did you have a look at the selective SSR docs?
genetic-orangeOP•4w ago
Will let you know when it’s done. If you like it, I can add it
genetic-orange•3w ago
Yes I read the docs but still I am not sure if this means all SSR:false routes are static HTML/JS/CSS? I only have the need of SSR one path with user generated public exercises
/exercises-db/$exerciseId
- prerendering would not cut it as its dynamic user generated content. I delivered the feature for now without og:image
from the user generated content but will try selective SSR.vicious-gold•3w ago
all SSR:false routes are static HTML/JS/CSSno. you would need to prerender them
vicious-gold•3w ago
Static Prerendering | TanStack Start React Docs
Static prerendering is the process of generating static HTML files for your application. This can be useful for either improving the performance of your application, as it allows you to serve pre-rend...
genetic-orange•3w ago
thanks I hope I find some time soon to give it a shot
genetic-orangeOP•3w ago
I'm not sure if anything from here is helpful for the docs, but here's the draft 🙏 https://catalins.tech/p/c0a56185-2dc7-4ca9-bbed-ed42540cd23c/
Catalin's Tech
Migrating to TanStack Start
A while ago, I decided to break away from full-stack React frameworks and use a client-server architecture. That is, separate the backend and the frontend, each being a standalone app.
So, I picked the following stack:
* Backend: Hono + Bun + PostgreSQL + Zod + Prisma + TypeScript + Better Auth
* Frontend: React + Vite + TypeScript + TanStack