Repository: remix-run/react-router
File: packages/router/router.ts (TypeScript)

Code before:
) {
  let contextualMatches: AgnosticDataRouteMatch[];
  let activeRouteMatch: AgnosticDataRouteMatch | undefined;
  if (fromRouteId != null && relative !== "path") {
    // Grab matches up to the calling route so our route-relative logic is
    // relative to the correct source route.  When using relative:path,
    // fromRouteId is ignored since that is always relative to the current
    // location path
    contextualMatches = [];
    for (let match of matches) {
      contextualMatches.push(match);
      if (match.route.id === fromRouteId) {
        activeRouteMatch = match;
        break;
      }
    }
  } else {
    contextualMatches = matches;
    activeRouteMatch = matches[matches.length - 1];
  }

  // Resolve the relative path
  let path = resolveTo(
    to ? to : ".",
    getPathContributingMatches(contextualMatches).map((m) => m.pathnameBase),
    location.pathname,
    relative === "path"
  );

  // When `to` is not specified we inherit search/hash from the current
  // location, unlike when to="." and we just inherit the path.
  // See https://github.com/remix-run/remix/issues/927
  if (to == null) {
    path.search = location.search;
    path.hash = location.hash;
  }

  // Add an ?index param for matched index routes if we don't already have one
  if (
    (to == null || to === "" || to === ".") &&
    activeRouteMatch &&
    activeRouteMatch.route.index &&
    !hasNakedIndexQuery(path.search)
  ) {
    path.search = path.search
      ? path.search.replace(/^\?/, "?index&")
      : "?index";
  }

  // If we're operating within a basename, prepend it to the pathname.  If
  // this is a root navigation, then just use the raw basename which allows

Review comment (suggestion):
`useLocation` strips this off so this code brought in from the react layer lost that since the raw router location contains the basename

Code after:
) {
  let contextualMatches: AgnosticDataRouteMatch[];
  let activeRouteMatch: AgnosticDataRouteMatch | undefined;
  if (fromRouteId != null && relative !== "path") {
    // Grab matches up to the calling route so our route-relative logic is
    // relative to the correct source route.  When using relative:path,
    // fromRouteId is ignored since that is always relative to the current
    // location path
    contextualMatches = [];
    for (let match of matches) {
      contextualMatches.push(match);
      if (match.route.id === fromRouteId) {
        activeRouteMatch = match;
        break;
      }
    }
  } else {
    contextualMatches = matches;
    activeRouteMatch = matches[matches.length - 1];
  }

  // Resolve the relative path
  let path = resolveTo(
    to ? to : ".",
    getPathContributingMatches(contextualMatches).map((m) => m.pathnameBase),
    stripBasename(location.pathname, basename) || location.pathname,
    relative === "path"
  );

  // When `to` is not specified we inherit search/hash from the current
  // location, unlike when to="." and we just inherit the path.
  // See https://github.com/remix-run/remix/issues/927
  if (to == null) {
    path.search = location.search;
    path.hash = location.hash;
  }

  // Add an ?index param for matched index routes if we don't already have one
  if (
    (to == null || to === "" || to === ".") &&
    activeRouteMatch &&
    activeRouteMatch.route.index &&
    !hasNakedIndexQuery(path.search)
  ) {
    path.search = path.search
      ? path.search.replace(/^\?/, "?index&")
      : "?index";
  }

  // If we're operating within a basename, prepend it to the pathname.  If
  // this is a root navigation, then just use the raw basename which allows