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

Support for rewrites #5703

Closed
kyjus25 opened this issue Jul 25, 2022 · 13 comments · Fixed by #11537
Closed

Support for rewrites #5703

kyjus25 opened this issue Jul 25, 2022 · 13 comments · Fixed by #11537
Labels
feature request New feature or request p3-edge-case SvelteKit cannot be used in an uncommon way
Milestone

Comments

@kyjus25
Copy link

kyjus25 commented Jul 25, 2022

Describe the problem

Probably kind of a huge undertaking, but it would be great to have rewrite support in SvelteKit similar to what Next.js can do.

The big hurdle for me comes when trying to convert existing PHP sites to SvelteKit. In PHP we'd have .htaccess to handle rewrites, but JS would require either the framework handling it, or a reverse proxy handling it beforehand (which is not helpful during development).

Static uploads are also something I'd love to be able to perform rewrites for. There's one site in particular I cannot convert because it acts as a monorepo for several other websites that share one common uploads directory separated by domain names.

For instance, when /example.png is accessed, PHP is rewriting it to /uploads/<domain>/images/example.png, which I believe is not possible to do in SvelteKit currently. Vite can change the assets path, but it is not dynamic. hooks.js can redirect, but ideally I would like to abstract the path away from the user so they never see the true source.

Describe the proposed solution

Implement something similar to Next.js' rewrite solution, or the ability to rewrite from handle or load functions as opposed to redirect.

Alternatives considered

Apart from having a reverse proxy in front, I don't believe there is a true solution currently.

The handle function can perform a redirect, but not a rewrite.

Under certain circumstances you could kludge up a [...catchall].svelte to redirect the requests, but also is not rewriting.

Importance

nice to have

Additional Information

No response

@antony
Copy link
Member

antony commented Jul 25, 2022

I think nextjs uses Vercel rewrites - which is also what I use in SvelteKit. I could be wrong though - I guess they have some sort of secondary solution in case you deploy a next app on a non-vercel platform?

I quite like the idea of a rewrite from an endpoint, but I sort of also feel like this is outside of the scope of SvelteKit.

Indicentally with adapter-node or similar you could do this sort of stuff within the node server.

@elliott-with-the-longest-name-on-github elliott-with-the-longest-name-on-github added feature request New feature or request p2-nice-to-have SvelteKit cannot be used by a small number of people, quality of life improvements, etc. p3-edge-case SvelteKit cannot be used in an uncommon way and removed p2-nice-to-have SvelteKit cannot be used by a small number of people, quality of life improvements, etc. labels Jul 27, 2022
@singingwolfboy
Copy link

According to Vercel's docs, you can configure rewrites using a vercel.json file. However, adapter-vercel doesn't appear to do anything with this file, and (possibly) as a result, when I attempted to deploy a SvelteKit project on Vercel with rewrites configured using vercel.json, the config file was ignored and the rewrites were not applied.

Is there some way that adapter-vercel can check for a vercel.json file, and include it in the deployment so that it's possible for a developer to configure rewrites on Vercel?

@antony
Copy link
Member

antony commented Aug 20, 2022

I got caught out by this, and I intended to document it, but I got distracted, so I apologise.

adapter-vercel has no business dealing with rewrites, as these are handled by vercel itself.

Instead, vercel needs to build the rewrites into the vercel filesystem api config generated by the adapter.

Thus, to get rewrites into your deployed app if you are not building on vercel's platform but on your own CI:

vercel build // merges rewrites into fs config
vercel deploy --prebuilt // deploy bundle

@singingwolfboy
Copy link

Thanks for the quick response, @antony, but I'm not sure I understand. You say that running vercel build merges the rewrites into the filesystem config, but from my local testing, that doesn't seem to be the case. I'm not sure how to make this work.

After doing some more research, I found that there is a way to integrate rewrite information into the filesystem api (apparently called the "Build Output API"). There is a transformer for turning the high-level, easy-to-use routing syntax from vercel.json into the low-level routing syntax that the Build Output API supports, and that transformer is available in the @vercel/routing-utils package. adapter-vercel doesn't use this package at all, although there is a comment that refers to it.

Based on this, I believe that the proper way of supporting rewrites for Vercel is to depend on the @vercel/routing-utils package and use the getTransformedRoutes() function to get this configuration into the built output. Does that seem correct to you, or am I missing something?

@antony
Copy link
Member

antony commented Aug 20, 2022

You don't need to. That's what vercel build does for you.

I know it works for a fact as I rely on it in production.

First run vite build, then vercel build, after each step compare the config file (I forget the name) in the .vercel output directory.

@singingwolfboy
Copy link

After fiddling with it a bit more, it appears that my problem was due to a trailing slash! My vercel.json looked like this:

{"rewrites": [{ "source": "/graphql/", "destination": "https://my.upstream.server/graphql/" }]}

When I tried to deploy that, and make a request to /graphql/, it was 308 redirected to /graphql, which then was not rewritten to my upstream server. That's why I thought the rewrite wasn't being applied; because I wasn't expecting the trailing slash to get redirected first!

When I tried changing my vercel.json config to refer to /graphql (without the trailing slash), and changed the request in my app to match, the rewrite worked correctly! I wish there was some way that the system could have made the rewrite override the trailing slash redirect, but regardless, I'm glad that I found a way to make this work.

@francoislg
Copy link

Found this issue out while trying to find a solution to my problem, I wanted to rewrite some sub-part of my SvelteKit site into another sub-domain.

e.g. domain.com/registration-form/:path* => registration.domain.com/:path*

My rewrite rule works well in the vercel.json config, but as soon as CSR kicks in, the "original" path doesn't take into account the rewrite (totally expected, from what I read here).

I managed to work around it by making all my sub-domain pages export const csr = false; thus making them SSR-only, which is a bit terrible, but kind of OK for me right now.

So +1 for this feature! Until then, I hope this comment might help others

@gprieto
Copy link

gprieto commented Mar 1, 2023

Having the same issue as @francoislg. Any workarounds exist better than completely disabling CSR?

@dummdidumm
Copy link
Member

Adding rewrites could potentially also solve one of the i18n use cases of translating the url

@manuganji
Copy link

manuganji commented Aug 20, 2023

I don't think this is an edge case. If someone wants to build something similar to Vercel Platforms in Svelte Kit, how can they do it now?

@lockieluke
Copy link

{
  "rewrites": [{
    "source": "/:path*",
    "has": [{
      "type": "host",
      "value": "api.lockie.dev"
    }],
    "destination": "/api/:path*"
  }]
}

subdomain rewrite doesn't work with SvelteKit

@antony
Copy link
Member

antony commented Dec 11, 2023

subdomain rewrite doesn't work with SvelteKit

Vercel rewrites happen before SvelteKit is executed, so SvelteKit has no bearing on whether this type of rewrite works or not. It sounds like something is wrong with your vercel setup / rewrite. Certain types of rewrite don't work on certain plans with Vercel, as far as I remember.

@jerriclynsjohn
Copy link

@Rich-Harris According to the current implementation of the reroute hook, we can't implement dynamic checks, like checking whether the incoming request is from a custom domain that is registered. We still do not have a hook level rewrite like in Next that can help us build something like Vercel Platforms

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature request New feature or request p3-edge-case SvelteKit cannot be used in an uncommon way
Projects
None yet
Development

Successfully merging a pull request may close this issue.