Troubleshooting: Angular Routing Issue causing 404 Error on GitHub Pages

After successfully implementing routing in my Angular app hosted on GitHub pages, I encountered an issue where the routing only worked partially. The setup followed the instructions from the routing documentation, as seen in my app-routing.module.ts file below:

const routes: Routes = [
  {
    path: 'research',
    component: ResearchPageComponent
  },
  {
    path: 'publications',
    component: PublicationsPageComponent
  },
  // ... more routes defined here ...
  {
    path: '',
    component: HomePageComponent
  }
];

While the routing functioned flawlessly on localhost://, issues arose when accessing the app on GitHub pages:

  • Clicking menu links on the homepage: works perfectly.
  • Navigating directly to the home page via URL: works perfectly.
  • Refreshing the home page: works perfectly.
  • Directly navigating to other pages via URL: 404 error.
  • Attempting to refresh other pages (after using the menu link): 404 error.

Why does the application perform as expected locally but experience issues on GitHub pages?

Despite checking for correct relative links and considering switching to hash routing based on recommendations, I prefer to stick with URL routes for their simplicity and memorability due to it being a personal website/resume/portfolio.

Answer №1

The Solution

If you're struggling to deploy your Angular 7 app to GitHub pages, look no further than this helpful thread. It appears that the issue lies in the order of operations when it comes to routing in Angular. The official documentation touches on this in its section "Deploying to GitHub Pages", although it may not be explained as clearly as needed. In summary, you need to create a custom 404 error page (named 404.html) that mirrors your compiled Angular root page, and place it in the output folder (e.g., /docs) after compiling your Angular app. Do not put it in your source code folder; otherwise, the Angular compiler won't generate the necessary output for this workaround to function properly.

While there are more sophisticated solutions for other web hosting platforms, they aren't accessible on GitHub pages due to restrictions.

The Breakdown

Curious about why this issue occurs? Let's delve into the explanation:

Essentially, your Angular router operates within the root of your Angular application, activating once your app initializes. Your Angular app itself resides on the main page of your site.

Typically, when you request a URL, the server delivers the corresponding page. However, Angular is "single-page", meaning the additional "pages" defined by routes do not actually exist. Instead, Angular dynamically switches content within your app to simulate different "pages". These routes simply map which content should replace the current view depending on the URLs received by the Angular router. This distinction is crucial and ties back to the sequence of events.

When you access your app's root page, the server returns that page before the Angular app and router commence their processes. To handle any routed URLs, the Angular router must already be operational. Thus, initiating from the homepage first and then navigating via links succeeds because the server sent the root page, enabling the Angular router to intercept navigation requests post-startup. Nonetheless, requesting routed URLs directly from the server (including through a refresh) triggers a 404 error since those "pages" aren't tangible and aren't returned by the server.

The workaround addresses this limitation by ensuring the Angular router initializes consistently. By duplicating your home page as the 404 error page, you provide the server with an actual page to serve on encountering a 404 error. Consequently, any requested route will return either your genuine homepage or the duplicated 404 error page (mirroring the home page), guaranteeing the Angular router's activation and seamless navigation between "pages."

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Trouble with combineLatest and ngrx remaining stagnant amidst changes

I'm facing an issue with the code below: this._loadingStateSubscription = combineLatest( select(fromTreeSelector.selectLoadingState), select(fromFinanceSelector.selectLoadingState), (isTreeLoading, isFinanceLoading) => { ...

Angular 2/NPM: setting up a new directory with all the necessary files for running the application

I'm feeling a bit frustrated, but I'm giving it a shot anyway. Our goal is to create a TypeScript Angular 2 hello world app that we can use as the front end for a Spring app. Currently, we're using the Angular 2 quickstart as our foundation ...

Is there anyone who can provide guidance on troubleshooting the HttpClient injection error (No provider for http_HttpClient) within an AngularJS/Angular hybrid application?

I've encountered an issue with my hybrid AngularJS/Angular app where the HttpClient module fails to inject (specifically, it shows "No provider for http_HttpClient" error). Interestingly, the deprecated @angular/http module works without any problems. ...

Leverage the power of Firebase Firestore by seamlessly integrating full-text search capabilities with external services while also

While I understand that using external services like Algolia and Elasticsearch is necessary for full-text queries in Firestore, my struggle lies in integrating these tools with Firestore's existing querying options such as "where," "limit," and "start ...

