#StackBounty: #.htaccess #nginx #url-rewriting #angular-ui-router #pretty-urls Handle the MEAN-stack application address without fragme…

Bounty: 50

I develop in Mac with Apache a MEAN-stack application that can be requested by
https://localhost:3000/#/home. In production with an NGINX server, the application can be requested by
https://www.myapp.io/#/home. The fragment-identifier # is needed in all cases because of angular ui-router.

So I wanted to make pretty url without # (eg, https://www.myapp.io/home, https://localhost:3000/home) work. I have done the following:

  1. added $locationProvider.html5Mode(true); $locationProvider.hashPrefix('') in app.config(['$stateProvider'....

  2. added <base href="/" /> in index.html

As a result, https://localhost:3000/#/home changes automatically to https://localhost:3000/home in the browser bar, similarly for https://www.myapp.io/#/home.

However, directly entering https://localhost:3000/home or https://www.myapp.io/home in the browser will raise an error (I don’t know how to turn previous <h1><%= message %></h1><h2><%= error.status %></h2><pre><%= error.stack %></pre> in error.ejs to error.html, so I don’t have more details).

So now, the goal is to make https://localhost:3000/home and https://www.myapp.io/home work.

By following this thread, I added the follows to app.js:

app.use('/js', express.static(__dirname + '/js'));
app.use('/dist', express.static(__dirname + '/../dist'));
app.use('/css', express.static(__dirname + '/css'));
app.use('/partials', express.static(__dirname + '/partials'));    
app.all('/*', function(req, res, next) {
    res.sendFile('index.html', { root: __dirname });

And in Apache of Mac, here is my httpd-vhosts.conf, after restarting apache,
https://localhost:3000/home still returns an error.

<VirtualHost *:443>
    ServerName localhost
    DocumentRoot "/Users/SoftTimur"

    SSLEngine on
    SSLCertificateFile /etc/apache2/ssl/localhost.crt
    SSLCertificateKeyFile /etc/apache2/ssl/localhost.key

    <Directory "/Users/SoftTimur">
        RewriteEngine on

        # Don't rewrite files or directories
        RewriteCond %{REQUEST_FILENAME} -f [OR]
        RewriteCond %{REQUEST_FILENAME} -d
        RewriteRule ^ - [L]

        # Rewrite everything else to index.html to allow html5 state links
        RewriteRule ^ index.html [L]

        Options Indexes FollowSymLinks
        AllowOverride All
        Order allow,deny
        Allow from all
        Require all granted

In production, here is the NGINX server block. After restarting NGINX, https://www.myapp.io/home still returns an error.

server {
    listen 443 ssl;

    server_name myapp.io www.myapp.io;

    ssl_certificate /etc/letsencrypt/live/myapp.io/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/myapp.io/privkey.pem;

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;
    ssl_dhparam /etc/ssl/certs/dhparam.pem;
    ssl_session_timeout 1d;
    ssl_stapling on;
    ssl_stapling_verify on;
    add_header Strict-Transport-Security max-age=15768000;

    index index.html;

    root /opt/myapp;

    location / {
        try_files $uri $uri/ /index.html;

    location ~ /.well-known {
        allow all;

    location / {
        proxy_set_header    Host                $host;
        proxy_set_header    X-Forwarded-For     $proxy_add_x_forwarded_for;
        proxy_set_header    X-Forwarded-Proto   $scheme;
        proxy_set_header    Accept-Encoding     "";
        proxy_set_header    Proxy               "";

        # These three lines added as per https://github.com/socketio/socket.io/issues/1942 to remove sock$

        proxy_http_version 1.1;
        proxy_set_header   Upgrade $http_upgrade;
        proxy_set_header   Connection "upgrade";

Could anyone help?

Get this bounty!!!

Leave a Reply