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

Wrong route id for preloaded routes after rebuild route tree #2400

Open
stevenlyd opened this issue Sep 23, 2024 · 0 comments
Open

Wrong route id for preloaded routes after rebuild route tree #2400

stevenlyd opened this issue Sep 23, 2024 · 0 comments

Comments

@stevenlyd
Copy link

stevenlyd commented Sep 23, 2024

Which project does this relate to?

Router

Describe the bug

After a route (it needs to have a lazy route) /_protected/test got preloaded, then we call router.buildRouteTree() to rebuild the route tree again, that route will have a wrong id /_protected/_protected/test.

Your Example Website or App

https://stackblitz.com/edit/vitejs-vite-s8qswn?file=src%2FApp.tsx

Steps to Reproduce the Bug or Issue

  1. Open my StackBlitz example.
  2. It should automatically run the project. If not, just npm run start
  3. Open browser devtool's console.
  4. Click the first button to print router.routesById, in the console you can confirm all routes' ids are fine.
  5. Click the second button, it preloads the /_protected/test route.
  6. Click the third button to run router.buildRouteTree()
  7. Click the fourth button to print router.routesById again, in the console you can see the preloaded route /test now has a wrong id: /_protected/_protected/test

Expected behavior

No matter how many times I rebuild the route tree, the result should be consistent.
I'm doing dynamic route injection, so I need to rebuild the route tree after there is a new route got injected.

Screenshots or Videos

duplicated_id_prefix.mp4

Platform

  • OS: [Windows]
  • Browser: [Chrome]
  • Version: [1.58.3]

Additional context

How the issue happened

  1. This is currently how we generate id for a route instance in its init() method:
    const customId = options?.id || path // Uses path as id's fallback

    // Strip the parentId prefix from the first level of children
    let id = isRoot
      ? rootRouteId
      : joinPaths([
          this.parentRoute.id === rootRouteId ? '' : this.parentRoute.id,
          customId,
        ])

Related code: https://github.com/TanStack/router/blob/main/packages/react-router/src/route.ts#L1032

  1. During the first initialization of the router, everything is fine because it fall back to the path, and the path doesn't contain a prefix from parent.

  2. When we preload the route, the lazy route's options will be assign to the primary route object, so that the primary route object now has an id in its options property. Related code: https://github.com/TanStack/router/blob/main/packages/react-router/src/router.ts#L2247

  3. Now we call router.buildRouteTree() to manually rebuild it, now the customId will be /_protected/test, and we are joining it with parent's id again, so we get /_protected/_protected/test.

I believe we should trim the parant prefix when using options.id as customId

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

No branches or pull requests

1 participant