Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Optimal .htaccess configuration for Angular 12, Angular 11, Angular 10, Angular 9, Angular 8, Angular 7, Angular 6, Angular 5 (and older) app in production incl. fix for the angular browser caching issue.

New generator

I created a new htaccess generator for angular apps that makes it easier for you to create the optimal htaccess file: https://julianpoemp.github.io/ngx-htaccess-generator/

The goal of this generator is to create the optimal .htaccess file for Angular apps easily. By default the generator creates an .htaccess file that solves the route redirection issue. To make it easier for you to I created a kind of interview mode with some questions. As an additional feature the generator supports adding exclusions for example if you have installed a blog in a subdirectory of your web application and more!

The generator 😁: https://julianpoemp.github.io/ngx-htaccess-generator/ The project: https://github.com/julianpoemp/ngx-htaccess-generator Place for issues and bug reports: https://github.com/julianpoemp/ngx-htaccess-generator/issues

@neesho7
Copy link

neesho7 commented Jun 9, 2021

Thanks @julianpoemp
This works like charm on my angular 11 app. Its just I had to place htaccess in dist/myfolder/htaccess.

@julianpoemp
Copy link
Author

julianpoemp commented Jun 9, 2021

Thank you so much guys! If you find any improvements feel free to contribute to the generator! :D

@rrakshita33
Copy link

rrakshita33 commented Aug 7, 2021

Hi, I want to run my Angular 8 app over Apache Tomcat server. But every time I reload then it returns 404 page not found. So, for that, I included the .htaccess file in the folder where my index.html is. But still, it doesn't work because maybe the mod_rewrite is not enabled. My request url is https://ip:port/sso/callback. On tomcat ../webapps/sso, where sso is the app folder which contains all the build files including index.html and .htaccess files. I have set base-href as /sso/ . Please help

@julianpoemp
Copy link
Author

julianpoemp commented Aug 7, 2021

@rrakshita33

Does your routing work in your local environment? (via npm start) If no, there is an issue with Angular routing.

What do the network entries say when trying to reload the app from https://ip:port/sso/callback? Look for the failed request and open its request header. What is the URL of its request header?

Your base-href should be correct if your app can be opened on https://ip:port/sso/. I assume that there is any custom server configuration that blocks the .htaccess from working.

Are .htaccess files enabled by the server?
Are there any other redirection rules?
Are you using more than one .htaccess files?

@rrakshita33
Copy link

rrakshita33 commented Aug 7, 2021

Does your routing work in your local environment? (via npm start) If no, there is an issue with Angular routing.- yes it works perfectly, I'm able to access each of the routes while I type in browser address bar
What do the network entries say when trying to reload the app from https://ip:port/sso/callback? Look for the failed request and open its request header. What is the URL of its request header? - the url of request header is https://ip:port/sso/callback, status 404
Your base-href should be correct if your app can be opened on https://ip:port/sso/. I assume that there is any custom server configuration that blocks the .htaccess from working. Since my app is deployed on tomcat and all the build files are placed inside /webapps/sso, I have set the base-href to /sso/. I'm not aware of any custom configuration on server
Are .htaccess files enabled by the server? - not sure. how shall I have to enable this?
Are there any other redirection rules? - no, it's simple angular routes, for login and callback mapped to corresponding components
Are you using more than one .htaccess files? - I created the .htaccess file referring yours and placed it inside /webapps/sso folder with index.html. In .htaccess , RewriteRule is ^ /sso/index.html

@julianpoemp
Copy link
Author

julianpoemp commented Aug 9, 2021

@rrakshita33 sorry for my late response.

Are .htaccess files enabled by the server? - not sure. how shall I have to enable this?

You need the "AllowOverride All" option in your apache configuration: https://help.ubuntu.com/community/EnablingUseOfApacheHtaccessFiles

Are you using Angular Universal?

It's quite difficult to find a solution without more information. If you like you can send me the URL of your app via Keybase (julian1412) and then I can have a look on it. Perhaps I can find something using the web dev tools.

@ajilijihad
Copy link

ajilijihad commented Oct 18, 2021

it's worked but why my backed wille be not worked

@ajilijihad
Copy link

ajilijihad commented Oct 18, 2021

