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

redirect to absolute URL not working #1103

Closed
bagr001 opened this issue Aug 31, 2023 · 14 comments
Closed

redirect to absolute URL not working #1103

bagr001 opened this issue Aug 31, 2023 · 14 comments
Labels

Comments

@bagr001
Copy link

bagr001 commented Aug 31, 2023

Description

Hi, I found a bug while migrating to new redirect() from 'vite-plugin-ssr/abort'

The signature promises support of relative and absolute urls, but redirection to absolute url crashes the app.

declare function redirect(url: `/${string}` | `https://${string}` | `http://${string}`): AbortRedirect;

Here is the error stack:

23:03:41 [vite-plugin-ssr][request(1)] throw redirect(302) intercepted while rendering /redirect
Error: [vite-plugin-ssr@0.4.140][Bug] You stumbled upon a bug in vite-plugin-ssr's source code. Go to https://github.com/brillout/vite-plugin-ssr/issues/new and copy-paste this error; a maintainer will fix the bug (usually under 24 hours).
    at assertNoInfiniteHttpRedirect (file:///~app/node_modules/vite-plugin-ssr/dist/esm/node/runtime/renderPage/createHttpResponseObject/assertNoInfiniteHttpRedirect.js:8:5)
    at createHttpResponseObjectRedirect (file:///~app/node_modules/vite-plugin-ssr/dist/esm/node/runtime/renderPage/createHttpResponseObject.js:38:5)
    at handleAbortError (file:///~app/node_modules/vite-plugin-ssr/dist/esm/node/runtime/renderPage.js:385:30)
    at renderPageAlreadyPrepared (file:///~app/node_modules/vite-plugin-ssr/dist/esm/node/runtime/renderPage.js:141:35)
    at renderPageAndPrepare (file:///~app/node_modules/vite-plugin-ssr/dist/esm/node/runtime/renderPage.js:93:12)
    at file:///~app/node_modules/vite-plugin-ssr/dist/esm/node/plugin/shared/getHttpRequestAsyncStore.js:68:35
    at renderPage (file:///~app/node_modules/vite-plugin-ssr/dist/esm/node/runtime/renderPage.js:46:50)
    at file:///~app/server/index.ts:48:29

I see the problem in assertNoInfiniteHttpRedirect where the check assert(urlSource.startsWith('/')) fails.

Thanks :-)

@brillout
Copy link
Member

I see, I'll fix it tomorrow.

@bagr001
Copy link
Author

bagr001 commented Sep 1, 2023

Thanks!

I just have a question, why is the public API of redirect() limited to 302. What is the benefot of disallowing 301? Can you pls explain?

@brillout
Copy link
Member

brillout commented Sep 1, 2023

Because you're supposed to use static redirections instead: https://vite-plugin-ssr.com/redirects. Dynamic/conditional redirections and 301 are inherently contradictory.

@brillout
Copy link
Member

brillout commented Sep 1, 2023

Fix pre-released as 0.4.140-commit-7343a85.

@brillout
Copy link
Member

brillout commented Sep 1, 2023

Fix pre-released as 0.4.140-commit-7343a85.

Actually, there is a bug about it. Let me fix it.

@brillout
Copy link
Member

brillout commented Sep 1, 2023

Pre-released as 0.4.140-commit-250158a.

@bagr001
Copy link
Author

bagr001 commented Sep 1, 2023

Thanks. I understand, but there are some cases when dynamic 301 redirects are useful. For example, my use case involves always redirecting to the canonical URL for SEO purposes. I always want to maintain a dynamic path and query parameters in a specific order. If a user or bot lands on a page that can be resolved but doesn't match the canonical format, they are permanently redirected to the correct canonical URL. This can't be achieved with static redirections since the route involves a path wildcard and a portion of the path is dynamic.

I really appreciate how the VPS remains open and non-restrictive during development. However, recent changes seem to introduce unnecessary restrictions that limit developers' flexibility :-(

Regardless, thank you for your awesome work! I'll make an effort to advocate for sponsorship within the company.

@brillout
Copy link
Member

brillout commented Sep 1, 2023

Makes sense, I will unlock dynamic 301 redirects: #1104.

recent changes seem to introduce unnecessary restrictions that limit developers' flexibility :-(

Can you elaborate?

@brillout
Copy link
Member

brillout commented Sep 1, 2023

Done: you can now use throw redirect('/some-url', 301). Also added a couple of goodies to config.redirects (see the updated docs in case you're curious).

thank you for your awesome work! I'll make an effort to advocate for sponsorship within the company.

Thanks, I hugely appreciate it. Keep me updated how it goes. Sponsoring makes a big difference for vite-plugin-ssr.

Flexibility being one of vite-plugin-ssr's raison d'etre, rest assured that I care about it. I know some decisions seem to suggest otherwise at first, but the vision is very much always also about increasing flexibility. (Let alone because flexibility degradation potentially means breaking existing apps which is a no-go.) Feel free to be cricital and elaborate about any aspect you believe is degrading.

@bagr001
Copy link
Author

bagr001 commented Sep 1, 2023

Awesome, thanks!

A few things come to my mind when discussing flexibility:

  • The restricted redirect to 301 (which you just resolved in this GitHub issue).
  • The abort render() function restriction on error codes (you added 410 upon my request in this GitHub issue). However, I am curious about why this restriction is necessary. There might be cases where I need to send a general 400 (Bad Request) error, or someone might require a different status code. There are plenty of status codes available here. Why not allow any status code within the range of 4xx or 5xx?
  • Lastly, why is there a warning about using the Vite path.alias customResolver function? (Link: commonConfig.ts) I use it for some low-level optimizations. Does this cause any problems in VPS internals? If not, I'd like to continue using it as long as Vite supports it.

@brillout
Copy link
Member

brillout commented Sep 3, 2023

The plan is to eventually remove the unkown status code warning: users will then be able to use any status code simply by doing throw render(666 as any). The reason I'm keeping the warning is because I'd like to know about and list the most common use cases (covering 99% of the use cases) for TypeScript's IntelliSense. I know it's unconventional but I believe it will eventually lead to a great DX.

As for path.alias, yes vite-plugin-ssr does need to be able to disambiguate between npm packages and path aliases.

I use it for some low-level optimizations

Do you mind elaborating?

@bagr001
Copy link
Author

bagr001 commented Sep 4, 2023

Thanks for the explanation.

Regarding the resolve.alias.customResolver, my use case involves using custom-generated API clients through OpenAPI Generator. We have clients for 10 different services, all of which share a common "runtime" module. This module ends up being included in the final bundle 10 times. I've managed to optimize this by using the customResolver. The outcome is a deduplicated "runtime" module and significantly smaller client bundle.

Here's an example from my vite.config. I'm also using aliasing for preact <-> react compatibility.

resolve: {
    alias: [
        /**
         * Alias # as the project root
         */
        {find: '#', replacement: process.cwd()},
        /**
         * Other library aliases
         */
        {find: 'ttag', replacement: isProd ? 'ttag/dist/mock' : 'ttag'},
        {find: 'react', replacement: 'preact/compat'},
        {find: 'react-dom', replacement: 'preact/compat'},
        /**
         * Replace all openapi clients' runtime with a single one
         */
        {
            find: /^(.*)\/runtime$/,
            replacement: '$&',
            customResolver: function (id, importer) {
                if (importer?.match(/node_modules\/@platform\/(.*)\/dist\/esm/)) { // We know it will match the API clients
                    return './node_modules/@platform/biano-frontend-service-react-api-client/dist/esm/runtime.js';
                }
                if (importer?.match(/node_modules\/@platform\/(.*)\/dist/)) {
                    return './node_modules/@platform/biano-frontend-service-react-api-client/dist/runtime.js';
                }
                if (importer?.match(/node_modules\/@platform\/(.*)\/src/)) {
                    return './node_modules/@platform/biano-frontend-service-react-api-client/src/runtime.ts';
                }
                return id;
            } as ResolveIdHook,
        }
    ]
}

I hope this gives you a rough idea of what it's all about.

@brillout
Copy link
Member

brillout commented Sep 4, 2023

I think it's possible to workaround it. Have a look at virtual modules and resolveId().

Btw. if your company ends up sponsoring then you'll get increased support. I'd also further dig into finding ways to remove the need for vite-plugin-ssr to disambiguate between npm packages and path aliases, so that you can keep using your solution with aliases. (Although, honestly, I think the fact that you're earning money with VPS would be the strongest reason for sponsoring; it just makes sense, let alone to ensure your dependency is well maintained. In my experience, managers care a lot about having happy employees, so that's also an argument since Software Engineers usually appreciate tight-knit companies who can show to be generous towards passionate peers such as open source developers.)

@brillout
Copy link
Member

brillout commented Sep 5, 2023

I'd also further dig into finding ways to remove the need for vite-plugin-ssr to disambiguate between npm packages and path aliases

FYI I did dig into this already: finding alternatives isn't trivial. It may be possible if I invest more time on it.

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

2 participants