Encountering a 404 error with Angular 6 routing after refreshing the page when using an Nginx proxy

I currently have my angular application running within a docker container, exposed on port 83. Additionally, I have a separate spring-boot rest app running inside another docker container, exposed on port 8083.

On the host server, there is an Nginx server configured to reroute all requests using the following configuration:

server {
    listen 80;
    server_name mydomain.com;

    location / {
        proxy_pass http://127.0.0.1:83;
    }
}

server {
    listen 80;
    server_name rest.mydomain.com;

    location / {
        proxy_pass http://127.0.0.1:8083;
    }
}

According to this configuration, any request using mydomain.com will be directed to my Angular 6 app, while requests using rest.mydomain.com will be directed to my spring-boot rest app.

The index page of my angular app features a search form that triggers the Routing module to open a search result page.

The content of my app-routing.module.ts file is as follows:

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { HomePgComponent } from './home-pg/home-pg.component';
import { ResultsPgComponent } from './results-pg/results-pg.component';

const routes: Routes = [
  { path: "", component: HomePgComponent },
  { path: "search", component: ResultsPgComponent }
];

@NgModule({
  imports: [RouterModule.forRoot(
    routes,
    { enableTracing: true }
  )],
  exports: [
    RouterModule
  ]
})
export class AppRoutingModule { }
export const RoutingComponents = [
  HomePgComponent, 
  ResultsPgComponent
];

The trigger function on my search form looks like this:

onSearchBtnClk(el) {
    if (el.value.length > 0) {
      console.log(">>> SEARCH ARGS = " + el.value);
      this.router.navigate(['/search'], { queryParams: { q: el.value }});
      this.newArgsEmitter.emit(el.value);
    }
}

Currently, everything functions correctly - when I click the search button, my Angular app successfully opens the search result page and displays the results. However, I am encountering an issue when I click the REFRESH button in the browser. Instead of displaying the search page results, it shows a 404 error page. Why does this happen?

Any advice or insight would be greatly appreciated. Thank you.

Answer №1

To optimize your configuration, consider adding a try_files statement. However, keep in mind that using a proxy_pass can complicate matters. Here is one possible approach:

server {
    listen 80;
    server_name mydomain.com;
    try_files $uri $uri/ /index.html @proxy;    

    location @proxy {
      proxy_pass http://127.0.0.1:83;
    }
}

The use of the “@” prefix denotes a named location for request redirection rather than regular request processing. Remember that named locations cannot be nested or contain nested locations.

Explore further

Answer №2

The reason behind this is due to the nature of an Angular app being a single page application (SPA).

Whenever you refresh the app, your nginx configuration must always serve up the index.html file.

For instance, if you refresh while on /some-path

nginx will defaultly search for a file named /some-path.html which does not exist.

To ensure that index.html is consistently served, adjustments need to be made to your nginx.conf file similar to this:

Nginx config for single page app with HTML5 App Cache

An extract from the recommended solution in the provided link is as follows:

root /files/whatever/public;
index index.html;

location / {
    try_files $uri /index.html =404;
}

# Redirect requests to "/auth" and "/api" to the designated server.
location ~ ^/(auth|api) {
    proxy_pass http://application_upstream;
    proxy_redirect off;
}

Furthermore, conduct a Google search on configuring Nginx to serve Single Page Applications for more information.

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

What approach provides the most effective way to navigate through an NPM Package?

I have an idea to enhance a particular open source NPM package. Although I understand the necessary steps, it would be incredibly beneficial to have the ability to debug the package while it is in operation. Is this achievable? ...

Obtain the JSON response from the servlet

