Menu

Fix 404 Errors from Angular Projects Hosted on Github Pages

March 7, 2017 by Christopher Sherman

This is part two of a three part series on deploying Angular CLI projects to Github Pages. To view part one, visit deploy an Angular project to Github Pages.

If you deploy an Angular project to Github Pages, you may notice that refreshing or navigating directly to a view other than the base domain redirects you to Github’s 404.html page. This is somewhat unavoidable since Github Pages is simply looking for a directory with a corresponding HTML file. For example, a request to http://dcvolunteer.com/opportunities/habitat-for-humanity will search for a habitat-for-humanity.html file located within the opportunities directory.

As a workaround, we add our own 404.html and cache the URL of the requested view. Once the view is cached, we then redirect to the base domain where the application is bootstrapped. From the base domain, we write a quick script to have Angular serve the requested view once the application bootstraps. This way, the user never gets stuck on the 404 page.

To accomplish the redirect, create a file named 404.html in the /src directory of the angular-cli application. In this file, we write a script to save, in session storage, the URL that generated the 404 error.

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="utf-8" />

  <title>Match your application's title</title>

  <script>
    // Store the URL the user was trying to access when receiving the 404.
    sessionStorage.redirect = location.href;
  </script>

  <!-- Immediately redirect to the base URL so we can use the SPA routing. -->
  <meta http-equiv="refresh" content="0;URL='/'"></meta>
</head>

<body>
<!-- IE required at least 512 bytes of data to show non-default 404. -->
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</body>    
            
             
</body>

</html>

In the /src/index.html file of the application, add the following script after the opening body tag. This script checks for a cached redirect URL in session storage, adjusts the URL via HTML5 history if one is found, and, finally, removes the cached URL from session storage.

<!-- Github Pages hack to allow SPA refresh without receiving 404. -->
  <script>
    (function () {
      // Retrieve the URL the user was trying to access when receiving the 404.
      var redirect = sessionStorage.redirect;
      // Remove the URL from sessionStorage.
      delete sessionStorage.redirect;
      // Check if we actually need to redirect.
      if (redirect && redirect != location.href) {
        // We need to redirect to the URL the user was trying to access.
        history.replaceState(null, null, redirect);
      }
    })();
  </script>
<!-- /Github Pages hack. -->

Next, in the angular-cli.json file, modify the assets entry to look like the following:

"assets": [
"assets",
"favicon.ico",
"404.html"
]

This configuration tells Angular CLI to copy these files to the /dist directory of the project when it builds.

With this hack, users can refresh as well as navigate directly to views without landing on the Github Pages 404 page. Credit to Daniel Buchner for coming up with this clever hack.

Angular