Run start index.mjs on subpath
I have an existing express app and i want to mount the tanstack/start index.mjs on a subroute of that app.
Even when setting a basepath in the router or a baseURL in app.config.ts the nitro server also responds on http://localhost:3000. The routes are correctly only available on http://localhost:3000/hub but as long as it registeres on / i can't run my existing app next to it. How can i configure tanstack start accordingly?
29 Replies
like-goldâĒ7mo ago
you probably need to proxy from the express app to the start app?
since only one server can bind to a single port
deep-jadeOPâĒ7mo ago
Yes that would also work ð I got it experimentally working by using the "node" instead of the "node-server" preset. With "node-server" and your suggestion we would have to run a separate node server and that would cause more devops/monitoring work in production. With "node" preset, nitro exposes a handler which we can register into the existing express app like this:
deep-jadeOPâĒ7mo ago
Nitro logs that this is experimental. Do you see any issues with this approach from the tanstack side?
https://nitro.build/deploy/runtimes/node#handler-advanced
Node.js - Nitro
Run Nitro apps with Node.js runtime.
like-goldâĒ7mo ago
no, that's a good solution!
deep-jadeOPâĒ7mo ago
Wonderful thank you ð
I am running into some issues with this now. I have tried a lot of different configs but I am no longer sure how to resolve this properly. If you have any suggestions on the top of your head that would be appreciated. Otherwise I will continue to play around, I am fairly sure that I can figure this out with enough time investment.
I am using "node" preset and have
basepath: "/hub",
in router.tsx
In my express app the resulting index.mjs is included like this:
My issue is that nitro.mjs tries to preload like this:
preloads: ["/_build/assets/client-CKkrWiz9.js", "/_build/assets/client-ikYd-yxj.js"]`
resulting in this request which results in a 404: http://localhost:3000/_build/assets/client-CKkrWiz9.js
I can modify the path that is used in preloads by adding to the app.config.ts
But so far no luck in configuring this correctly ðlike-goldâĒ7mo ago
what happens if you configure it like this?
deep-jadeOPâĒ7mo ago
if i do that it just changes the subfolder structure so not helpful at all.
.output/public/_build/assets --> .output/public/hub/assets
I kinda hoped that app.config
server.baseURL: "/hub"
would do the trick but it does not appear to change how the chunks are preloaded.
i am still trying to understand how server.baseURL relates to router.tsx basepath. maybe a combination of the 2 will do the trick
ok so even if i set baseURL: "/TESTING1asdf",
the first reuqest request will be http://localhost:3000/_build/assets/client-gJCxyI7W.js but then it retries with http://localhost:3000/TESTING1asdf/_build/assets/client-gJCxyI7W.js
Right now both fail but that might be due to my server setup. i think i need to serve the public directory separately.
While the request for my app.css for example is http://localhost:3000/TESTING1asdf/_build/assets/app-TBb7edEX.css right awaylike-goldâĒ7mo ago
if you can provide a minimal reproducer as a git repo I can have a look later
deep-jadeOPâĒ7mo ago
i will try some more things as the setup is pretty overwhelming. But it might be best anyway to start with a basic starter and try to start that at a subpath ð
like-goldâĒ7mo ago
yes that's best
it's absolutely possible we need to honor the base path inside of start somewhere
not a common thing so might have gone unnoticed
deep-jadeOPâĒ7mo ago
I created a repo with some testing notes and instructions: https://github.com/flodaniel/tss-subdirectory-hosting-node
i also found a very dirty workaround
GitHub
GitHub - flodaniel/tss-subdirectory-hosting-node
Contribute to flodaniel/tss-subdirectory-hosting-node development by creating an account on GitHub.
deep-jadeOPâĒ7mo ago
The workaround is not something i would be comfortable with putting into production so I am looking forward to your thoughts and I will continue to work on this on monday most likely ð
like-goldâĒ7mo ago
it looks like this nitro integration does not serve static files. i asked nitro for clarification
deep-jadeOPâĒ7mo ago
Thank you! I hope this is something that could be added or we can find a cleaner workaround that is stable in production ð
@Manuel Schiller did you create a github issue somewhere in the nitro repo or did you reach out to them directly? ð
like-goldâĒ7mo ago
directly
no response yet
deep-jadeOPâĒ7mo ago
okidoki and thanks for the update ð
Did you hear back from them? We are inching closer to wanting to release TSS to production and this is one of the biggest last pieces for us right now ð
like-goldâĒ7mo ago
unfortunately nope
ok got the reply that serveStatic is default on for that preset. might want to check if this is changed somewhere (e.g. vinxi)?
deep-jadeOPâĒ7mo ago
i can check that yes ð
Is that the actual problem though because without any basepath set (so just hosting it a
/
) works?
i think it is more of a path usage issue (so that the basepath in createTanStackRouter is not used correctly)?
Do you know why i have to set app.config.ts server.baseURL as well as router.tsx createTanstackRouter basepath or what the difference is between the two?deep-jadeOPâĒ7mo ago
so this is how my folder structure looks like when deployed but the index.mjs looks for the preload chunks in the frontend folder which is
/
for it
deep-jadeOPâĒ7mo ago
is it possible that i can't have TSR configured to run on subpath /hub but then also have the static assets be served from /hub?
deep-jadeOPâĒ7mo ago
i am just thinking loud here now ð
with server.baseUrl it attempts to get the chunks first from / and then from /hub. It does not do this with no server.baseURL is set.
However on /hub (http://localhost:3001/hub/_build/assets/client-DkXsmdUL.js) TSR responds instead of actually doing a static serve of the asset.
I could change server.baseURL but I think then i would have to serve the app twice, once for static assets and once normally ð

deep-jadeOPâĒ7mo ago
I am looking at react-start-config which uses the clientBase to construct the URL for preload but ignores the baseURL set from server.baseURL
https://github.com/TanStack/router/blob/0cf5e3e84695878578c2ed17d7fd2fdec4a04433/packages/react-start-config/src/index.ts#L589
GitHub
router/packages/react-start-config/src/index.ts at 0cf5e3e846958785...
ðĪ Fully typesafe Router for React (and friends) w/ built-in caching, 1st class search-param APIs, client-side cache integration and isomorphic rendering. - TanStack/router
deep-jadeOPâĒ7mo ago
I lack some overall understanding but do you think the publicBase, clientBase, apiBase, serverBase should use the server.baseURL as a prefix?
Currently not even sure if this would resolve my issue ð
like-goldâĒ7mo ago
maybe? just try it out ðĪŠ
deep-jadeOPâĒ7mo ago
ok that caused the first requests (screenshot above) to also include the baseUrl but ofc it still results in a 404, as the last request already tries to do that anyway.
https://github.com/nitrojs/nitro/blob/v2/src/presets/node/preset.ts
"node" does not come with
serveStatic:true
. In addition, other deployments had bugfixes to respect baseURL (vercel, cloudflare)
I need to dig deeper what serveStatic does and if useNitroApp
or toNodeListener
(from h3) respect the baseURl optiondeep-jadeOPâĒ7mo ago
Ok i got it working by enabling serveStatic and setting baseURL only in production, otherwise local development gets messed up. So the solution was much simpler.
I now serve the nitro app like this:
Unfortunately there are still 2 initially failed requests. Looks like TSR has some kind of fallback already and then tries again with the baseURL attached or sth like that.

deep-jadeOPâĒ7mo ago
well
actually does not work, i have to set it directly on the server object, which makes the build .output work but breaks the local development server..
Only way i found to make this adaptable is
baseURL: process.env.BASE_URL,
. So overall the out-of-the-box support for "node" preset on a subpath could be improved, but ofc this is a edge case ð
also the baseURL is not applied to head links, which it definitely should :/like-goldâĒ7mo ago
can you create a PR for this?
deep-jadeOPâĒ7mo ago
I can try ð
In a test like this where can i add options like in the createTanstackRouter method?
Also would you say the baseURL should be added based on the nitro server prop or the TSR basepath?