Published: April 20, 2026 · 14 min read
Next.js Remote MFE: basePath and assetPrefix Guide
Your Next.js host application is running. You deploy two Next.js remote MFEs — Products and Content — to the same domain. Every route collides. The Products index page overwrites the Content index page. CSS files return 404. The basePath and assetPrefix configuration in Next.js remote micro frontends solves this — and getting it wrong is the most common reason Next.js remotes fail silently in production. In the previous article, you set up the host application with NextFederationPlugin. Now it is time to configure the remote side.
In this guide, you will:
- Understand why basePath and assetPrefix are required for Next.js remotes but not React remotes
- See the exact route and asset conflicts that happen without them
- Configure a Products remote and a Content remote with complete
next.config.jsfiles - Learn how the host resolves remoteEntry.js using the basePath in the URL
- Set up Nginx reverse proxy routing for Next.js remotes
- Deploy Next.js remotes as standalone Node.js servers

Why basePath and assetPrefix Are Required
When multiple Next.js applications run behind the same domain, every application thinks it owns the root path /. The host serves pages from /, the Products remote serves pages from /, the Content remote serves pages from / — all competing for the same URL space. This creates two distinct problems: route conflicts and asset conflicts.
basePath solves route conflicts. Setting basePath: '/products' in the Products remote tells Next.js to prefix every route with /products. The index page becomes /products/, API routes become /products/api/..., and internal navigation links automatically include the prefix.
assetPrefix solves asset conflicts. Setting assetPrefix: '/products' tells Next.js to prepend /products to every static asset URL in the generated HTML — JavaScript bundles, CSS files, images, and font files. Without it, the browser requests assets from /_next/static/... (root path), where Nginx routes traffic to the host app, not the Products remote.
basePath and assetPrefix must always match. If basePath is '/products' but assetPrefix is missing or different, pages load but every CSS, JavaScript, and image file returns 404. The page renders as unstyled HTML with no interactivity. This is the most common deployment bug with Next.js remote MFEs.
The basePath and assetPrefix Rule
These two settings solve different problems but must always have the same value in a micro frontend architecture. Here is every combination and what happens:
The rule is simple: set both, set them to the same value, and make sure your Nginx config routes that path prefix to the correct remote server.
Products Remote — Complete Configuration
The Products remote is a full Next.js application that exposes components to the host via NextFederationPlugin. It runs on port 5007 and uses basePath: '/products' to namespace all routes and assets under /products/.
Key configuration details:
basePath: '/products'+assetPrefix: '/products'— routes and assets namespaced to/products/output: 'standalone'— generates a self-contained build for Docker deploymentfilename: 'static/chunks/remoteEntry.js'— follows the Next.js asset convention (opens in a new tab), placing the remote entry alongside other chunkstranspilePackages— ensures monorepo shared packages (@myapp/store,@myapp/api,@myapp/seo) are compiled from sourceautomaticAsyncBoundary: true— wraps exposed modules in an async boundary, replacing the manualbootstrap.jspattern used in React MFEs
NEXT_PRIVATE_LOCAL_WEBPACK=true is required in every npm script — both for the remote and the host. Without it, Next.js uses its internal webpack build that does not expose the container plugin API, and Module Federation silently fails. See the host setup guide for details.
Content Remote — Complete Configuration
The Content remote serves legal and informational pages — FAQ, Terms and Conditions, Privacy Policy, and more. It runs on port 5006 with basePath: '/content'.
The Content remote follows the same pattern as Products — the only differences are the name, basePath, assetPrefix, port, and the components it exposes. The shared dependencies, extraOptions, and transpilePackages are identical. This consistency across remotes is intentional — it means every team follows the same configuration template.
Exposing Components from Remote MFEs
The exposes map in NextFederationPlugin defines which components the remote makes available to the host. The host imports these using the format import('RemoteName/ExposedKey').

Two important rules for the exposes map:
-
Expose components, not pages with side effects. If the exposed page imports
next/routerat the top level, it crashes when rendered inside the host because the router context belongs to the host, not the remote. Wrap the page in a component that handles its own routing internally. -
Keep exposed keys stable. Changing
'./ProductDetailPage'to'./ProductDetail'breaks every host that imports the old key. Treat exposed keys like a public API — rename them only with a migration plan.
How the Host Resolves Next.js Remotes
The host must include the remote's basePath in the remoteEntry.js URL. This is the critical link between the remote's basePath setting and the host's remotes configuration.
The URL structure for Next.js remotes is: domain + basePath + /_next/static/{ssr|chunks}/remoteEntry.js. Compare this to React remotes, which use: domain + publicPath + /remoteEntry.js.
For a deep dive into the isServer toggle and why Next.js remotes need two remote entry files, see the upcoming SSR vs CSR in Next.js Module Federation article.
Shared Dependencies — Matching the Host
The remote's shared configuration must match the host's shared configuration exactly. If the host shares react as a singleton with eager: false but the remote uses eager: true, the shared dependency negotiation fails — the remote bundles its own React copy, breaking singleton state and doubling the bundle size.
Key rules for shared dependencies in Next.js remotes:
| Setting | Value | Why |
|---|---|---|
singleton | true | Only one instance of React, Redux across all MFEs |
requiredVersion | false (core libs) | Let Next.js manage React version internally |
eager | false | Prevents SSR hydration mismatch errors |
strictVersion | true (internal packages) | Ensures exact version match for @myapp/store, @myapp/api |
requiredVersion | '1.0.0' (internal packages) | Matches the host's pinned version |
The remote does NOT include exposePages or enableImageLoaderFix in its extraOptions. Those options are host-only configurations. The remote only needs automaticAsyncBoundary: true to wrap its exposed modules for async loading.
Nginx Reverse Proxy for Next.js Remotes
Unlike React remotes (which produce static files served directly by Nginx), Next.js remotes run as standalone Node.js servers. Nginx acts as a reverse proxy, routing requests by path prefix to the correct backend.
The Nginx location blocks must match the basePath values exactly. When a browser requests https://myapp.com/products/_next/static/chunks/remoteEntry.js, Nginx matches the /products/ prefix and proxies the request to the Products server on port 5007. The Products server (with basePath: '/products') recognizes the request and serves the file.
Deploying Next.js Remotes as Standalone Servers
Each Next.js remote is built with output: 'standalone' and deployed as an independent Node.js server (opens in a new tab). This produces a lightweight, self-contained build (~150MB vs ~500MB without standalone).
The standalone server automatically respects the basePath configuration. Requesting http://localhost:5007/ returns 404 — only /products/ routes are served. This is the correct behavior and confirms that basePath is working.

Common Mistakes
-
Setting basePath but forgetting assetPrefix — Pages load as unstyled HTML. Every CSS and JS file returns 404 because the browser requests assets from
/_next/static/...instead of/products/_next/static/.... -
Using different values for basePath and assetPrefix — Nginx routes
/products/traffic to the remote, but the remote's HTML references assets at a different path. Nothing loads correctly. -
Forgetting basePath in the host's remote URL — Writing
Products@https://myapp.com/_next/static/chunks/remoteEntry.jsinstead ofProducts@https://myapp.com/products/_next/static/chunks/remoteEntry.js. The file does not exist at the root path. -
Missing
output: 'standalone'— Without standalone, the build requires the fullnode_modulesdirectory at runtime. Docker images become bloated and deployments fail when the production server lacks build-time dependencies. -
Using
eager: truein the remote — Even if the host useseager: false, one remote witheager: truecan cause hydration errors across the entire application because shared modules load synchronously before the host's hydration cycle completes. -
Not including the basePath in Nginx location blocks — If Nginx has
location /product/instead oflocation /products/, requests never reach the remote server. The host receives a 404 for the remote entry and silently falls back to the error state.
What's Next
You now have two Next.js remote MFEs properly configured with basePath and assetPrefix, exposing components to the host, and deployed as standalone Node.js servers behind Nginx. The next article explains how SSR vs CSR works in Next.js Module Federation — why NextFederationPlugin generates two remote entry files, what the isServer flag actually does during webpack compilation, and how hydration works when mixing server-rendered Next.js remotes with client-only React remotes.
← Back to Next.js MFE Host App Setup
Continue to SSR vs CSR in Next.js Module Federation →
Frequently Asked Questions
What does basePath do in a Next.js remote micro frontend?
basePath prefixes every route in the Next.js application with a path segment. Setting basePath: '/products' means the app's index page is served at /products/ instead of /. All internal links, API routes, and page navigation automatically include the prefix. This prevents route conflicts when multiple Next.js MFEs run on the same domain — each MFE owns its own URL namespace.
What does assetPrefix do in a Next.js remote micro frontend?
assetPrefix prefixes every static asset URL (JavaScript chunks, CSS files, images, fonts) generated by Next.js. Setting assetPrefix: '/products' changes asset requests from /_next/static/chunks/page.js to /products/_next/static/chunks/page.js. Without assetPrefix, the browser requests assets from the root path where Nginx routes traffic to the host app — not the remote — causing 404 errors for every asset.
Do basePath and assetPrefix need to be the same value?
Yes, in a micro frontend architecture they should always match. basePath controls where routes are served and assetPrefix controls where assets are loaded from. If basePath is '/products' but assetPrefix is different or missing, Nginx routes /products/ traffic to the remote but the remote requests assets from the wrong path. Mismatched values cause pages to load with no styles, broken JavaScript, and missing images.
Why don't React remotes need basePath and assetPrefix?
React remotes built with ModuleFederationPlugin use webpack's publicPath setting instead. Setting publicPath: '/auth/' in webpack.config.js tells webpack to load all chunks from the /auth/ path. React MFEs produce static files (HTML, JS, CSS) that Nginx serves directly from a directory. Next.js MFEs run a Node.js server and generate assets dynamically, which is why they need the Next.js-specific basePath and assetPrefix configuration.
What happens if you forget assetPrefix but set basePath?
The pages load because basePath routes correctly, but every CSS file, JavaScript chunk, and image returns 404. The HTML renders unstyled with broken interactivity. This happens because Next.js generates asset URLs like /_next/static/chunks/page.js (without the prefix), but Nginx sends all root-path requests to the host app. The remote's assets only exist at /products/_next/static/... which requires assetPrefix: '/products' to generate the correct URLs.
How does the host resolve remoteEntry.js for Next.js remotes with basePath?
The host includes the basePath in the remote entry URL. For a Products remote with basePath '/products', the host config is: Products@https://myapp.com/products/_next/static/chunks/remoteEntry.js. The basePath becomes part of the URL path between the domain and /_next/static/. The isServer ternary switches between chunks (browser) and ssr (Node.js) paths. React remotes without basePath use a simpler URL: Auth@https://myapp.com/auth/remoteEntry.js.