Elastic Beanstalk: remove hashbang urls from SPA - angularjs

I have an AngularJS app hosted using Elastic Beanstalk and I'd like to remove the hashbangs (#!) from urls, but am having trouble using config files to make the necessary modifications to the Apache server.
I have enabled html5mode in my angular app and I currently have the following config file in my .ebextensions directory
files:
"/etc/httpd/conf.d/wsgirewrite.conf":
mode: "000644"
owner: root
group: root
content: |
RewriteEngine On
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]
RewriteRule ^ /index.html
Everything works fine without the hashbangs until I reload the page and I get a 404 indicating that the rewrite rules aren't working.
If possible, I'd like to avoid any solutions that involve ssh, copying, and modifying one of the default configs as this will likely make maintenance a nightmare if AWS changes any defaults down the road

Hashbang is a fallback mechanism for older browsers, where HTML5 is not supported. Check illustration:
What you may be looking for is how to configure "pretty URLs" in AngularJS. Besides enabling HTML5 mode (which it seems you already did: $locationProvider.html5Mode(true)), you need to configure the <base href="/"> tag inside your <head>, specifying the base URL/target for all relative URLs in a document.
Note: the $location service will automatically fallback to the hashbang method for browsers that do not support the HTML5 History API.
By Angular's documentation, without #, the url looks much nicer, but it also requires server side rewrites. This is the httpd.conf example they have for Apache server:
<VirtualHost *:80>
ServerName my-app
DocumentRoot /path/to/app
<Directory /path/to/app>
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]
</Directory>
</VirtualHost>
Since you are working with Beanstalk, you need to config httpd.conf via ebextensions. Two options available for Apache:
To override the Elastic Beanstalk default Apache configuration completely, include a configuration in your source bundle at .ebextensions/httpd/conf/httpd.conf.
To extend the Elastic Beanstalk default Apache configuration, add .conf configuration files to a folder named .ebextensions/httpd/conf.d in your application source bundle (e.g. .ebextensions/httpd/conf.d/port5000.conf).
I would recommend the extension option.
References:
https://scotch.io/tutorials/pretty-urls-in-angularjs-removing-the-hashtag
https://github.com/angular-ui/ui-router/wiki/Frequently-Asked-Questions#how-to-configure-your-server-to-work-with-html5mode
https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/java-tomcat-proxy.html
https://docs.aws.amazon.com/pt_br/elasticbeanstalk/latest/dg/ebextensions.html

Related

Whats the best way for reactjs web app in production server

First, I planed deploy a reactjs website to production server by Apache.
But when I searched the thing in google, it showed me many way to serve a reactjs web app
For example:
Pm2, or just simple by using next start (i'm using nextjs)
So, is Pm2 or next start is good enough for production server.
or the traditional web http server (apache, nginx)
Many thanks
Personnally, I use a simple apache server which deserve react like this
DocumentRoot /www
<Directory "/www">
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]
</Directory>

React-router typed-url and refresh on tomcat, elastic beanstalk

There are a lot of questions about this topic which is that typed URL and refresh do not work when using react on production but I'm trying for a long time now and for some reason it does not work.
I'm using React with Spring boot and tomcat. I am using BrowserRouter for routing. I deploy the application on aws elastic beanstalk. When I deploy, I do the following:
run npm run build then copy the resulting files in build folder into webContent folder then export project as war file and deploy it to aws.
As I understood, the main solution for this is to server the index.html file for all requests and I tried the following to do that:
- add the following to /etc/httpd/conf/httpd.conf
<VirtualHost *:80>
DocumentRoot /var/lib/tomcat8/webapps/ROOT/
ServerName domain.elasticbeanstalk.com
AliasMatch ^/(.*)$ /var/lib/tomcat8/webapps/ROOT/index.html
<Directory "/var/lib/tomcat8/webapps/ROOT">
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
RewriteEngine On
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^/(.*)$ - [L]
RewriteRule ^/(.*)$ /index.html [L]
</Directory>
</VirtualHost>
From the questions I read, it is suggested to use /var/www/html but I did not get why. I tried to use it by copying everything from ROOT to it but also did not work.
I tried many variations to the code I put in the configuration file.
With the configuration, I get the error
SyntaxError: expected expression, got '<'.
On firefox, I get The script from “http://awsdomain.com/static/js/2.7322c0fb.chunk.js” was loaded even though its MIME type (“”) is not a valid JavaScript MIME type.
and on chrome I get same error but with css files and not js.
At this point, I assume the serving of index.html is working but there is another issue that the server is trying to parse some js or css files like html or text which would not work. In any case, I have no idea how to tell the browser to parse them in the right way and why is it parsing them with no errors in the normal way (without solving the routing issue)?
I tried to add type attribute to link and script tags in index.html but did not work.
There are many stuff I tired specially in the config files on aws instance but it would be hard to put it all here. I'm hoping from the comments to get the root of the problems and then I can give any missing information.
My problem is finally fixed.
The following is my final addition to the httpd.conf
<VirtualHost *:80>
DocumentRoot /var/lib/tomcat8/webapps/ROOT/
ServerName domain.elasticbeanstalk.com
<Directory /var/lib/tomcat8/webapps/ROOT>
Options FollowSymLinks MultiViews
AllowOverride All
Require all granted
DirectoryIndex index.html
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]
</IfModule>
</Directory>
</VirtualHost>
Also, it was annoying that dir_module was not included by default which is needed by DirectoryIndex. To include it, add LoadModule dir_module modules/mod_dir.so.

