1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.
  2. Anuncie Aqui
    Anuncie aqui você Também: fdantas@4each.com.br

How to properly set up basehref when working with Angular Native Federation?

Discussão em 'Angular' iniciado por Guilherme Taffarel, Julho 15, 2025.

  1. We are migrating a couple of Angular 17 applications to a Micro-Frontend architecture by using Native Federation, but there is still one issue I still couldn't solve, which is the app context for some files.

    The application in production runs at www.mydomain.com/app-context. For that to work, I had to change the path of the manifest file at main.ts to /app-context/assets/federation.manifest.json.

    In localhost, the app runs at localhost:4200 without the context by default, so that path wouldn't work. So then I set the basehref for localhost too, but the remoteEntry.json file is still being served at localhost:4200/remoteEntry.json, causing a 404.

    This is an issue I only have with the host app, because the mfe app doesn't have a manifest to watch at main.ts, solving the issue by sticking with not setting up the basehref for localhost.

    What am I missing here?

    I need either one of these to work:

    • Not having to add the context to the path in main.ts and it still work in production (preferable, if possible)
    • Have the context set up for localhost too, but have it work consistently
    main.ts


    import { initFederation } from '@angular-architects/native-federation';

    initFederation('/app-context/assets/federation.manifest.json')
    .catch(err => console.error(err))
    .then(_ => import('./bootstrap'))
    .catch(err => console.error(err));

    angular.json


    configurations dsv and local are the localhost configs.

    {
    "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
    "version": 1,
    "newProjectRoot": "projects",
    "projects": {
    "app-context": {
    "projectType": "application",
    "schematics": {
    "@schematics/angular:component": {
    "style": "scss"
    }
    },
    "root": "",
    "sourceRoot": "src",
    "prefix": "app",
    "architect": {
    "build": {
    "builder": "@angular-architects/native-federation:build",
    "options": {},
    "configurations": {
    "production": {
    "target": "app-context:esbuild:production"
    },
    "development": {
    "target": "app-context:esbuild:dsv",
    "dev": true
    }
    },
    "defaultConfiguration": "production"
    },
    "serve": {
    "builder": "@angular-architects/native-federation:build",
    "options": {
    "target": "app-context:serve-original:dsv",
    "rebuildDelay": 0,
    "dev": true,
    "port": 0
    }
    },
    "extract-i18n": {
    "builder": "@angular-devkit/build-angular:extract-i18n",
    "options": {
    "buildTarget": "app-context:build"
    }
    },
    "test": {
    "builder": "@angular-devkit/build-angular:karma",
    "options": {
    "polyfills": [
    "zone.js",
    "zone.js/testing"
    ],
    "tsConfig": "tsconfig.spec.json",
    "inlineStyleLanguage": "scss",
    "assets": [
    "src/favicon.ico",
    "src/assets"
    ],
    "styles": [
    "src/styles.scss"
    ],
    "scripts": []
    }
    },
    "esbuild": {
    "builder": "@angular-devkit/build-angular:application",
    "options": {
    "outputPath": "dist/app-context",
    "index": "src/index.html",
    "browser": "src/main.ts",
    "polyfills": [
    "zone.js",
    "es-module-shims"
    ],
    "baseHref": "/app-context/",
    "outputHashing": "all",
    "tsConfig": "tsconfig.app.json",
    "inlineStyleLanguage": "scss",
    "assets": [
    "src/favicon.ico",
    "src/assets"
    ],
    "styles": [
    "src/styles.scss",
    "node_modules/ngx-toastr/toastr.css"
    ],
    "stylePreprocessorOptions": {
    "includePaths": [
    "src/assets/scss"
    ]
    },
    "scripts": []
    },
    "configurations": {
    "production": {
    "fileReplacements": [
    {
    "replace": "src/environments/environment.ts",
    "with": "src/environments/environment.prod.ts"
    }
    ],
    "optimization": true,
    "baseHref": "/app-context/",
    "outputHashing": "all",
    "sourceMap": false,
    "extractLicenses": true,
    "budgets": [
    {
    "type": "initial",
    "maximumWarning": "2mb",
    "maximumError": "5mb"
    },
    {
    "type": "anyComponentStyle",
    "maximumWarning": "6kb",
    "maximumError": "10kb"
    }
    ]
    },
    "dsv": {
    "fileReplacements": [
    {
    "replace": "src/environments/environment.ts",
    "with": "src/environments/environment.dsv.ts"
    }
    ],
    "optimization": false,
    "baseHref": "/app-context/",
    "outputHashing": "none",
    "sourceMap": true,
    "extractLicenses": false,
    "budgets": [
    {
    "type": "initial",
    "maximumWarning": "2mb",
    "maximumError": "5mb"
    }
    ]
    },
    "local": {
    "optimization": false,
    "baseHref": "/app-context/",
    "outputHashing": "none",
    "sourceMap": true,
    "extractLicenses": false,
    "budgets": [
    {
    "type": "initial",
    "maximumWarning": "2mb",
    "maximumError": "5mb"
    }
    ]
    }
    },
    "defaultConfiguration": "production"
    },
    "serve-original": {
    "builder": "@angular-devkit/build-angular:dev-server",
    "configurations": {
    "production": {
    "buildTarget": "app-context:esbuild:production"
    },
    "dsv": {
    "buildTarget": "app-context:esbuild:dsv"
    },
    "local": {
    "buildTarget": "app-context:esbuild:local"
    }
    },
    "defaultConfiguration": "local",
    "options": {
    "port": 4200
    }
    }
    }
    }
    },
    "cli": {
    "analytics": false
    }
    }

    Continue reading...

Compartilhe esta Página