please help me :(

@julianpoemp
Copy link
Author

julianpoemp commented Oct 18, 2021

@djbev please answer the following questions:

  1. Does the routing work on your local machine using npm start?

  2. Did you place the .htaccess file next to your index.html file of your Angular App?

  3. Did you correctly set the base-href Attribute?

  4. Does your webserver support .htaccess files? Nginx isn't supported and on Apache you have to set the following if you are using your own webserver. You don't have to set it if you are using webhosting.:

You need the "AllowOverride All" option in your apache configuration: https://help.ubuntu.com/community/EnablingUseOfApacheHtaccessFiles

@ajilijihad
Copy link

ajilijihad commented Oct 19, 2021

me be i know problem :/
my backed and fronted is in the same serveur so if redirection all page to index my backend well be not worked
so can you give me code rederiction to all page but not redirection to page Includes words "api"

@julianpoemp
Copy link
Author

julianpoemp commented Oct 19, 2021

@djbev

As far I can understand your "api" folder is next to your index.html of your Angular app? (so "inside" your app folder)

The generator has an option called "Do you want to exclude subdirectories?". Toggle this to "yes". Type in "api" into the textbox and click on the plus icon. This line is going to be added to the .htaccess code:

  # Excluded directories:
  RewriteRule ^api/?(.*) %{REQUEST_URI} [L,R=301]

This should solve your problem because requests to http://.../api are not going to be redirected to the index.html.

@realshoaib
Copy link

realshoaib commented Nov 9, 2021

Hi everyone and @julianpoemp. I need help regarding implementing the .htaccess file in my angular project which doesn't have the backend integration yet at all. That is why i can't make http headers to send the 'Cache-Control' header as i want it to. Like currently I'm working on the lighthouse optimization of the project where I need to cache the cacheable resources like images stylesheets and scripts in order to reduce round trip to the server again & again. Currently I'm getting 70+ resources that needs to be cached but I can't cache each single one seperately, so I decided to go with .htaccess way so that simply defining in one place and getting effect everywhere. The problem is, despite placing .htaccess file in root directory, I'm unable to see the desired effect i.e. cache control header is vanished.
Kindly help, Thanks in advance.

@julianpoemp
Copy link
Author

julianpoemp commented Nov 9, 2021

@realshoaib what does your .htaccess look like?

Do you know the .htaccess template from HTML Boilerplate? There is a section for caching. You can find it here:
https://github.com/h5bp/server-configs-apache/blob/a5893aa05178bf395099f8df1e7ef1a97eb5a924/dist/.htaccess#L1090

If you want to apply caching to specific files or folders, you can wrap it with <FilesMatch ...> the similar way I do in order to prevent Browser caching:

# Disable browser caching for all files that don't get a hash string by Angular.
<FilesMatch "^(?!.*\.([0-9a-z]{20})\.).*$">
  <IfModule mod_headers.c>
    FileETag None
    Header unset ETag
    Header unset Pragma
    Header unset Cache-Control
    Header unset Last-Modified
    Header set Pragma "no-cache"
    Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate"
    Header set Expires "Mon, 1 Jan 1900 00:00:00 GMT"
  </IfModule>

</FilesMatch>

In my case I prevent ressources from caching in order to force retrieving ressources from the server on every page reload. In your case you coud combine the caching by mime type with the FilesMatch tag, in order to cache ressource from a specific URI.

@realshoaib
Copy link

realshoaib commented Nov 10, 2021

@julianpoemp as i mentioned earlier in my post that my project doesn't possess any backend which is why i can't implement it onto the backend.

I'm trying to accomplish .htaccess implementation in Angular(on frontend) only.
Below is my .htaccess code:

## EXPIRES CACHING ##
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/jpg "access 1 year"
ExpiresByType image/jpeg "access 1 year"
ExpiresByType image/gif "access 1 year"
ExpiresByType image/png "access 1 year"
ExpiresByType text/css "access 1 month"
ExpiresByType application/pdf "access 1 month"
ExpiresByType application/javascript "access 1 month"
ExpiresByType application/x-javascript "access 1 month"
ExpiresByType application/x-shockwave-flash "access 1 month"
ExpiresByType image/x-icon "access 1 year"
ExpiresDefault "access 2 days"
</IfModule>
## EXPIRES CACHING ##

Kindly guide in this regard.

@julianpoemp
Copy link
Author

julianpoemp commented Nov 10, 2021

@realshoaib I think that your webserver Apache configuration does not allow the mod_expires.c in .htaccess files. Are you sure that you can't use the Cache-Controll header at all? Perhaps you can try the approach described here: https://serverfault.com/a/316330

@realshoaib
Copy link

realshoaib commented Nov 10, 2021

@julianpoemp brother, you're not getting my point at all. I've said I DON'T HAVE ANY WEBSERVER AT ALL. Did you got my point? I need to deal with .htaccess on the frontend side

@julianpoemp
Copy link
Author

julianpoemp commented Nov 10, 2021

@realshoaib you can't use .htaccess without any webserver. Your problem can't be solved without a webserver at all.

@realshoaib
Copy link

realshoaib commented Nov 16, 2021

@julianpoemp Thank you so much for guiding me in regard. I'll definitely be going with the webserver approach.

@UnoRing
Copy link

UnoRing commented Jan 7, 2022

Great job, thanks a lot for sharing!

@benzdouglas
Copy link

benzdouglas commented Mar 24, 2022

Hey Julian, thanks for creating this! It helped me to figure out how to set up an Angular install with a Lumen rest api in a subfolder. I do have one issue that maybe you can help with, and might be a good addition to the generator? I've tried to turn off the Indexes throughout my server but for some reason it still wants to display the index of the api folder. Lumen has it's endpoint in a sub-sub folder /api/public so instead of just ignoring the folder I am rewriting to that directory using:
RewriteRule ^api/(.*)$ /api/public/$1 [L]
And above everything I also added
Options -Indexes
(which I've also added in the apache2.conf file and the sites-available conf file, and for those I also have the +FollowSymLinks after Options).
It shows the index when I go to domain.com/api/ but not when I leave off the trailing / as in domain.com/api so I feel like this is just a small typo - or I'm just going about doing this in the complete wrong way! Any advice?

@julianpoemp
Copy link
Author

julianpoemp commented Mar 24, 2022

hi @benzdouglas, did you also try RewriteRule ^api/?(.*)$ /api/public/$1 [L] ?

@benzdouglas
Copy link

benzdouglas commented Mar 24, 2022

You're a genius! That looks to have worked, thanks! Would have taken me a long time to find that missing character

@MincDev
Copy link

MincDev commented Apr 21, 2022

This is awesome. Can you also make it do redirection to www? I had to add this manually, but would save me time if you had this as part of your generator :)

@julianpoemp
Copy link
Author

julianpoemp commented Apr 21, 2022

@MincDev nice idea! I'll add it asap 🙂

@julianpoemp
Copy link
Author

julianpoemp commented Aug 8, 2022

@MincDev I added an option for redirection to www :)

@MincDev
Copy link

MincDev commented Aug 8, 2022

@MincDev I added an option for redirection to www :)

Great stuff! Thanks @julianpoemp!

@Ronaldy-Alves
Copy link

Ronaldy-Alves commented Aug 29, 2022

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment