-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Support rewrite request (Similarly to redirect) #7562
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
base: main
Are you sure you want to change the base?
Conversation
🦋 Changeset detectedLatest commit: d125553 The changes in this PR will be included in the next version bump. This PR includes changesets to release 4 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
@@ -220,6 +221,19 @@ export function createRequestEvent( | |||
return new RedirectMessage(); | |||
}, | |||
|
|||
rewrite: (url: string) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Incidentally, I'd also like us to support location objects for easy parameter changing.
@@ -201,6 +202,12 @@ export interface RequestEventCommon<PLATFORM = QwikCityPlatform> | |||
*/ | |||
readonly redirect: (statusCode: RedirectCode, url: string) => RedirectMessage; | |||
|
|||
/** | |||
* URL to rewrite to. When called, the response will immediately end with the correct rewrite url. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The response should stay active, no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I initially taken the phrasing from redirect - I'm still figuring things out, I'll rephrase it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
@wmertens At the moment I managed to render a white screen 😅, at least without errors.
I'm not yet sure where exactly the rewrite can be handled properly. Do you have ideas? |
@omerman when you get a rewrite request, you need to restart processing, so you should basically call the handler again, skipping any initialization tasks, and making sure it can't do an infinite loop (e.g. only allow like 5 redirects, that should be plenty) |
So far I hopefully managed to understand some of the flow: we call runQwikCity with a serverRequest event that in dev-time we generate and in prod we get it from all the possible integrations. I was thinking the key part is in the runQwikCity implementation:
by re-run the flow, do you mean I should support a way for the responsePromise to wait for another requestEv to be created( |
@omerman so the http request object itself cannot be recreated, and should be retained. Ideally the whole RequestEvent object is retained, the less work the better. After the rewrite, the route modules have to be regenerated and the request handling has to happen again. |
Do you mean something like this, e.g passing this function to be used somewhere deeper as part of the process, and if rewrite occours rerun the output's built routeHandlers and return the final response? Am I getting close 😅 ? ![]() By regenerate the route modules you meant building the routeHandlers again, right? |
Yes something like that. Also, very important to add e2e tests. See /e2e |
@wmertens It works well now. I will fix up my code making it more readable and better, and will write e2e tests as you asked. |
c7e8332
to
4ac925a
Compare
const rewriteUrl = typeof _rewriteUrl === 'string' ? _rewriteUrl : _rewriteUrl.toString(); | ||
const fixedURL = rewriteUrl.replace(/([^:])\/{2,}/g, '$1/'); | ||
if (rewriteUrl !== fixedURL) { | ||
console.warn(`Rewrite URL ${rewriteUrl} is invalid, fixing to ${fixedURL}`); | ||
} | ||
url.pathname = fixedURL; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// TODO - handle rewrite to urls with search params
// This is not accurate, because the url might have search params
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm. Ok, I can see rewriting to a string be like a shortcut that passes on search params, and then passing a URL object should not do anything
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I made the API as flexible as possible. Let me know if you think it should be different.
Awesome, a day well spent 😊 |
@@ -227,10 +228,27 @@ export function ssrDevMiddleware(ctx: BuildContext, server: ViteDevServer) { | |||
await server.ssrLoadModule('@qwik-serializer'); | |||
const qwikSerializer = { _deserializeData, _serializeData, _verifySerializable }; | |||
|
|||
const applyRewrite: ApplyRewriteInternal = async (url: URL) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TODO - not sure if this is the best name for this function.
it doesnt actually apply the rewrite itself.
Open to suggestions
This comment was marked as resolved.
This comment was marked as resolved.
@wmertens Ready to go. works both in dev and prod environments. Edit: Let me know if you think something is missing or should be changed. |
8454774
to
1ded727
Compare
@wmertens Sorry to bug you yet again, I'm reverting this PR back to a draft because I tried to link it to my work in progress of converting a full website to qwik, and I get an issue with routeLoaders.
I'm guessing its because of the limitation of having route loaders re-export in routes or something like that. As usual, I'll look into it in depth soon, but if you have any insights that might help Im all ears :) |
@omerman awesome work 🚀 I'm guessing that executing the routeloaders got skipped somewhere. I'm not quite sure if we can keep the results of the previous run but I'm inclined to let that happen for efficiency reasons. |
@wmertens Thank you 🙏 hope I'll crack the remaining issue as well. ![]() It would seem that once performing a client navigation, we execute the head code again, which makes perfect sense. I did manage to make it work by doing this: I will try to get more clues as to why in this specific case it goes down like this. |
@wmertens I've fixed all the issues. it works perfectly now. the flow is fully operational 🎉 |
applyRewrite: ApplyRewriteInternal, | ||
resolve: (value: any) => void | ||
) { | ||
async function _runNext( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@wmertens If you have any suggestions as to how to make this function clearer, I'm all ears. It became more complex after introduced with the rewrite handling.
bd87eda
to
dab6f20
Compare
@wmertens I fixed and improved the code per your notes, thank you 🙏 Aside both comments I did as instructed :) |
What is it?
Feature / enhancement
Description
This PR adds functionality to support URL rewrites.
At the moment, a user can perform a redirect, which will re-route the request entirely, modifying the url the user sees.
This feature will introduce a new method,
rewrite
, to the event, alongside the already existingredirect
.rewrite
will make an internal redirect, keeping the url of the request intact.This change addresses qwik-evolution discussion 237 by giving developers explicit control over routing behavior while maintaining SEO best practices.
Checklist
pnpm change