From 1acaced4c41e673b9474401b3f551443e127be5f Mon Sep 17 00:00:00 2001 From: saengmotmi Date: Sun, 20 Oct 2024 23:20:29 +0900 Subject: [PATCH 1/4] test: add fail case test --- integration/vite-prerender-test.ts | 87 ++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/integration/vite-prerender-test.ts b/integration/vite-prerender-test.ts index de77dac736..e824af9954 100644 --- a/integration/vite-prerender-test.ts +++ b/integration/vite-prerender-test.ts @@ -560,6 +560,93 @@ test.describe("Prerendering", () => { ); }); + test("Handles UTF-8 characters in prerendered and non-prerendered routes", async ({ + page, + }) => { + fixture = await createFixture({ + prerender: false, + files: { + ...files, + "vite.config.ts": js` + import { defineConfig } from "vite"; + import { reactRouter } from "@react-router/dev/vite"; + + export default defineConfig({ + build: { manifest: true }, + plugins: [ + reactRouter({ + prerender: ["/", "/utf8-prerendered"], + }) + ], + }); + `, + "app/routes/utf8-prerendered.tsx": js` + import { useLoaderData } from 'react-router'; + export function loader({ request }) { + return { + prerendered: request.headers.has('X-React-Router-Prerender') ? 'yes' : 'no', + data: "한글 데이터 - UTF-8 문자", + }; + } + + export default function Comp() { + let data = useLoaderData(); + return ( + <> +

UTF-8 Prerendered

+

{data.prerendered}

+

{data.data}

+ + ); + } + `, + "app/routes/utf8-not-prerendered.tsx": js` + import { useLoaderData } from 'react-router'; + export function loader({ request }) { + return { + prerendered: request.headers.has('X-React-Router-Prerender') ? 'yes' : 'no', + data: "非プリレンダリングデータ - UTF-8文字", + }; + } + + export default function Comp() { + let data = useLoaderData(); + return ( + <> +

UTF-8 Not Prerendered

+

{data.prerendered}

+

{data.data}

+ + ); + } + `, + }, + }); + appFixture = await createAppFixture(fixture); + + let app = new PlaywrightFixture(appFixture, page); + + // Test prerendered route with UTF-8 characters + await app.goto("/utf8-prerendered"); + await page.waitForSelector("[data-mounted]"); + expect(await app.getHtml("[data-title]")).toContain("UTF-8 Prerendered"); + expect(await app.getHtml("[data-prerendered]")).toContain("yes"); + expect(await app.getHtml("[data-content]")).toContain( + "한글 데이터 - UTF-8 문자" + ); + + // Test non-prerendered route with UTF-8 characters + await app.goto("/utf8-not-prerendered"); + await page.waitForSelector("[data-mounted]"); + expect(await app.getHtml("[data-title]")).toContain( + "UTF-8 Not Prerendered" + ); + expect(await app.getHtml("[data-prerendered]")).toContain("no"); + expect(await app.getHtml("[data-content]")).toContain( + "非プリレンダリングデータ - UTF-8文字" + ); + }); + test("Renders down to the proper HydrateFallback", async ({ page }) => { fixture = await createFixture({ prerender: true, From 29b2fbf6bf14024feea0a39c52f460f55f4138bd Mon Sep 17 00:00:00 2001 From: saengmotmi Date: Sun, 20 Oct 2024 23:27:56 +0900 Subject: [PATCH 2/4] fix: utf-8 prerender issue --- packages/react-router-dev/vite/plugin.ts | 2 +- packages/react-router/lib/server-runtime/routes.ts | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/react-router-dev/vite/plugin.ts b/packages/react-router-dev/vite/plugin.ts index 201d143677..53fbb58f43 100644 --- a/packages/react-router-dev/vite/plugin.ts +++ b/packages/react-router-dev/vite/plugin.ts @@ -1888,7 +1888,7 @@ async function handlePrerender( reactRouterConfig, viteConfig, data - ? { headers: { ...headers, "X-React-Router-Prerender-Data": data } } + ? { headers: { ...headers, "X-React-Router-Prerender-Data": encodeURI(data) } } : { headers } ); } diff --git a/packages/react-router/lib/server-runtime/routes.ts b/packages/react-router/lib/server-runtime/routes.ts index 6023927eec..cb090db81b 100644 --- a/packages/react-router/lib/server-runtime/routes.ts +++ b/packages/react-router/lib/server-runtime/routes.ts @@ -79,9 +79,12 @@ export function createStaticHandlerDataRoutes( // If we're prerendering, use the data passed in from prerendering // the .data route so we dom't call loaders twice if (args.request.headers.has("X-React-Router-Prerender-Data")) { - let encoded = args.request.headers.get( + const preRenderedData = args.request.headers.get( "X-React-Router-Prerender-Data" ); + let encoded = preRenderedData + ? decodeURI(preRenderedData) + : preRenderedData; invariant(encoded, "Missing prerendered data for route"); let uint8array = new TextEncoder().encode(encoded); let stream = new ReadableStream({ From 79653009ef1f5e0ea97ebb994fe0274be6de7c67 Mon Sep 17 00:00:00 2001 From: saengmotmi Date: Sun, 20 Oct 2024 23:38:55 +0900 Subject: [PATCH 3/4] chore: add contributors.yml --- contributors.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/contributors.yml b/contributors.yml index 18f4146169..c737d45122 100644 --- a/contributors.yml +++ b/contributors.yml @@ -227,6 +227,7 @@ - rubeonline - ryanflorence - ryanhiebert +- saengmotmi - sanketshah19 - saul-atomrigs - sbolel From 33a0c0dfdffc3c8432be934cd703dc7ffa0f9711 Mon Sep 17 00:00:00 2001 From: Jacob Ebey Date: Tue, 12 Nov 2024 15:07:19 -0800 Subject: [PATCH 4/4] Create shiny-cameras-try.md --- .changeset/shiny-cameras-try.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .changeset/shiny-cameras-try.md diff --git a/.changeset/shiny-cameras-try.md b/.changeset/shiny-cameras-try.md new file mode 100644 index 0000000000..6bec5dfd02 --- /dev/null +++ b/.changeset/shiny-cameras-try.md @@ -0,0 +1,7 @@ +--- +"integration": patch +"@react-router/dev": patch +"react-router": patch +--- + +fix(react-router): (v7) fix static prerender of non-ascii characters