diff --git a/.changeset/form-action-index.md b/.changeset/form-action-index.md
new file mode 100644
index 0000000000..5d4929f2d1
--- /dev/null
+++ b/.changeset/form-action-index.md
@@ -0,0 +1,5 @@
+---
+"react-router-dom": patch
+---
+
+Fix `useFormAction` which was incorrectly inheriting the `?index` query param from child route `action` submissions
diff --git a/packages/react-router-dom/__tests__/data-browser-router-test.tsx b/packages/react-router-dom/__tests__/data-browser-router-test.tsx
index 574b653816..5f0ce3faf5 100644
--- a/packages/react-router-dom/__tests__/data-browser-router-test.tsx
+++ b/packages/react-router-dom/__tests__/data-browser-router-test.tsx
@@ -2693,6 +2693,28 @@ function testDomRouter(
"/foo"
);
});
+
+ it("does not include the index parameter if we've submitted to a child index route", async () => {
+ let router = createTestRouter(
+ createRoutesFromElements(
+
+
+ }>
+ Index} />
+
+
+
+ ),
+ {
+ window: getWindow("/foo/bar?index&a=1"),
+ }
+ );
+ let { container } = render();
+
+ expect(container.querySelector("form")?.getAttribute("action")).toBe(
+ "/foo/bar?a=1"
+ );
+ });
});
describe("index routes", () => {
diff --git a/packages/react-router-dom/index.tsx b/packages/react-router-dom/index.tsx
index c86eb8286f..78b6d8db96 100644
--- a/packages/react-router-dom/index.tsx
+++ b/packages/react-router-dom/index.tsx
@@ -1551,11 +1551,11 @@ export function useFormAction(
// would have called useResolvedPath(".") which will never include a search
path.search = location.search;
- // When grabbing search params from the URL, remove the automatically
- // inserted ?index param so we match the useResolvedPath search behavior
- // which would not include ?index
- if (match.route.index) {
- let params = new URLSearchParams(path.search);
+ // When grabbing search params from the URL, remove any included ?index param
+ // since it might not apply to our contextual route. We add it back based
+ // on match.route.index below
+ let params = new URLSearchParams(path.search);
+ if (params.has("index") && params.get("index") === "") {
params.delete("index");
path.search = params.toString() ? `?${params.toString()}` : "";
}