diff --git a/contributors.yml b/contributors.yml index 280d0143a7f..4ac93533057 100644 --- a/contributors.yml +++ b/contributors.yml @@ -138,6 +138,7 @@ - ianduvall - illright - imzshh +- ionut-botizan - isaacrmoreno - ishan-me - IshanKBG diff --git a/integration/form-test.ts b/integration/form-test.ts index ab7cfd5de58..11032fa88e3 100644 --- a/integration/form-test.ts +++ b/integration/form-test.ts @@ -40,6 +40,8 @@ test.describe("Forms", () => { let SPLAT_ROUTE_CURRENT_ACTION = "splat-route-cur"; let SPLAT_ROUTE_PARENT_ACTION = "splat-route-parent"; let SPLAT_ROUTE_TOO_MANY_DOTS_ACTION = "splat-route-too-many-dots"; + let UNDEFINED_ACTION_SEARCH_PARAMS = "undefined-action-search-params"; + let EXPLICIT_ACTION_SEARCH_PARAMS = "explicit-action-search-params"; test.beforeAll(async () => { fixture = await createFixture({ @@ -277,6 +279,22 @@ test.describe("Forms", () => { ) } `, + + "app/routes/login.jsx": js` + import { Form } from "@remix-run/react"; + export default function() { + return ( + <> +
+ +
+
+ +
+ + ) + } + `, }, }); @@ -574,5 +592,28 @@ test.describe("Forms", () => { expect(el.attr("action")).toMatch("/"); }); }); + + test.describe("in a route with search params", () => { + test("undefined action preserves current location's search params", async ({ + page, + }) => { + let app = new PlaywrightFixture(appFixture, page); + let url = "/login?redirectTo=/profile"; + await app.goto(url); + let html = await app.getHtml(); + let el = getElement(html, `#${UNDEFINED_ACTION_SEARCH_PARAMS}`); + expect(el.attr("action")).toMatch(url); + }); + + test("explicit action is preserved as defined", async ({ page }) => { + let app = new PlaywrightFixture(appFixture, page); + let url = "/login?redirectTo=/profile"; + let action = "/auth?nonce=123"; + await app.goto(url); + let html = await app.getHtml(); + let el = getElement(html, `#${EXPLICIT_ACTION_SEARCH_PARAMS}`); + expect(el.attr("action")).toMatch(action); + }); + }); }); }); diff --git a/packages/remix-react/components.tsx b/packages/remix-react/components.tsx index 721e5a49ae3..6f4ec7ca4c7 100644 --- a/packages/remix-react/components.tsx +++ b/packages/remix-react/components.tsx @@ -933,7 +933,7 @@ let FormImpl = React.forwardRef( reloadDocument = false, replace = false, method = "get", - action = ".", + action, encType = "application/x-www-form-urlencoded", fetchKey, onSubmit, @@ -988,16 +988,21 @@ type HTMLFormSubmitter = HTMLButtonElement | HTMLInputElement; * @see https://remix.run/api/remix#useformaction */ export function useFormAction( - action = ".", + action?: string, // TODO: Remove method param in v2 as it's no longer needed and is a breaking change method: FormMethod = "get" ): string { let { id } = useRemixRouteContext(); - let path = useResolvedPath(action); + let path = useResolvedPath(action ?? "."); + let location = useLocation(); let search = path.search; let isIndexRoute = id.endsWith("/index"); - if (action === "." && isIndexRoute) { + if (action === undefined) { + search = location.search; + } + + if ((action === undefined || action === ".") && isIndexRoute) { search = search ? search.replace(/^\?/, "?index&") : "?index"; }