redwood icon indicating copy to clipboard operation
redwood copied to clipboard

Feature request: `useCurrentRoute` or `useRouteName`

Open stephenhandley opened this issue 3 years ago • 2 comments

Creating issue based on this conversation on the forums.

It would be helpful to be able to get the currently matched route via a hook for use in generic page analytics and also for additional route-based logic needed in some component used across multiple pages.

Here's an example of the analytics use case, where I want to use the name of the current route to identify the page so I can use it in a hook in my top level App component in order to make calls to segment’s analytics.page function generically rather than having to do so by hand on each individual page.

function usePageAnalytics() {
  const analytics = useAnalytics()
  const location = useLocation()

  // name would be the same as the `name` key in Routes.tsx
  const name = useRouteName();
  const params = useParams()
 
  // alternatively could have this return the currently matched route and associated properties such as name, params, pattern, etc.
  const { name, params } = useCurrentRoute();

  useEffect(() => {
    analytics.page({name, properties: { location , params }})
  }, [location])
}

Here's an example approach I've taken in the past to give example of the returned object shape in case that's useful https://github.com/Hello10/groutcho/blob/master/packages/groutcho/src/MatchResult.js https://github.com/Hello10/groutcho/blob/master/packages/groutcho/src/Route.js#L60-L107

stephenhandley avatar Nov 30 '21 01:11 stephenhandley

If anyone wants to take this on here are some pointers

  • Keep the name of the current route in RouterContextProvider
  • In router.tsx on line 240ish when rendering <RouterContextProvider> you already have name, so just pass that as a prop to the context
  • There is already a useRouterState hook that could be used to access the name, but that's more for internal use. So I'd create a new hook that's nicer to use, like useRouteName(), for use in RW apps.

The biggest issue is how to type the return value of useRouteName(). The simple solution is to just type it as string, but we should be able to do better. We already analyse the user's Routes.tsx file to provide better types for the named routes functions in routes (i.e. as used in <Link to={routes.about()}>. We should be able to use something similar (maybe even the same code) to get types for useRouteName(). After figuring out how to generate the types the next issue is to get RouterContextProvider to know about them. Not really sure how to do that either.

Tobbe avatar Nov 30 '21 05:11 Tobbe

It seems that people tend to seek this functionality in order to track page views in a generic way. I now have this use case and was surprised to find there's no way to resolve the current route name. I haven't found evidence that there are any good workarounds either (other than adding manual tracking per page).

The simple solution is to just type it as string, but we should be able to do better.

Is this a blocker for implementing any solution at all here? The rest of the above suggests that just making the route name available via the context and a hook may be reasonably straightforward. I'm a fan of the suggested well-typed implementation, but is it worth not having such functionality at all in the meantime?

pvenable avatar Jul 21 '22 21:07 pvenable

If anyone here is still interested in this feature, take a look here and let me know what you think: #9758

Tobbe avatar Dec 26 '23 20:12 Tobbe