From 90c0d27a7314922e306c8695b7eb2489f19b7dcc Mon Sep 17 00:00:00 2001 From: Matt Brophy Date: Thu, 8 Feb 2024 11:36:18 -0500 Subject: [PATCH] Fix SPA Mode issue when using a basename --- .changeset/eighty-years-accept.md | 5 ++ integration/helpers/create-fixture.ts | 2 +- integration/spa-mode-test.ts | 82 +++++++++++++++++++++++++++ packages/remix-dev/vite/plugin.ts | 8 ++- 4 files changed, 93 insertions(+), 4 deletions(-) create mode 100644 .changeset/eighty-years-accept.md diff --git a/.changeset/eighty-years-accept.md b/.changeset/eighty-years-accept.md new file mode 100644 index 00000000000..e2ac278139b --- /dev/null +++ b/.changeset/eighty-years-accept.md @@ -0,0 +1,5 @@ +--- +"@remix-run/dev": patch +--- + +Fix build issue in SPA mode when using a `basename` diff --git a/integration/helpers/create-fixture.ts b/integration/helpers/create-fixture.ts index 64d5cd508d8..7b2ba9b3485 100644 --- a/integration/helpers/create-fixture.ts +++ b/integration/helpers/create-fixture.ts @@ -216,7 +216,7 @@ export async function createAppFixture(fixture: Fixture, mode?: ServerMode) { app.use(express.static(path.join(fixture.projectDir, "build/client"))); app.get("*", (_, res, next) => res.sendFile( - path.join(process.cwd(), "build/client/index.html"), + path.join(fixture.projectDir, "build/client/index.html"), next ) ); diff --git a/integration/spa-mode-test.ts b/integration/spa-mode-test.ts index 20febf9c2c1..7eae3affcb4 100644 --- a/integration/spa-mode-test.ts +++ b/integration/spa-mode-test.ts @@ -263,6 +263,88 @@ test.describe("SPA Mode", () => { expect(html).toMatch(/^
/); expect(html).not.toMatch(//); }); + + test("works when combined with a basename", async ({ page }) => { + fixture = await createFixture({ + compiler: "vite", + spaMode: true, + files: { + "vite.config.ts": js` + import { defineConfig } from "vite"; + import { unstable_vitePlugin as remix } from "@remix-run/dev"; + + export default defineConfig({ + plugins: [remix({ + basename: "/base/", + unstable_ssr: false }, + )], + }); + `, + "app/root.tsx": js` + import { Outlet, Scripts } from "@remix-run/react"; + + export default function Root() { + return ( + + + +

Root

+ + + + + ); + } + + export function HydrateFallback() { + return ( + + + +

Loading SPA...

+ + + + ); + } + `, + "app/routes/_index.tsx": js` + import * as React from "react"; + import { useLoaderData } from "@remix-run/react"; + + export async function clientLoader({ request }) { + return "Index Loader Data"; + } + + export default function Component() { + let data = useLoaderData(); + const [mounted, setMounted] = React.useState(false); + React.useEffect(() => setMounted(true), []); + + return ( + <> +

Index

+

{data}

+ {!mounted ?

Unmounted

:

Mounted

} + + ); + } + `, + }, + }); + appFixture = await createAppFixture(fixture); + + let app = new PlaywrightFixture(appFixture, page); + await app.goto("/base/"); + console.log(await app.getHtml()); + await new Promise((r) => setTimeout(r, 1000)); + console.log(await app.getHtml()); + await page.waitForSelector("[data-mounted]"); + expect(await page.locator("[data-route]").textContent()).toBe("Index"); + expect(await page.locator("[data-loader-data]").textContent()).toBe( + "Index Loader Data" + ); + }); }); test.describe("normal apps", () => { diff --git a/packages/remix-dev/vite/plugin.ts b/packages/remix-dev/vite/plugin.ts index defadd62f22..59956887967 100644 --- a/packages/remix-dev/vite/plugin.ts +++ b/packages/remix-dev/vite/plugin.ts @@ -1284,7 +1284,8 @@ export const remixVitePlugin: RemixVitePlugin = (remixUserConfig = {}) => { serverBuildDirectory, ctx.remixConfig.serverBuildFile, clientBuildDirectory, - viteConfig + viteConfig, + ctx.remixConfig.basename ); } }, @@ -1721,7 +1722,8 @@ async function handleSpaMode( serverBuildDirectoryPath: string, serverBuildFile: string, clientBuildDirectory: string, - viteConfig: Vite.ResolvedConfig + viteConfig: Vite.ResolvedConfig, + basename: string ) { // Create a handler and call it for the `/` path - rendering down to the // proper HydrateFallback ... or not! Maybe they have a static landing page @@ -1730,7 +1732,7 @@ async function handleSpaMode( let build = await import(url.pathToFileURL(serverBuildPath).toString()); let { createRequestHandler: createHandler } = await import("@remix-run/node"); let handler = createHandler(build, viteConfig.mode); - let response = await handler(new Request("http://localhost/")); + let response = await handler(new Request(`http://localhost${basename}`)); let html = await response.text(); if (response.status !== 200) { throw new Error(