Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Posting to nested forms without leading / modifies route (since v2.3.0) #8054

Closed
chohner opened this issue Nov 18, 2023 · 1 comment
Closed

Comments

@chohner
Copy link
Contributor

chohner commented Nov 18, 2023

Reproduction

https://stackblitz.com/edit/remix-run-remix-tutwtc?file=app%2Froutes%2F%24.tsx

  • nested url -> routeParam submit -> check terminal log of route params & pathname

Working cases (flat url, posting form with leading /) included for convenience

System Info

System:
    OS: macOS 14.1.1
    CPU: (10) arm64 Apple M2 Pro
    Memory: 2.71 GB / 32.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 20.9.0 - ~/.nvm/versions/node/v20.9.0/bin/node
    Yarn: 1.22.19 - ~/.nvm/versions/node/v20.9.0/bin/yarn
    npm: 10.2.4 - ~/.nvm/versions/node/v20.9.0/bin/npm
    pnpm: 7.28.0 - ~/.nvm/versions/node/v20.9.0/bin/pnpm
  Browsers:
    Brave Browser: 119.1.60.118
    Safari: 17.1

Used Package Manager

npm

Expected Behavior

The route do not change, independent of the form action

Actual Behavior

When submitting to an action with a dash that isn't in the first position, the route is changed

@chohner chohner changed the title Sending form to nested action without leading / causes route params to change (since v2.3.0) Posting to nested forms without leading / modifies route (since v2.3.0) Nov 18, 2023
@brophdawg11 brophdawg11 self-assigned this Nov 20, 2023
@brophdawg11
Copy link
Contributor

This is the result of a recent bug fix in React Router (remix-run/react-router#10983) where useResolvedPath was not working correctly for splat routes (this is what is called internally by useFormAction).

Relative routing when not using a leading / is relative to the current location, so when you are on http://example.com/foo, if you have a <Link to="foo">/<Form action="foo">, then that should append to the current location and result in http://example.com/foo/foo. Previously, this behavior was broken in splat routes so there was an inconsistency across static, dynamic, and splat routes where static/dynamic were relative to the current route location but splat routes were relative to the parent route.

This shows itself most notably when using an action on a splat route:

// $.tsx
export function action() { ... }

export default function Component() {
  return (
      <Form method="post">
        <button type="submit">Form no action</button>
      </Form>
    </>
  );
}

Submitting the above form in Remix 2.2.0 and before would throw a 405 error because the <Form> action (defaulting to ".") would be relative to the splat parent (/), not the current location (i.e., /foo), so it would look on root.tsx for the action instead of the current route.

Whereas if you did the exact same thing above in a static route (foo.tsx) or a dynamic route ($param.tsx) then it would work as expected. This unit test shows the expected consistency across route types with the aforementioned fix.

If you want your paths to be relative to the parent, you can do that via:

<Form method="post" action={`../${routeParam}`}>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants