Thank @RichN for his/her answer. I tried to improve/fix his/her answer and also make it compatible with react-router v6.4:
import { UNSAFE_RouteContext } from 'react-router-dom'
function usePathPattern () {
let lastRouteContext = useContext(UNSAFE_RouteContext)
while (lastRouteContext.outlet) lastRouteContext = lastRouteContext.outlet.props.routeContext
return lastRouteContext.matches
.map(({ route: { path } }) => path).filter(Boolean)
.join('/').replaceAll(/\/\*?\//g, '/')
}
Sample output:
/:localeCode/:orgName/iaas/:projectSlug/vms/:vmUid/*
Or:
return lastRouteContext.matches.reduce((patternPath, { route: { path } }) =>
patternPath + (path
? path.endsWith('*') ? path.slice(0, -1) : path.endsWith('/') ? path : path + '/'
: ''
), '')
Sample output:
/:localeCode/:orgName/iaas/:projectSlug/vms/:vmUid/
But ...
... if you (like me) need to know the pattern that matched until here (where usePathPattern() is used), NOT the full-pattern, then you don't need to traverse into route-context to find the last one (findLastNode in @RichN's answer).
So this would be enough:
const usePathPattern = () => useContext(UNSAFE_RouteContext).matches.reduce((patternPath, { route: { path } }) =>
patternPath + (path
? path.endsWith('*') ? path.slice(0, -1) : path.endsWith('/') ? path : path + '/'
: ''
), '')
Sample output:
# In a near-to-root component:
/:localeCode/:orgName/
# In a very nested component (for the same URL):
/:localeCode/:orgName/iaas/:projectSlug/vms/:vmUid/