Skip to content

Commit 52c8edd

Browse files
committed
everything works well.
1 parent f816acc commit 52c8edd

File tree

8 files changed

+47
-8
lines changed

8 files changed

+47
-8
lines changed

packages/docs/src/routes/api/qwik-city-middleware-request-handler/api.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,7 @@
327327
}
328328
],
329329
"kind": "Interface",
330-
"content": "```typescript\nexport interface RequestEventCommon<PLATFORM = QwikCityPlatform> extends RequestEventBase<PLATFORM> \n```\n**Extends:** [RequestEventBase](#requesteventbase)<!-- -->&lt;PLATFORM&gt;\n\n\n<table><thead><tr><th>\n\nProperty\n\n\n</th><th>\n\nModifiers\n\n\n</th><th>\n\nType\n\n\n</th><th>\n\nDescription\n\n\n</th></tr></thead>\n<tbody><tr><td>\n\n[error](#)\n\n\n</td><td>\n\n`readonly`\n\n\n</td><td>\n\n&lt;T = any&gt;(statusCode: ErrorCodes, message: T) =&gt; [ServerError](#servererror)<!-- -->&lt;T&gt;\n\n\n</td><td>\n\nWhen called, the response will immediately end with the given status code. This could be useful to end a response with `404`<!-- -->, and use the 404 handler in the routes directory. See https://developer.mozilla.org/en-US/docs/Web/HTTP/Status for which status code should be used.\n\n\n</td></tr>\n<tr><td>\n\n[exit](#)\n\n\n</td><td>\n\n`readonly`\n\n\n</td><td>\n\n() =&gt; [AbortMessage](#abortmessage)\n\n\n</td><td>\n\n\n</td></tr>\n<tr><td>\n\n[html](#)\n\n\n</td><td>\n\n`readonly`\n\n\n</td><td>\n\n(statusCode: StatusCodes, html: string) =&gt; [AbortMessage](#abortmessage)\n\n\n</td><td>\n\nConvenience method to send an HTML body response. The response will be automatically set the `Content-Type` header to`text/html; charset=utf-8`<!-- -->. An `html()` response can only be called once.\n\n\n</td></tr>\n<tr><td>\n\n[json](#)\n\n\n</td><td>\n\n`readonly`\n\n\n</td><td>\n\n(statusCode: StatusCodes, data: any) =&gt; [AbortMessage](#abortmessage)\n\n\n</td><td>\n\nConvenience method to JSON stringify the data and send it in the response. The response will be automatically set the `Content-Type` header to `application/json; charset=utf-8`<!-- -->. A `json()` response can only be called once.\n\n\n</td></tr>\n<tr><td>\n\n[locale](#)\n\n\n</td><td>\n\n`readonly`\n\n\n</td><td>\n\n(local?: string) =&gt; string\n\n\n</td><td>\n\nWhich locale the content is in.\n\nThe locale value can be retrieved from selected methods using `getLocale()`<!-- -->:\n\n\n</td></tr>\n<tr><td>\n\n[redirect](#)\n\n\n</td><td>\n\n`readonly`\n\n\n</td><td>\n\n(statusCode: RedirectCode, url: string) =&gt; [RedirectMessage](#redirectmessage)\n\n\n</td><td>\n\nURL to redirect to. When called, the response will immediately end with the correct redirect status and headers.\n\nhttps://developer.mozilla.org/en-US/docs/Web/HTTP/Redirections\n\n\n</td></tr>\n<tr><td>\n\n[rewrite](#)\n\n\n</td><td>\n\n`readonly`\n\n\n</td><td>\n\n(url: string \\| URL, keepCurrentSearchParams?: boolean) =&gt; [RewriteMessage](#rewritemessage)\n\n\n</td><td>\n\nURL to rewrite to. When called, the flow will reset to display the given url route.\n\nURL will remain unchanged in the browser history.\n\n\n</td></tr>\n<tr><td>\n\n[send](#)\n\n\n</td><td>\n\n`readonly`\n\n\n</td><td>\n\nSendMethod\n\n\n</td><td>\n\nSend a body response. The `Content-Type` response header is not automatically set when using `send()` and must be set manually. A `send()` response can only be called once.\n\n\n</td></tr>\n<tr><td>\n\n[status](#)\n\n\n</td><td>\n\n`readonly`\n\n\n</td><td>\n\n(statusCode?: StatusCodes) =&gt; number\n\n\n</td><td>\n\nHTTP response status code. Sets the status code when called with an argument. Always returns the status code, so calling `status()` without an argument will can be used to return the current status code.\n\nhttps://developer.mozilla.org/en-US/docs/Web/HTTP/Status\n\n\n</td></tr>\n<tr><td>\n\n[text](#)\n\n\n</td><td>\n\n`readonly`\n\n\n</td><td>\n\n(statusCode: StatusCodes, text: string) =&gt; [AbortMessage](#abortmessage)\n\n\n</td><td>\n\nConvenience method to send an text body response. The response will be automatically set the `Content-Type` header to`text/plain; charset=utf-8`<!-- -->. An `text()` response can only be called once.\n\n\n</td></tr>\n</tbody></table>",
330+
"content": "```typescript\nexport interface RequestEventCommon<PLATFORM = QwikCityPlatform> extends RequestEventBase<PLATFORM> \n```\n**Extends:** [RequestEventBase](#requesteventbase)<!-- -->&lt;PLATFORM&gt;\n\n\n<table><thead><tr><th>\n\nProperty\n\n\n</th><th>\n\nModifiers\n\n\n</th><th>\n\nType\n\n\n</th><th>\n\nDescription\n\n\n</th></tr></thead>\n<tbody><tr><td>\n\n[error](#)\n\n\n</td><td>\n\n`readonly`\n\n\n</td><td>\n\n&lt;T = any&gt;(statusCode: ErrorCodes, message: T) =&gt; [ServerError](#servererror)<!-- -->&lt;T&gt;\n\n\n</td><td>\n\nWhen called, the response will immediately end with the given status code. This could be useful to end a response with `404`<!-- -->, and use the 404 handler in the routes directory. See https://developer.mozilla.org/en-US/docs/Web/HTTP/Status for which status code should be used.\n\n\n</td></tr>\n<tr><td>\n\n[exit](#)\n\n\n</td><td>\n\n`readonly`\n\n\n</td><td>\n\n() =&gt; [AbortMessage](#abortmessage)\n\n\n</td><td>\n\n\n</td></tr>\n<tr><td>\n\n[html](#)\n\n\n</td><td>\n\n`readonly`\n\n\n</td><td>\n\n(statusCode: StatusCodes, html: string) =&gt; [AbortMessage](#abortmessage)\n\n\n</td><td>\n\nConvenience method to send an HTML body response. The response will be automatically set the `Content-Type` header to`text/html; charset=utf-8`<!-- -->. An `html()` response can only be called once.\n\n\n</td></tr>\n<tr><td>\n\n[json](#)\n\n\n</td><td>\n\n`readonly`\n\n\n</td><td>\n\n(statusCode: StatusCodes, data: any) =&gt; [AbortMessage](#abortmessage)\n\n\n</td><td>\n\nConvenience method to JSON stringify the data and send it in the response. The response will be automatically set the `Content-Type` header to `application/json; charset=utf-8`<!-- -->. A `json()` response can only be called once.\n\n\n</td></tr>\n<tr><td>\n\n[locale](#)\n\n\n</td><td>\n\n`readonly`\n\n\n</td><td>\n\n(local?: string) =&gt; string\n\n\n</td><td>\n\nWhich locale the content is in.\n\nThe locale value can be retrieved from selected methods using `getLocale()`<!-- -->:\n\n\n</td></tr>\n<tr><td>\n\n[redirect](#)\n\n\n</td><td>\n\n`readonly`\n\n\n</td><td>\n\n(statusCode: RedirectCode, url: string) =&gt; [RedirectMessage](#redirectmessage)\n\n\n</td><td>\n\nURL to redirect to. When called, the response will immediately end with the correct redirect status and headers.\n\nhttps://developer.mozilla.org/en-US/docs/Web/HTTP/Redirections\n\n\n</td></tr>\n<tr><td>\n\n[rewrite](#)\n\n\n</td><td>\n\n`readonly`\n\n\n</td><td>\n\n(url: string \\| URL) =&gt; [RewriteMessage](#rewritemessage)\n\n\n</td><td>\n\nURL to rewrite to. When called, the flow will reset to display the given url route.\n\nURL will remain unchanged in the browser history.\n\nNote that if the url is a string without a protocol, the rewritten url will inherit the search params from the canonical url.\n\n\n</td></tr>\n<tr><td>\n\n[send](#)\n\n\n</td><td>\n\n`readonly`\n\n\n</td><td>\n\nSendMethod\n\n\n</td><td>\n\nSend a body response. The `Content-Type` response header is not automatically set when using `send()` and must be set manually. A `send()` response can only be called once.\n\n\n</td></tr>\n<tr><td>\n\n[status](#)\n\n\n</td><td>\n\n`readonly`\n\n\n</td><td>\n\n(statusCode?: StatusCodes) =&gt; number\n\n\n</td><td>\n\nHTTP response status code. Sets the status code when called with an argument. Always returns the status code, so calling `status()` without an argument will can be used to return the current status code.\n\nhttps://developer.mozilla.org/en-US/docs/Web/HTTP/Status\n\n\n</td></tr>\n<tr><td>\n\n[text](#)\n\n\n</td><td>\n\n`readonly`\n\n\n</td><td>\n\n(statusCode: StatusCodes, text: string) =&gt; [AbortMessage](#abortmessage)\n\n\n</td><td>\n\nConvenience method to send an text body response. The response will be automatically set the `Content-Type` header to`text/plain; charset=utf-8`<!-- -->. An `text()` response can only be called once.\n\n\n</td></tr>\n</tbody></table>",
331331
"editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik-city/src/middleware/request-handler/types.ts",
332332
"mdFile": "qwik-city.requesteventcommon.md"
333333
},