Error Encountered in Kendo UI Angular: (SystemJS) HTML Syntax Error Detected

I am currently working on a project using VS2015 RC3, Angular2 2.0.0 within an ASP.NET Core solution hosted on IIS. When attempting to incorporate new UI modules like dropdowns or inputs, I keep encountering a SystemJS error. However, strangely enough, my ...

What is the process for developing an Angular package that contains a collection of reusable pages and routes?

Is it possible to create Angular packages as a comprehensive reusable set of pages? If so, what is the fundamental way/architecture to implement it? Imagine having an Angular app and installing an npm package '@myuilibrary/account'. Suddenly, 11 ...

In TypeScript, the 'fs' module can be imported using the syntax `import * as fs from "

import * as fs from "fs"; const image1 = Media.addImage(document, fs.readFileSync("new.png")); Here is the configuration from my tsconfig.json: "compileOnSave": false, "compilerOptions": { "importHelpers": true, "outDir": "./dist/out-tsc", ...

What is the best way to retrieve the final entry from a JSON file while using json server with Angular?

I'm currently working with a JSON file where I am making post requests followed by get requests. My goal is to retrieve the latest record in each get request after submitting a post request. For example: [ { "id": 1, "title&qu ...

What is the function of the OmitThisParameter in TypeScript when referencing ES5 definitions?

I came across this specific type in the ES5 definitions for TypeScript and was intrigued by its purpose as the description provided seemed quite vague. /** * Removes the 'this' parameter from a function type. */ type OmitThisParameter<T> ...

Ag-Grid is displaying a third column that is not present in my dataset

Recently, I've been working with Angular and incorporating the Ag-Grid into my project. My goal is to display a grid with two columns; however, upon implementation, an unexpected third separator appears as if there are three columns in total. https: ...

Child route CanActivate guards execute before the parent Resolve completes

I'm currently facing an issue with resolving data prior to navigating to child routes in order to utilize that data within the children guard. The problem lies in the fact that the parent resolver is executing after the child guard has already been tr ...

Tips for calculating the total sum of inner object property values using JavaScript, TypeScript, or Angular 5

What is the total sum of successCount values in the given array object? var successCount;//I want count of all successCount attributes from the below object var accordianData = [ { name: "Start of Day", subItemsData: [ { title: " ...

Is there a way to confirm that a method was invoked using the internal testing framework?

Currently, I am utilizing the The Intern test framework to test my web application. My current challenge is verifying whether a method has been called during a test. I have searched for resources that demonstrate how this can be achieved using tools like ...

Unpacking arguments in Typescript functions

I have a function to update todo items in the database, like this: async function update({id, ...todoInfo }: ITodo) { const db = await makeDb() const foundTodo = await db.collection('todos').updateOne({ _id: transformId(id) }, { $set: { . ...

react-router: The 'history' type is not found in the current context

Here is some code snippet from App.tsx: interface AppProps{ history: any } export default class App extends React.Component<AppProps,...> { public state = { target: this.props.history.push('/') }; private route() { if (! ...

How to Fix TypeScript React JS Lint Error: Missing Dependency in React Hook useEffect without Disabling Lint or Adding Additional Dependencies

As I build a Web application using React JS and TypeScript with React hooks, I encountered a warning when utilizing a custom hook in my Component. The warning states that the dependency 'productsHook' is missing in the useEffect hook. One way to ...

Exploring ngAfterViewInit and ngAfterContentChecked

This question pertains to a common issue raised on StackOverflow multiple times. In essence, when you encounter a scenario such as: @Component({ selector: 'my-app', template: `<div>I'm {{message}} </div>`, }) export class A ...

Utilizing PrimeNG's p-dataView feature without repetitive FieldSets

Currently, I am utilizing p-dataView and I'm interested in implementing p-fieldset based on the application type. My goal is to prevent the fieldset from being duplicated when multiple instances occur. The scenario below illustrates one such case; how ...

Visual Studio - TypeScript project synchronization issue

Currently using the 2015 version of Visual Studio Community, I am facing an issue while working on a typescript project. Whenever I make modifications to the code, debug it, and save it using ctrl + s followed by refreshing the browser with ctrl + r, the c ...

Managing simultaneous asynchronous updates to the local state

There is a scenario where a series of asynchronous calls are made that read from a local state S, perform certain computations based on its current value, and return an updated value of the local state S'. All these operations occur at runtime, with ...