skip to Main Content

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


  1. Chosen as BEST ANSWER

    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.

    server {
      listen 443;
    
      root /www/new-app;
      index index.html;
    
      # I left the following alone
      location / {
        try_files $uri @prerender;
      }
    
      # Here's the meat of what worked
      location /old-app {
        alias /www/old-app;
        index index.html;
        try_files $uri $uri/ index.html;
      }
    }
    

    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!


  2. Two things are wrong here.

    location /old-app {
        root /www/old-app;
    

    This will look for files at /www/old-app/old-app (see this document for details).

    try_files $uri @prerender;
    

    This sends all of your routes to the location @prerender block, which ends with rewrite .* /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 with rewrite ^ /old-app/index.html last;

    For example:

    location /old-app {
        root /www;
        try_files $uri @oldrender;
    }
    location @oldrender {
        ...
            rewrite ^ /old-app/index.html last;
        ...
    }
    

    Notice the root has changed, and you need to use rewrite...last.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search