react-router: [Bug]: Match route does not work if there is a minus sign at the beginning

What version of React Router are you using?

6.2.1

Steps to Reproduce

<Routes>
      <Route path="/users/:id" element={<UserApp />} />
</Routes>

Expected Behavior

/users/-wYVsb1KDtT9YJJFUiSTq0dqUyvc5vK51nx7QW29CPJc - This route is matched

Actual Behavior

/users/-wYVsb1KDtT9YJJFUiSTq0dqUyvc5vK51nx7QW29CPJc - This route is NOT matched

/users/wYVsb1KDtT9YJJFUiSTq0dqUyvc5vK51nx7QW29CPJc - This route is matched

I think the problem is in the mechanism that is looking for a suitable route.

Anything that starts with a symbol - is not matched.

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 4
  • Comments: 21 (9 by maintainers)

Most upvoted comments

@brophdawg11 So are routes like https://www.npmjs.com/package/@types/node in violation of RFC 3986 and thus react-router won’t support it, despite this existing in the wild? Or am I misunderstanding?

@troyschneringer Yeah that’s intentional per the Unreserved Characters section of RFC 3986 referenced in the PR. Preceding that is the section on Reserved Characters which includes @ and indicates that URLs should be encoding @ ahead of time:

2.2. Reserved Characters

URIs include components and subcomponents that are delimited by characters in the “reserved” set. These characters are called “reserved” because they may (or may not) be defined as delimiters by the generic syntax, by each scheme-specific syntax, or by the implementation-specific syntax of a URI’s dereferencing algorithm. If data for a URI component would conflict with a reserved character’s purpose as a delimiter, then the conflicting data must be percent-encoded before the URI is formed.

 reserved    = gen-delims / sub-delims

 gen-delims  = ":" / "/" / "?" / "#" / "[" / "]" / "@"

 sub-delims  = "!" / "$" / "&" / "'" / "(" / ")"
             / "*" / "+" / "," / ";" / "="

Same problem for @ character at the beginning

I wouldn’t consider it a hard “won’t support it” based on #8563 alone - @ in particular hasn’t been given a lot of thought since it was not the original issue in this bug or #8561. The RFC section I mentioned above spoke more to why the PR author chose to support ~/-/. as they are explicitly Unreserved Characters.

I would vote that support for Reserved Characters such as @ be discussed separately in a new discussion/issue so they can be properly evaluated.

2.2. Reserved Characters

URIs include components and subcomponents that are delimited by characters in the “reserved” set. These characters are called “reserved” because they may (or may not) be defined as delimiters by the generic syntax, by each scheme-specific syntax, or by the implementation-specific syntax of a URI’s dereferencing algorithm.

I think the operative phrase here is “… they may (or may not) be defined as delimiters by the generic syntax, by each scheme-specific syntax…”

I believe standard URLs (via http: and https: schemes) treat @ as a regular character. Same with mailto: (otherwise you’d have to encode the @ in email addresses.

@dartandrevinsky and @egerrek

I think the issue can be traced to line 1225: https://github.com/remix-run/react-router/blob/59b319feaa12745a434afdef5cadfcabd01206f9/packages/react-router/index.tsx#L1213-L1226

The problem with using \b in the regex is that its only matching the equivalent of [a-zA-Z0-9_].

I’m not a regex expert and am not finding an equivalent of \b to use that handles unicode characters.

same here, urls with @ in the beginning does not work, this was working before, what happened ?

thanks in advance

I’ve just noticed the same bug, but I have a “.” in the route. e.g. this wouldn’t match to the path - login/reset/:resetToken: login/reset/Djdfsd32afasdg.kdaf324asdf.adsgGsd however this path - login/reset/:resetToken/success will be matched: login/reset/Djdfsd32afasdg.kdaf324asdf.adsgGsd/success

Update Since my error was actually 404, it’s actually a problem with Vite’s local dev server, and I’ve found Issue and PR in their repo for similar behaviour with “.” in the URL.