angularproxy

Angular 19 Proxy Not Affecting URLs on Http Client Calls


I am at my wit's end with this. I am using Angular 19 with a pretty simple frontend. I'm trying to call my backend using a proxy.

I know for a fact my API can be accessed at https://localhost:32771/api/, it works fine in browser, but my proxy isn't affecting my calls.

When I make a call, such as this:

this.http.post(`${this.apiUrl}/LoginInformation/authenticate`, loginData, { withCredentials: true })

(with apiUrl = "/api")

The network tab shows that localhost:4200 is being queried regardless.

Here is my proxy.conf.json:

{
  "/api": {
    "target": "https://localhost:32771", // Your backend server URL
    "secure": false, // Set to true if you're using HTTPS
    "changeOrigin": true,
    "logLevel": "debug" // Optional: for debugging proxy
  }
}

And the relevant portion of my angular.json:

"serve": {
  "builder": "@angular-devkit/build-angular:dev-server",
  "options": {
    "proxyConfig": "proxy.conf.json"
  },
  "configurations": {
    "production": {
      "buildTarget": "rubble_rousers:build:production"
    },
    "development": {
      "buildTarget": "rubble_rousers:build:development"
    }
  },
  "defaultConfiguration": "development"
},

I have tried adding extra asterisks to the path, as some other answers have suggested (How to configure proxy with Angular 18) but without any effect

I've also tried manually forcing it with the --proxy-config flag in the command line, but nada

What could I possibly be doing wrong? I've tried every way I can find online to fix this, but the proxy just isn't having any effect.


Solution

  • Please use the pathRewrite to remove the API part, so that it calls the API properly.

    {
      "/api/**": {
        "target": "https://localhost:32771",
        "secure": false,
        "changeOrigin": true,
        "logLevel": "debug",
        "pathRewrite": {
          "^/api": ""
        }
      }
    }
    

    Then we can trigger the API like:

    @Component({
      selector: 'app-root',
      imports: [RouterOutlet],
      templateUrl: './app.component.html',
      styleUrl: './app.component.scss',
    })
    export class AppComponent {
      title = 'test';
      http = inject(HttpClient);
    
      ngOnInit() {
        this.http.post(`/api/posts`, { "id": "2", "title": "a title 2", "views": 1001 }).subscribe();
      }
    }
    

    Full Angular.json:

    {
      "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
      "version": 1,
      "newProjectRoot": "projects",
      "projects": {
        "test": {
          "projectType": "application",
          "schematics": {
            "@schematics/angular:component": {
              "style": "scss"
            }
          },
          "root": "",
          "sourceRoot": "src",
          "prefix": "app",
          "architect": {
            "build": {
              "builder": "@angular-devkit/build-angular:application",
              "options": {
                "outputPath": "dist/test",
                "index": "src/index.html",
                "browser": "src/main.ts",
                "polyfills": ["zone.js"],
                "tsConfig": "tsconfig.app.json",
                "inlineStyleLanguage": "scss",
                "assets": [
                  {
                    "glob": "**/*",
                    "input": "public"
                  }
                ],
                "styles": ["src/styles.scss"],
                "scripts": []
              },
              "configurations": {
                "production": {
                  "budgets": [
                    {
                      "type": "initial",
                      "maximumWarning": "500kB",
                      "maximumError": "1MB"
                    },
                    {
                      "type": "anyComponentStyle",
                      "maximumWarning": "4kB",
                      "maximumError": "8kB"
                    }
                  ],
                  "outputHashing": "all"
                },
                "development": {
                  "optimization": false,
                  "extractLicenses": false,
                  "sourceMap": true
                }
              },
              "defaultConfiguration": "production"
            },
            "serve": {
              "builder": "@angular-devkit/build-angular:dev-server",
              "options": {
                "proxyConfig": "proxy.conf.json"
              },
              "configurations": {
                "production": {
                  "buildTarget": "test:build:production"
                },
                "development": {
                  "buildTarget": "test:build:development"
                }
              },
              "defaultConfiguration": "development"
            },
            "extract-i18n": {
              "builder": "@angular-devkit/build-angular:extract-i18n"
            },
            "test": {
              "builder": "@angular-devkit/build-angular:karma",
              "options": {
                "polyfills": ["zone.js", "zone.js/testing"],
                "tsConfig": "tsconfig.spec.json",
                "inlineStyleLanguage": "scss",
                "assets": [
                  {
                    "glob": "**/*",
                    "input": "public"
                  }
                ],
                "styles": ["src/styles.scss"],
                "scripts": []
              }
            }
          }
        }
      }
    }
    

    steps:

    1. Install inside backend and run npx json-server test.json.
    2. cd test -> npm i -> npm run start

    Stackblitz Demo