I’m trying to serve two different versions of a single page application – one, built with a brand new, shiny JS framework, and another built with an older, crummier JS framework. All of the important features and functionality are in the new SPA, and all the non-critical in the older SPA and are in the midst of being ported over.
With this in mind, I’m trying to make the older SPA available via a path, e.g. /old-app
.
The new app resides in /www/new-app
.
The old app resides in /www/old-app
.
This is what I have tried:
server {
listen 443;
root /www/new-app;
index index.html;
location / { # default to new app
try_files $uri @prerender;
}
location /old-app {
root /www/old-app; # I have also tried *alias* instead of *root* here
index index.html;
try_files $uri @prerender;
}
location @prerender {
set $prerender = 0;
# a bunch of rules for prerender from here: https://gist.github.com/thoop/8165802
if ($prerender = 1) {
proxy_pass http://127.0.0.1:8080/$scheme://$host$request_uri;
}
if ($prerender = 0) {
rewrite .* /index.html break;
}
}
}
The above returns a 200 OK
for https://www.domain.example/old-app/<route>
, but the page served is not /www/old-app/index.html
. Instead, the file served is from /www/new-app/index.html
with a blank page, presumably because the new SPA does not understand the provided /<route>
, which only the old SPA understands.
2
Answers
While Richard's answer works and is probably more correct than mine, I ended up with the following config (before Richard had the chance to post his answer!) after a lot of trial and error. I'm posting it here for posterity, should anyone else have the same requirements as mine.
And finally, in the
index.html
of the old single page app, I added a<base href="/old-app/" />
to make sure any references to images, stylesheets etc. were served from the correct server path.Now, visiting
http://domain.example/old-app
correctly serves the default route of the old SPA!Two things are wrong here.
This will look for files at
/www/old-app/old-app
(see this document for details).This sends all of your routes to the
location @prerender
block, which ends withrewrite .* /index.html break;
There may be a more elegant solution, but you could just add a second "prerender" block, for example
location @oldrender
which is similar to the original, but ends withrewrite ^ /old-app/index.html last;
For example:
Notice the
root
has changed, and you need to userewrite...last
.