Photo by Andrew Ruiz on Unsplash

Angular with clean URL’s using Apache’s mod_rewrite

In Angular you have a really nice router which takes care of all the things you need. Prefetching data, guarding specific routes and it will even lazy load modules. That all works out of the box, which I think is really awesome.

When you are using Apache to serve your public/production environment you want to have beautiful clean URL’s, for example ‘whatwhat.app/page/3’. You need some additional configuration to make sure Angular’s routing also kicks in when people visit those pages directly and not coming through the index/homepage.

By default you will get a 404 page, because that file is not physically on the server. With mod_rewrite you can adjust this behavior in Apache, if that module is turned on (which is often the case). Configuration for Apache can be changed per folder using .htaccess.

Apache’s mod_rewrite and .htaccess

Just copy the configuration below and drop it in a file named .htaccess in the same folder containing your index.html file. That's it!

# Check if mod_rewrite module is available
<IfModule mod_rewrite.c>

# Turn the rewrite engine on and set URI base
RewriteEngine On
RewriteBase /

# Serve files when they are found
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]

# When file is not found, serve index.html instead
RewriteRule ^ /index.html

</IfModule>

Optional: Run your Angular app from a sub directory

You need some additional configuration for this, because Angular needs to know the path above it. The easiest way is to add a base tag in the <head> tag of the index.html like this: <base href="/app/path/">. Where the path should be adjusted to match yours of course, make sure it is the path above your Angular app (which should be ignored).

Another way is to inject it, that can be easier if you have different configurations per environment (ex. dev/acc/prod). You can find more information in the documentation of Angular APP_BASE_HREF.

When using a sub directory also change that in your .htaccess like this:

  • RewriteBase / should change to RewriteBase /app/path/.
  • RewriteRule ^ /index.html should be RewriteRule ^ /app/path/index.html.
  • Make sure the .htaccess file is in the same directory as Angular's index.html.

What mod_rewrite will do for Angular

For this of you who want a little background information about what is happening.

What Apache does is serving files to your visitors when they ask for it. In the case of a homepage like ‘whatwhat.app’ it will serve the index.html. With the configuration from the .htaccess it will change a bit:

  • When a file is found Apache will serve that to your visitor, which will make sure assets like js, css and images can be loaded. That also includes your Angular project. That is done with the RewriteCond and RewriteRule. Which will just use the URI from the request.
  • After that there is another RewriteRule as fallback and is only executed when a file is not found. It changes any URI to /index.html. Which makes Apache look for the index.html file and serve that instead. In that case your Angular app is served to your visitor.
  • That is exactly what you want because when you move from ‘whatwhat.app/’ to ‘whatwhat.app/page/3’ Angular will do the work, but if you visit ‘whatwhat.app/page/3’ right away Apache will try to find it. Which it can’t. By serving your app instead, the Angular router will get loaded and take over and resolve it afterwards.
  • Any 404 page is a route that can’t by found by the Angular router, which should also show an error page. That is up to you.

Even more possibilities

You can use hashtags routing too, which won’t be send to the server. That is an alternative in some cases and it can be good for security too (if you have params you don’t want to send to the server). I will probably write about this in a separate article as well.

Also using Angular’s i18n and want some clean URL’s? I have written an article called Serve Angular i18n with clean URL’s using Apache’s mod_rewrite. To make translating Angular apps itself really easy you might like a tool I have made called What?!.

I am working on articles for other webservers and CDN’s too, follow me on Medium to keep an eye out on those. Any tips or questions? Reach out to me in the comments or on Twitter. Thanks for reading!

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Tim etc.

Tim etc.

Creator of digital things. JavaScript Consultant at Passionate People.