router icon indicating copy to clipboard operation
router copied to clipboard

Serving TSS on basepath (e.g. /hub) does not correctly serve assets

Open flodaniel opened this issue 7 months ago • 4 comments

Which project does this relate to?

Start

Describe the bug

A defined basepath is not respected correctly in TSS. A basepath in TSS can be set in theory by:

  • setting basepath: '/hub' in createTanStackRouter()
  • in app.config.ts setting server.preset to node (to be able to just serve it with an existing express app. "node" results in just a handler being generated by nitro)
  • in app.config.ts setting server.baseURL to /hub

However when I do that any assets that are served from the public folder do not get the basepath appended correctly.

Example 1 the favicon-16x16.png fails to load in production but it works when being run with vinxi dev:

export const Route = createRootRouteWithContext<RouterContext>()({
    head: () => {
        return {
            links: [
                {
                    rel: "icon",
                    type: "image/png",
                    sizes: "16x16",
                    href: `favicon-16x16.png`,
                },
            ],
        };
    },
    component: RootComponent,
});

Example 2 the image/default-1.webp fails to load in production but it works when being run with vinxi dev:

 <img src={`/img/default-1.webp`} />

Your Example Website or App

https://github.com/flodaniel/tss-subdirectory-hosting-node

Steps to Reproduce the Bug or Issue

  1. Use the provided repository to build a minimal TSS app with the props and serve it at the subpath with the express app (also in the repo)

Expected behavior

Setting the basepath as described should serve all assets correctly from the basepath.

Screenshots or Videos

No response

Platform

  • OS: any
  • Browser: Brave
  • Version: 1.114.30

Additional context

Previous discord discussions:

  • https://discord.com/channels/719702312431386674/1351676051964690452/1351676051964690452
  • https://discord.com/channels/719702312431386674/1339584143549403186/1347216553091010572

flodaniel avatar Apr 03 '25 08:04 flodaniel

Going to bump this because we are running into the same issue.

We are running multiple apps on company.com/app-a, company.com/app-b and then we have company.com/tanstack-app and so none of the assets or chunks are being loaded no matter what baseURL we set or try to use. Work arounds mentioned in the discord discussions do not work for us.

Although the base html does load and the server is serving correctly when visiting company.com/tanstack-app/page/one, the assets them selves do not.

// https://company.com/tanstack-app logs
GET https://company.com/_build/assets/index-CvefQra0.css net::ERR_ABORTED 404 (Not Found)
GET https://company.com/_build/assets/qr-JTUVpYoO.png 404 (Not Found)
GET https://company.com/_build/assets/omni-BDVQEBec.png 404 (Not Found)
GET https://company.com/_build/assets/client-D6AqD1NZ.js net::ERR_ABORTED 404 (Not Found)
GET https://company.com/_build/assets/client-Bb0BiWZS.js net::ERR_ABORTED 404 (Not Found)

For now looks like our best bet would be to host the app on a different domain for now and then revert back to when baseURL does work correctly.

ArthurTimofey avatar Apr 09 '25 09:04 ArthurTimofey

@flodaniel @ArthurTimofey did you try these? there is a public base path that can be set.

https://github.com/TanStack/router/discussions/3032 https://github.com/TanStack/router/issues/3080

aarjithn avatar Apr 20 '25 00:04 aarjithn

None of those solutions worked for me. regardless of what I do assets are resolved from root

sfc-gh-alisowski avatar Jun 12 '25 21:06 sfc-gh-alisowski

The same issue, I remember in the original vite+react it only required one configuration.

rxliuli avatar Jun 14 '25 03:06 rxliuli

@flodaniel were you able to solve this?

markstos avatar Sep 04 '25 20:09 markstos

We currently have a solution with version 1.13X: in vite.config.ts

import svgr from "vite-plugin-svgr";
import tsConfigPaths from "vite-tsconfig-paths";

import { tanstackStart } from "@tanstack/react-start/plugin/vite";
import viteReact from "@vitejs/plugin-react";
import { defineConfig } from "vite";

export default defineConfig({
    base: process.env.NITRO_BASE_URL, // is undefined on develop, "/hub" on production
    plugins: [
        tsConfigPaths({
            projects: ["./tsconfig.json"],
        }),
        tanstackStart({
            customViteReactPlugin: true,
            target: "node",
            tsr: {
                srcDirectory: "./src",
            },
        }),
        viteReact(),
        svgr({
            include: "**/*.svg?react",
        }),
    ],
});

in nitro.config.ts

export default defineNitroConfig({
    serveStatic: true,
});

and in router.tsx we set basepath: import.meta.env.VITE_BASEPATH, which is always /hub

flodaniel avatar Sep 05 '25 13:09 flodaniel