With vue-router 1.x, it was possible to see where a route had been redirected from using router.currentRoute.redirectedFrom. This was useful when server-side rendering, as you could send a 301 from the server instead of sending the HTML for the new page and then changing the URL on the client.
With 2.x, the property has gone and I can't find it anywhere. Has it been removed? If so, it would be great if it could come back!
Reason it was nice that it existed: https://github.com/vuejs/vue-router/issues/968
router.currentRoute.redirectedFrom === '/old-path'

Hahaha was I the only person using this? _nice._
Solution (in entry-server.js):
import { createApp } from './app';
export default context => new Promise((resolve, reject) => {
const { app, router, store } = createApp();
console.log(router.resolve(context.url).route); // object has redirectedFrom property
router.push(context.url);
router.onReady(() => { /* ... */ }, reject);
});
In case this helps anyone, after some digging I found that luckily when you push/replace a route, there is a pending property that gets set with that route:
On the server-side, in your entry-server, you can add router and fullPath to context. Something like:
// ...
const route = router.resolve(url).route
const { fullPath } = route;
if (fullPath !== url) {
return reject({ url: fullPath })
}
context.fullPath = fullPath;
context.router = router;
// set router's location
router.push(url)
// ...
That part doesn't handle the case of a redirect the app makes after loading data and trying to render.
To address that, back inside the server/express side where you call renderToString, you can detect those redirects and handle:
// ...
renderer.renderToString(context, (err, html) => {
if (err) {
return handleError(err)
}
const {pending} = context.router.history;
if (pending) {
if (pending.fullPath !== context.fullPath) {
console.log(`redirect ${context.fullPath} to ${pending.fullPath}`);
return res.redirect(301, pending.fullPath);
}
}
res.send(html)
});
// ...
Hope this helps! And if there is a better way, let me know.
@joenoon What do you mean by your solution? Caz if your url is not the same,
if (fullPath !== url) {
return reject({ url: fullPath })
}
it would directly reject the req and would not do the redirect any longer. As far as I am concerned, It should be solved in the handleError
@NoraGithub its a bit different case. the fullPath !== url is the easy one, where the router instantly knows it is a redirect.
The second one is harder, where async data is fetched, and a component ends up reacting to the data and decides to redirect instead. For example, when a user profile component is loaded, the component fetches the user but discovers the user no longer exists. The component does something like if (!user) this.$router.push('/').
Your component still likely rendered something, like an empty <div></div> etc. But the server side is now able to see the component is also trying to redirect.
router.currentRoute.redirectedFrom actually does exist in version 3: https://github.com/vuejs/vue-router/blob/effb1143db10376c4ed553aec9a909dd1430ef66/src/util/route.js#L32
To me this should not be a feature request but it's rather a documentation issue. With the hints from the comments above there could be a nice how-to.
in Vue Router 3 redirectedFrom only exists for records with a redirect option. In Vue Router 4, it will also exist for redirections made with navigation guards
Most helpful comment
Hahaha was I the only person using this? _nice._