Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: v7pre - Can't use vite preview with SPA + basename + prerender #12083

Open
daniharo opened this issue Oct 6, 2024 · 6 comments
Open
Assignees
Labels

Comments

@daniharo
Copy link

daniharo commented Oct 6, 2024

What version of React Router are you using?

7.0.0-pre.0

Steps to Reproduce

  • Enable SPA mode (ssr: false)
  • Set the basename to /chat/
  • Enable prerender.
  • Build the app with npm run build
  • Run vite preview.

Minimal reproduction (run npm run build + npm run preview on it):
https://stackblitz.com/edit/react-router-v7-basename-prerender-preview?file=vite.config.ts

Expected Behavior

When opening http://localhost:4173/chat/, the preview server responds with /build/client/chat/index.html and the root route is rendered.

Actual Behavior

There is a 404 error response.
When opening http://localhost:4173/chat/, vite tries to respond with the file /build/client/index.html which doesn't exist (the prerendered route is in /build/client/chat/index.html), so there is a 404 response.

@daniharo daniharo added the bug label Oct 6, 2024
@daniharo
Copy link
Author

daniharo commented Oct 6, 2024

For now I've solved it adding this plugin to vite config, but it doesn't seem very clean

    {
      name: "configure-preview-server",
      configurePreviewServer(server) {
        return () => {
          server.middlewares.use((req, res, next) => {
            if (req.url === "/index.html") {
              req.url = `${req.originalUrl?.slice(0, -1)}${req.url}`;
            }
            next();
          });
        };
      }
    }

@brophdawg11
Copy link
Contributor

I'm not quite sure what to do here - with basename: '/chat/', React Router has to generate the file inside of a chat/ directory so it can be deployed to a static file CDN and served at chat/.

But then when Vite's base is also set, Vite strips that from any incoming request during vite preview it seems and hence the 404. You need to go to /chat/chat to get Vite to serve the file, and then that fails to hydrate because the basename doesn't match.

I think vite preview works as expected if you just use basename and skip base - is that an option is your setup?

@daniharo
Copy link
Author

It does work but scripts will have href="/assets/...".
I need the href for scripts to begin with /chat (such as href="/chat/assets/entry.client-BmgBuKBB.js"), not only the routes.
AFAIK the only way to do that is setting base: '/chat/'.

@brophdawg11
Copy link
Contributor

I think we have a check somewhere that basename has to start with base so in theory we could strip any base from basename when we generate the files, but that would mean you can no longer run your app via a simple HTTP server like npx http-server build/client because they wouldn't live in /chat anymore and http-server doesn't know to add /chat since that's a vite preview only thing...

I'll see if I can find some time to play around with these combinations and see if there's a good solution that works for all cases.

@brophdawg11 brophdawg11 self-assigned this Oct 11, 2024
@mayank99
Copy link

It's worth mentioning that Vite allows using base: "./" which I've found works quite well for static/prerendered sites. All assets are looked up relatively, avoiding any issues with deeply-nested absolute paths.

@mayank99
Copy link

mayank99 commented Oct 22, 2024

I'm not quite sure what to do here - with basename: '/chat/', React Router has to generate the file inside of a chat/ directory so it can be deployed to a static file CDN and served at chat/.

@brophdawg11 I think this assumption might be incorrect? The base name is often used for deploying to a sub-directory that already exists. This is the case with GitHub Pages, where you are basically forced to use a sub-path, even if you deploy to the root.

Currently, using reactRouter({ basename: "/chat/", prerender: true, ssr: false }) will generate two directories: build/client/chat/ and build/client/assets/. This makes it very difficult to deploy. It would be easier if the assets/ directory was inside chat/.

Maybe unrelated: I also noticed a strange issue after deploying the build/client/ directory as-is. Prerendered pages work when visiting the URLs directly, but don't work at all navigating on the client using <Link>.

@brophdawg11 brophdawg11 added the v7 label Oct 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants