Reputation: 3401
Scenario:
I have a Vue2 SPA ready to replace a legacy LAMP website but PO would like to deploy it progressively (starting with just one single URL) to test user's reactions, analytics, ad revenue, etc.
We've built this architecture to allow this approach:
It works. So, if you go to http://example.com/release-first (let's say this is the page we want to release publicly in the first place) CF returns the content from the S3, and any other URL is fetched from the legacy server.
But, of course, when you access /release-first
you're in the SPA, and since most of the navigation is done with <router-link :to="">
, you're trapped in the SPA and you can access the rest of the new version, which we don't want at this point.
Possible solutions I thought:
One solution could be to replace all <router-link>
tags with standard <a>
links that would force the browser to do a new petition to the CloudFront every time. That might work but I'd prefer not to do it because I have to change a lot of links and also because links are not the only way the user can move around (there's some form submission too, etc.)
So, I tried something like:
router.beforeEach((to, from, next) => {
if (!/\/release-first\/?$/.test(to.path)) {
window.location.href = `http://example.com${to.path}`
return;
} else {
next();
}
});
This works fine in staging
env (because it has a different subdomain, so it's redirecting to production) but if I try in production it doesn't work. I don't know if Vue hijacks the Location API or what, but it doesn't force a new petition to the CloudFront.
I've also tried with:
const absolutePath = `http://example.com${to.path}`;
window.history.pushState({ urlPath: absolutePath }, "", absolutePath);
window.location.reload();
But it doesn't work either... and I couldn't find in vue-router
's Docs an option to force the page to reload on navigation. Any idea on how to achieve this?
Extra information requested in comments:
history
./
/single-level-pages
/two/level-pages
/two-levels-with/:param
/multiple/level/pages
/multiple/level/with/:param/
release-first
URL. The URL I wanna release in first place is like first-level-with/an-specific-param
.beforeEach
navigation guard works fine in staging too, so the only issue is that this in not enough when the domain is the same because the location.href
overwrite doesn't seem to force a new request when the destination is in the same domain.Upvotes: 3
Views: 1421
Reputation: 3401
This is how I finally solved it:
router.beforeEach((to, from, next) => {
if (
window.location.host === "prod-env.example.com" &&
/\/release-first/.test(from.path) &&
!/\/release-first/.test(to.path)
) {
let a = document.createElement("a");
a.id = "forceReloadLink";
a.href = to.path;
document.querySelector("body").appendChild(a);
document.getElementById("forceReloadLink").click();
} else {
next();
}
});
Upvotes: 2