Is there a way to get a JSON response from a servlet in JavaScript? I am using AJAX post to send data to the servlet. Here is my AJAX code $.ajax({ type: "POST", url: "formDelegationServlet", data: { ...

Modify radio button colors upon selection with a variety of colors

Looking to create Yes/No buttons that start with a default state of null and change color when pressed - green for yes, red for no. Check out this example code: <label class="formheading">Apparatus group is correct</label> <fieldset data-r ...

Learn how to integrate Bootstrap with Vue.js TreeView in this tutorial

If you're looking to create a treeview using Vue.js, the code structure would resemble something like this: HTML: <!-- item template --> <script type="text/x-template" id="item-template"> <li> <div ...

An error was encountered: "Uncaught SyntaxError: Unable to utilize import statement outside of a module in

I have come across the following code while learning React and trying to execute it. HTML <html> <head> <link href="index.css" rel="stylesheet"> </head> <body> <div id="r ...

Guide to accessing a method from a separate file with the help of an event bus

I'm working on CreateEntryStepper.vue where I have a button that needs to call a function in CreateEntryStepperImageUpload.vue when pressed. I understand that event busses need to be used, but I am unsure about what exactly needs to be passed and how ...

Ways to Toggle div Visibility for Elements with Identical Class Names on an Individual Basis

After searching for solutions on stackoverflow, I attempted to implement some answers provided by other users, but I'm still not achieving the desired outcome. In my website's about section, there are four different items. When a specific item&a ...

css: positioning images with overlap in a responsive layout

Two divs have been created with background images, both displaying the same image but in different colors - one grey and the other green. These images are waveforms. Initially, only the grey image (div1) is visible while the green image (div2) remains hid ...

Unusual trait of TrackballControls.target within the world of Three.js

My current project involves simulating a 3D distribution of galaxies. In this simulation, the galaxies are represented as points. question1.htm references galaxydata1.txt to calculate and load the galaxy positions: rawFile.open("GET", "galaxydata1.txt", ...

How to define an index signature in Typescript that includes both mandatory and optional keys

I am on a quest to discover a more refined approach for creating a type that permits certain keys of its index signature to be optional. Perhaps this is a scenario where generics would shine, but I have yet to unlock the solution. At present, my construc ...

Ensure that the first option in the Woocommerce 2 Variable Product Dropdown List always displays all available choices

I am currently working on a variable WooCommerce product that includes 2 drop-down select fields. The first field is for selecting the Type of Product (framed or unframed artwork) and the second field is for choosing the Size of Artwork. With the help of ...

What is the best method for returning the AJAX outcome to the JSP page?

Using AJAX, I am able to post data from my JSP page to my servlet. $.ajax({ url: 'myServlet?action=FEP', type: 'post', data: {machine: i, name: txt}, // where i and txt hold certain values success: f ...

When using nextjs, there is an issue that arises when attempting to define the property 'id' using context.params.id. This results in

Attempting to retrieve data from a JSON file (response.json) hosted on localhost:8000/response.json. Below is the code snippet from pages/test.js: import React from "react"; import Link from "next/link"; import Image from "next/ima ...

Identify the locality and apply it to the root module of Angular 2 by utilizing a provider

I am working on a function that detects the current locale and I need to set it in the root App module of Angular 2 using a provider so that I can access it in all other components. I understand that I can achieve this by following the code below: { pr ...

developing a multimedia player using HTML5

I'm attempting to create a dynamic video "collage" that showcases videos with different aspect ratios in a flexible grid layout. Each row should have videos of the same height, while filling up the horizontal space within a container. With known widt ...

"Embrace the power of Ajax and JSON with no regrets

function register() { hideshow('loading', 1); //error(0); $.ajax({ type: 'POST', dataType: 'json', url: 'submit.php', data: $('#regForm').serialize(), su ...

Tips for assigning a standard or custom value using JavaScript

What is the best way to automatically assign a value of 0 to my input field when the user leaves it blank? Should I use an if statement { } else { } ...

What is the process of overriding methods in a function-based component in React?

Overriding in a parent component works when it is a class-based component // Parent Button Class class Button extends React.Component { createLabel = () => { return <span>{this.props.label}</span>; }; render() { return <butt ...

I am looking for a way to hide email addresses using Regex in JavaScript

I'm looking for a way to hide an email address [email protected]=> [email protected] using JavaScript I attempted to use the /(?<=.{2}).(?=[^@]*?@)/ regex, but it is not functioning properly in Internet Explorer and Mozilla. I need a ...

Discovering the keycode for the GO button in JavascriptDiscovering the keycode

Can anyone help me figure out how to find the keycode for the GO button using Javascript in an Android browser? ...