packages/docs/src/routes/api/qwik-city-middleware-request-handler/index.mdx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1343,14 +1343,16 @@ https://developer.mozilla.org/en-US/docs/Web/HTTP/Redirections
13431343
13441344
</td><td>
13451345
1346-
(url: string \| URL, keepCurrentSearchParams?: boolean) =&gt; [RewriteMessage](#rewritemessage)
1346+
(url: string \| URL) =&gt; [RewriteMessage](#rewritemessage)
13471347
13481348
</td><td>
13491349
13501350
URL to rewrite to. When called, the flow will reset to display the given url route.
13511351
13521352
URL will remain unchanged in the browser history.
13531353
1354+
Note that if the url is a string without a protocol, the rewritten url will inherit the search params from the canonical url.
1355+
13541356
</td></tr>
13551357
<tr><td>
13561358

packages/qwik-city/src/middleware/request-handler/middleware.request-handler.api.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ export interface RequestEventCommon<PLATFORM = QwikCityPlatform> extends Request
136136
readonly locale: (local?: string) => string;
137137
// Warning: (ae-forgotten-export) The symbol "RedirectCode" needs to be exported by the entry point index.d.ts
138138
readonly redirect: (statusCode: RedirectCode, url: string) => RedirectMessage;
139-
readonly rewrite: (url: string | URL, keepCurrentSearchParams?: boolean) => RewriteMessage;
139+
readonly rewrite: (url: string | URL) => RewriteMessage;
140140
// Warning: (ae-forgotten-export) The symbol "SendMethod" needs to be exported by the entry point index.d.ts
141141
readonly send: SendMethod;
142142
// Warning: (ae-forgotten-export) The symbol "StatusCodes" needs to be exported by the entry point index.d.ts

packages/qwik-city/src/middleware/request-handler/request-event.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ export function createRequestEvent(
234234
return new RedirectMessage();
235235
},
236236

237-
rewrite: (_rewriteUrl: string | URL, keepCurrentSearchParams = true) => {
237+
rewrite: (_rewriteUrl: string | URL) => {
238238
check();
239239
let rewriteUrl: URL;
240240
if (typeof _rewriteUrl === 'string') {
@@ -250,6 +250,9 @@ export function createRequestEvent(
250250
rewriteUrl.pathname = fixedPathname;
251251
}
252252

253+
// Assume that if Devs passed a string without a protocol, they want to keep the current search
254+
const keepCurrentSearchParams =
255+
typeof _rewriteUrl === 'string' && !_rewriteUrl.startsWith('http');
253256
if (keepCurrentSearchParams) {
254257
url.searchParams.forEach((value, key) => {
255258
// rewriteUrl values should take precedence over current url values

packages/qwik-city/src/middleware/request-handler/types.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -208,10 +208,12 @@ export interface RequestEventCommon<PLATFORM = QwikCityPlatform>
208208
*
209209
* URL will remain unchanged in the browser history.
210210
*
211+
* Note that if the url is a string without a protocol, the rewritten url will inherit the search
212+
* params from the canonical url.
213+
*
211214
* @param url - The url to rewrite to.
212-
* @param keepCurrentSearchParams - Whether to keep the current search params.
213215
*/
214-
readonly rewrite: (url: string | URL, keepCurrentSearchParams?: boolean) => RewriteMessage;
216+
readonly rewrite: (url: string | URL) => RewriteMessage;
215217

216218
/**
217219
* When called, the response will immediately end with the given status code. This could be useful

starters/apps/qwikcity-test/src/routes/(common)/products/[id]/index.tsx

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,15 @@ export default component$(() => {
8484
T-Shirt (Rewrite to /products/tshirt)
8585
</Link>
8686
</li>
87+
<li>
88+
<Link
89+
href="/qwikcity-test/products/shirt-rewrite-plain_string"
90+
data-test-link="products-shirt-rewrite-plain_string_no_trailing_slash"
91+
>
92+
T-Shirt (Rewrite to /products/tshirt) Also trailing slash should be
93+
added.
94+
</Link>
95+
</li>
8796
<li>
8897
<Link
8998
href="/qwikcity-test/products/hoodie/"
@@ -155,12 +164,11 @@ export const useProductLoader = routeLoader$(
155164
}
156165

157166
if (id === "shirt-rewrite-plain_string") {
158-
// Rewrite, which should have the same effect as redirect but with keep the url
159167
throw rewrite("/qwikcity-test/products/tshirt/");
160168
}
161169

162170
if (id === "shirt-rewrite-url_object") {
163-
// Rewrite, which should have the same effect as redirect but with keep the url
171+
// Rewrite with a URL object.
164172
throw rewrite(new URL("/qwikcity-test/products/tshirt/", url.origin));
165173
}
166174

starters/e2e/qwikcity/page.spec.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,19 @@ function tests() {
134134
h1: "Product: tshirt",
135135
activeHeaderLink: "Products",
136136
});
137+
138+
/*********** Products: shirt (rewrite to /products/tshirt) ***********/
139+
await linkNavigate(
140+
ctx,
141+
'[data-test-link="products-shirt-rewrite-plain_string_no_trailing_slash"]',
142+
);
143+
await assertPage(ctx, {
144+
pathname: "/qwikcity-test/products/shirt-rewrite-plain_string/",
145+
title: "Product tshirt - Qwik",
146+
layoutHierarchy: ["root"],
147+
h1: "Product: tshirt",
148+
activeHeaderLink: "Products",
149+
});
137150
}
138151

139152
/*********** Products: hoodie (404) ***********/

starters/e2e/qwikcity/util.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,16 @@ export async function assertPage(ctx: TestContext, test: AssertPage) {
2323
expect(canonicalUrl.pathname).toBe(test.pathname);
2424
}
2525

26+
if (test.searchParams) {
27+
if (test.searchParams === "empty") {
28+
expect(pageUrl.searchParams.size).toBe(0);
29+
} else {
30+
for (const [key, value] of Object.entries(test.searchParams)) {
31+
expect(pageUrl.searchParams.get(key)).toBe(value);
32+
}
33+
}
34+
}
35+
2636
if (test.title) {
2737
const title = head.locator("title");
2838
expect(await title.innerText()).toBe(test.title);
@@ -76,6 +86,7 @@ export async function assertPage(ctx: TestContext, test: AssertPage) {
7686

7787
interface AssertPage {
7888
pathname?: string;
89+
searchParams?: Record<string, string> | "empty";
7990
title?: string;
8091
h1?: string;
8192
layoutHierarchy?: string[];

0 commit comments

Comments
 (0)