AngularJS HTML5 mode with UI Router on apache

I had turned on the html 5 mode on my angular(1.5.8) app a few days back with this code:
$locationProvider.html5Mode({enabled:true,requireBase:true}).hashPrefix('!');
Later I read configuring apache server for html5 mode with ui-router.
After doing these settings, I am facing 2 problems:
Browser reload, redirects to home page for every deep nested app link.
Any link coming from outside(via email) always redirects to the homepage.
I have played with
mod_rewrite as-in using <Directory>, FallbackResource on apache.
changing paths to assets in the index.html (using relative URI and full qualified URI)
adding/removing the base HTML tag. (trying options like '/', '<sitename>')
But I am yet to overcome these problems.
Here is the detailed setup on my localhost:
I am deploying to apache via Virtual Host(and not .htaccess).
My deployment directory is /Users/<name>/Sites/<sitename> (I am on mac OS)
My index.html in-parts is as follows:
<head>
<base href="/">
<!-- SPELLS 1-->
<script src="/js/jquery.min.js"></script>
<script src="/js/bootstrap.min.js"></script>
<script src="/js/angular.min.js"></script>
<!-- more scripts / css et al -->
</head>
My Apache(2.4.28) config is as follows:
<VirtualHost *:80>
ServerName <servername>
DocumentRoot "/Users/<name>/Sites/<sitename>"
#LogLevel debug
LogLevel debug rewrite:trace6
RewriteEngine on
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]
RewriteRule ^ index.html [L]
Options Indexes FollowSymLinks
Require all granted
</VirtualHost>
Can anyone help me with the exact setup?
I'm not a fan of theL flag unless you plan on rewriting the URL more than once (it only ends the current iteration, and the rewritten URL goes through the rules again). You don't need the Indexes option and the directory test unless you want Apache to do automatic listing of directory contents. Try this:
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
RewriteRule ^ index.html [END]

Html5 mode with Hashbang Route for direct url on pages

I'm using AngularJS for my Portfolio. I would like to make it compatible and crawled entirely by Googlebot. So, I tried to set the html5 mode in the config.
The '#' is now gone but I can't access to pages directly. Server send me a 404.
I'm using an Apache server. I normally configure my server to route request on index with the .htaccess.
My portfolio is already on a server My portfolio
You can see the code on my github Here
you need to configure your server so that it redirect all routing requests to angular...
read here
How to: Configure your server to work with html5Mode
in apache
<VirtualHost *:80>
ServerName my-app
DocumentRoot /path/to/app
<Directory /path/to/app>
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]
</Directory>
</VirtualHost>

Configuring Apache to rewrite urls to index.html in root directory

My AngularJS application is using html5 mode for pretty urls. The urls on my local environment work but typing full urls directly into the browser causes my test server (set up on Heroku) to respond with 404 "Not Found" errors.
Examples:
1) Typing "localhost/log_in" or "localhost" directly into the browser results the login page.
2) Typing "localhost/fkjdlfdsaf" or any other url that begins with "localhost/" directly into my browser results in the login page.
3) Typing "myapplication.herokuapp.com" (test environment) directly into the browser also results in the login page.
4) Typing "myapplication.herokuapp.com/log_in" (test environment), however, incorrectly results in a 404 "Not Found" error.
It seems like the test environment server hasn't loaded [root dir]/index.html since the file contains scripts (including a route that serves the "login" page if the url doesn't match any other routes).
Can somebody tell me what I'm missing on my test server? I prefer solutions that modify the "httpd.conf" file over using a .htaccess file.
Snippet from httpd.conf on local server:
DocumentRoot "C:/Sites/myApplication"
<Directory "C:/Sites/myApplication">
Options Indexes FollowSymLinks Includes ExecCGI
AllowOverride All
Require all granted
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]
</Directory>
To configure web servers on Heroku, I created two files, procfile.txt (see this and this) as well as apache_app.conf (see this).
procfile.txt (heroku):
web: vendor/bin/heroku-php-apache2 -C apache_app.conf
apache_app.conf:
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]

Resources