Here's the code I have to do this:
const matches = useMatches()
const navigate = useNavigate()
const navigateTo = useCallback(({ paramsOverrides }) => {
const lastMatch = matches[matches.length - 1]
const newParams = { ...lastMatch, ...paramsOverrides }
const newPathname = lastMatch.id.replaceAll(/\$([^\/]+)/g, (_, pathParam) => {
return newParams[pathParam]
})
navigate({ ...location, pathname: newPathname })
})
This seems like something the router should be able to do for me, but I can't find an API for it