Skip to content

Commit 5d55300

Browse files
committed
Merge branch 'release-next'
2 parents aaa1506 + 26653a6 commit 5d55300

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

66 files changed

+1377
-369
lines changed

CHANGELOG.md

Lines changed: 210 additions & 151 deletions
Large diffs are not rendered by default.

contributors.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
- amsal
3030
- Andarist
3131
- andreasottosson-polestar
32+
- andreiborza
3233
- andreiduca
3334
- antonmontrezor
3435
- appden
@@ -55,6 +56,7 @@
5556
- bilalk711
5657
- bjohn465
5758
- black5box
59+
- BlankParticle
5860
- bmsuseluda
5961
- bobziroll
6062
- bravo-kernel
@@ -105,6 +107,7 @@
105107
- dgrijuela
106108
- DigitalNaut
107109
- DimaAmega
110+
- dimmageiras
108111
- dmitrytarassov
109112
- dogxii
110113
- dokeet
@@ -338,6 +341,7 @@
338341
- renyu-io
339342
- reyronald
340343
- RFCreate
344+
- richardkall
341345
- richardscarrott
342346
- rifaidev
343347
- rimian

integration/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
### Minor Changes
66

77
- Unstable Vite support for Node-based Remix apps ([#7590](https://github.com/remix-run/remix/pull/7590))
8+
89
- `remix build` 👉 `vite build && vite build --ssr`
910
- `remix dev` 👉 `vite dev`
1011

integration/client-data-test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ test.describe("Client Data", () => {
149149
templateName,
150150
files: {
151151
"react-router.config.ts": reactRouterConfig({
152-
v8_splitRouteModules,
152+
future: { v8_splitRouteModules },
153153
}),
154154
"app/root.tsx": js`
155155
import { Form, Outlet, Scripts } from "react-router"

integration/helpers/vite.ts

Lines changed: 13 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -23,42 +23,23 @@ const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
2323
const root = path.resolve(__dirname, "../..");
2424
const TMP_DIR = path.join(root, ".tmp/integration");
2525

26-
export const reactRouterConfig = ({
27-
ssr,
28-
basename,
29-
prerender,
30-
appDirectory,
31-
v8_middleware,
32-
v8_splitRouteModules,
33-
v8_viteEnvironmentApi,
34-
routeDiscovery,
35-
}: {
36-
ssr?: boolean;
37-
basename?: string;
38-
prerender?: boolean | string[];
39-
appDirectory?: string;
40-
v8_middleware?: boolean;
41-
v8_splitRouteModules?: NonNullable<Config["future"]>["v8_splitRouteModules"];
42-
v8_viteEnvironmentApi?: boolean;
43-
routeDiscovery?: Config["routeDiscovery"];
44-
}) => {
45-
let config: Config = {
46-
ssr,
47-
basename,
48-
prerender,
49-
appDirectory,
50-
routeDiscovery,
51-
future: {
52-
v8_middleware,
53-
v8_splitRouteModules,
54-
v8_viteEnvironmentApi,
55-
},
56-
};
26+
export const reactRouterConfig = (
27+
// Don't support function configs due to JSON.stringify()
28+
config: Omit<Partial<Config>, "buildEnd" | "presets" | "serverBundles">,
29+
) => {
30+
if (
31+
typeof config.prerender === "function" ||
32+
(typeof config.prerender === "object" &&
33+
!Array.isArray(config.prerender) &&
34+
typeof config.prerender.paths === "function")
35+
) {
36+
throw new Error("reactRouterConfig() does not support prerender functions");
37+
}
5738

5839
return dedent`
5940
import type { Config } from "@react-router/dev/config";
6041
61-
export default ${JSON.stringify(config)} satisfies Config;
42+
export default ${JSON.stringify(config, null, 2)} satisfies Config;
6243
`;
6344
};
6445

integration/middleware-test.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ test.describe("Middleware", () => {
4040
// ...existing code...
4141
"react-router.config.ts": reactRouterConfig({
4242
ssr: false,
43-
v8_middleware: true,
43+
future: { v8_middleware: true },
4444
}),
4545
"vite.config.ts": js`
4646
import { defineConfig } from "vite";
@@ -368,8 +368,7 @@ test.describe("Middleware", () => {
368368
files: {
369369
"react-router.config.ts": reactRouterConfig({
370370
ssr: false,
371-
v8_middleware: true,
372-
v8_splitRouteModules: true,
371+
future: { v8_middleware: true, v8_splitRouteModules: true },
373372
}),
374373
"vite.config.ts": js`
375374
import { defineConfig } from "vite";
@@ -466,7 +465,7 @@ test.describe("Middleware", () => {
466465
fixture = await createFixture({
467466
files: {
468467
"react-router.config.ts": reactRouterConfig({
469-
v8_middleware: true,
468+
future: { v8_middleware: true },
470469
}),
471470
"vite.config.ts": js`
472471
import { defineConfig } from "vite";
@@ -773,7 +772,7 @@ test.describe("Middleware", () => {
773772
let fixture = await createFixture({
774773
files: {
775774
"react-router.config.ts": reactRouterConfig({
776-
v8_middleware: true,
775+
future: { v8_middleware: true },
777776
}),
778777
"vite.config.ts": js`
779778
import { defineConfig } from "vite";
@@ -895,7 +894,7 @@ test.describe("Middleware", () => {
895894
let fixture = await createFixture({
896895
files: {
897896
"react-router.config.ts": reactRouterConfig({
898-
v8_middleware: true,
897+
future: { v8_middleware: true },
899898
}),
900899
"vite.config.ts": js`
901900
import { defineConfig } from "vite";
@@ -1060,8 +1059,7 @@ test.describe("Middleware", () => {
10601059
fixture = await createFixture({
10611060
files: {
10621061
"react-router.config.ts": reactRouterConfig({
1063-
v8_middleware: true,
1064-
v8_splitRouteModules: true,
1062+
future: { v8_middleware: true, v8_splitRouteModules: true },
10651063
}),
10661064
"vite.config.ts": js`
10671065
import { defineConfig } from "vite";
@@ -1156,7 +1154,9 @@ test.describe("Middleware", () => {
11561154
test.beforeAll(async () => {
11571155
fixture = await createFixture({
11581156
files: {
1159-
"react-router.config.ts": reactRouterConfig({ v8_middleware: true }),
1157+
"react-router.config.ts": reactRouterConfig({
1158+
future: { v8_middleware: true },
1159+
}),
11601160
"vite.config.ts": js`
11611161
import { defineConfig } from "vite";
11621162
import { reactRouter } from "@react-router/dev/vite";
@@ -1983,7 +1983,7 @@ test.describe("Middleware", () => {
19831983
{
19841984
files: {
19851985
"react-router.config.ts": reactRouterConfig({
1986-
v8_middleware: true,
1986+
future: { v8_middleware: true },
19871987
}),
19881988
"vite.config.ts": js`
19891989
import { defineConfig } from "vite";

integration/single-fetch-test.ts

Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4476,4 +4476,193 @@ test.describe("single-fetch", () => {
44764476
await page.waitForSelector("h1");
44774477
expect(await app.getHtml("h1")).toMatch("It worked!");
44784478
});
4479+
4480+
test("always uses /{path}.data without future.unstable_trailingSlashAwareDataRequests flag", async ({
4481+
page,
4482+
}) => {
4483+
let fixture = await createFixture({
4484+
files: {
4485+
...files,
4486+
"app/routes/_index.tsx": js`
4487+
import { Link } from "react-router";
4488+
4489+
export default function Index() {
4490+
return (
4491+
<div>
4492+
<h1>Home</h1>
4493+
<Link to="/about/">Go to About (with trailing slash)</Link>
4494+
<Link to="/about">Go to About (without trailing slash)</Link>
4495+
</div>
4496+
);
4497+
}
4498+
`,
4499+
"app/routes/about.tsx": js`
4500+
import { Link, useLoaderData } from "react-router";
4501+
4502+
export function loader({ request }) {
4503+
let url = new URL(request.url);
4504+
return {
4505+
pathname: url.pathname,
4506+
hasTrailingSlash: url.pathname.endsWith("/"),
4507+
};
4508+
}
4509+
4510+
export default function About() {
4511+
let { pathname, hasTrailingSlash } = useLoaderData();
4512+
return (
4513+
<div>
4514+
<h1>About</h1>
4515+
<p id="pathname">{pathname}</p>
4516+
<p id="trailing-slash">{String(hasTrailingSlash)}</p>
4517+
<Link to="/">Go back home</Link>
4518+
</div>
4519+
);
4520+
}
4521+
`,
4522+
},
4523+
});
4524+
let appFixture = await createAppFixture(fixture);
4525+
let app = new PlaywrightFixture(appFixture, page);
4526+
4527+
let requests: string[] = [];
4528+
page.on("request", (req) => {
4529+
let url = new URL(req.url());
4530+
if (url.pathname.endsWith(".data")) {
4531+
requests.push(url.pathname + url.search);
4532+
}
4533+
});
4534+
4535+
// Document load without trailing slash
4536+
await app.goto("/about");
4537+
await page.waitForSelector("#pathname");
4538+
expect(await page.locator("#pathname").innerText()).toEqual("/about");
4539+
expect(await page.locator("#trailing-slash").innerText()).toEqual("false");
4540+
4541+
// Client-side navigation without trailing slash
4542+
await app.goto("/");
4543+
await app.clickLink("/about");
4544+
await page.waitForSelector("#pathname");
4545+
expect(await page.locator("#pathname").innerText()).toEqual("/about");
4546+
expect(await page.locator("#trailing-slash").innerText()).toEqual("false");
4547+
expect(requests).toEqual(["/about.data"]);
4548+
requests = [];
4549+
4550+
// Document load with trailing slash
4551+
await app.goto("/about/");
4552+
await page.waitForSelector("#pathname");
4553+
expect(await page.locator("#pathname").innerText()).toEqual("/about/");
4554+
expect(await page.locator("#trailing-slash").innerText()).toEqual("true");
4555+
4556+
// Client-side navigation with trailing slash
4557+
await app.goto("/");
4558+
await app.clickLink("/about/");
4559+
await page.waitForSelector("#pathname");
4560+
expect(await page.locator("#pathname").innerText()).toEqual("/about");
4561+
expect(await page.locator("#trailing-slash").innerText()).toEqual("false");
4562+
expect(requests).toEqual(["/about.data"]);
4563+
requests = [];
4564+
4565+
// Client-side navigation back to /
4566+
await app.clickLink("/");
4567+
await page.waitForSelector("h1:has-text('Home')");
4568+
expect(requests).toEqual(["/_root.data"]);
4569+
requests = [];
4570+
});
4571+
4572+
test("uses {path}.data or {path}/_.data depending on trailing slash with future.unstable_trailingSlashAwareDataRequests flag", async ({
4573+
page,
4574+
}) => {
4575+
let fixture = await createFixture({
4576+
files: {
4577+
...files,
4578+
"react-router.config.ts": reactRouterConfig({
4579+
future: {
4580+
unstable_trailingSlashAwareDataRequests: true,
4581+
},
4582+
}),
4583+
"app/routes/_index.tsx": js`
4584+
import { Link } from "react-router";
4585+
4586+
export default function Index() {
4587+
return (
4588+
<div>
4589+
<h1>Home</h1>
4590+
<Link to="/about/">Go to About (with trailing slash)</Link>
4591+
<Link to="/about">Go to About (without trailing slash)</Link>
4592+
</div>
4593+
);
4594+
}
4595+
`,
4596+
"app/routes/about.tsx": js`
4597+
import { Link, useLoaderData } from "react-router";
4598+
4599+
export function loader({ request }) {
4600+
let url = new URL(request.url);
4601+
return {
4602+
pathname: url.pathname,
4603+
hasTrailingSlash: url.pathname.endsWith("/"),
4604+
};
4605+
}
4606+
4607+
export default function About() {
4608+
let { pathname, hasTrailingSlash } = useLoaderData();
4609+
return (
4610+
<div>
4611+
<h1>About</h1>
4612+
<p id="pathname">{pathname}</p>
4613+
<p id="trailing-slash">{String(hasTrailingSlash)}</p>
4614+
<Link to="/">Go back home</Link>
4615+
</div>
4616+
);
4617+
}
4618+
`,
4619+
},
4620+
});
4621+
let appFixture = await createAppFixture(fixture);
4622+
let app = new PlaywrightFixture(appFixture, page);
4623+
4624+
let requests: string[] = [];
4625+
page.on("request", (req) => {
4626+
let url = new URL(req.url());
4627+
if (url.pathname.endsWith(".data")) {
4628+
requests.push(url.pathname + url.search);
4629+
}
4630+
});
4631+
4632+
// Document load without trailing slash
4633+
await app.goto("/about");
4634+
await page.waitForSelector("#pathname");
4635+
expect(await page.locator("#pathname").innerText()).toEqual("/about");
4636+
expect(await page.locator("#trailing-slash").innerText()).toEqual("false");
4637+
4638+
// Client-side navigation without trailing slash
4639+
await app.goto("/");
4640+
await app.clickLink("/about");
4641+
await page.waitForSelector("#pathname");
4642+
expect(await page.locator("#pathname").innerText()).toEqual("/about");
4643+
expect(await page.locator("#trailing-slash").innerText()).toEqual("false");
4644+
expect(requests).toEqual(["/about.data"]);
4645+
requests = [];
4646+
4647+
// Document load with trailing slash
4648+
await app.goto("/about/");
4649+
await page.waitForSelector("#pathname");
4650+
expect(await page.locator("#pathname").innerText()).toEqual("/about/");
4651+
expect(await page.locator("#trailing-slash").innerText()).toEqual("true");
4652+
4653+
// Client-side navigation with trailing slash
4654+
await app.goto("/");
4655+
await app.clickLink("/about/");
4656+
await page.waitForSelector("#pathname");
4657+
expect(await page.locator("#pathname").innerText()).toEqual("/about/");
4658+
expect(await page.locator("#trailing-slash").innerText()).toEqual("true");
4659+
expect(requests).toEqual(["/about/_.data"]);
4660+
requests = [];
4661+
4662+
// Client-side navigation back to /
4663+
await app.clickLink("/");
4664+
await page.waitForSelector("h1:has-text('Home')");
4665+
expect(requests).toEqual(["/_.data"]);
4666+
requests = [];
4667+
});
44794668
});

0 commit comments

Comments
 (0)