Configuration Basics
Add the routing configuration that tells Vercel which paths go to which apps.
Outcome
Configure microfrontends.json for routing and wrap each Next.js config with withMicrofrontends to prevent asset conflicts.
Two Configuration Files
Microfrontends require two types of configuration:
microfrontends.json- Defines routing (which paths go to which apps)next.config.tswrapper - Configures asset prefixes to prevent collisions
Fast Track
- Install
@vercel/microfrontendsin each app - Create
microfrontends.jsonin the marketing (default) app - Wrap each
next.config.tswithwithMicrofrontends
Hands-on Exercise 2.1
Configure the Acme Platform for microfrontends.
Part 1: Install the Package
Add @vercel/microfrontends to each application using pnpm's workspace filter:
pnpm add @vercel/microfrontends --filter acme-marketing
pnpm add @vercel/microfrontends --filter acme-docs
pnpm add @vercel/microfrontends --filter acme-dashboardThis installs the package in all three apps.
Part 2: Create microfrontends.json
Create apps/marketing/microfrontends.json:
{
"$schema": "https://openapi.vercel.sh/microfrontends.json",
"applications": {
"acme-marketing": {
"development": {
"fallback": "acme-marketing.vercel.app",
"local": 3000
}
},
"acme-docs": {
"routing": [
{
"paths": ["/docs", "/docs/:path*"]
}
],
"development": {
"local": 3001
}
},
"acme-dashboard": {
"routing": [
{
"paths": ["/app", "/app/:path*", "/settings", "/settings/:path*"]
}
],
"development": {
"local": 3002
}
}
}
}Each key under applications is a Vercel project name. We named the packages acme-marketing, acme-docs, and acme-dashboard back in Lesson 1.4, so every key matches both its package.json name and the project we'll create in Lesson 2.5.
If a package name ever drifts from its project name, keep the key as the project name and add packageName with the name from package.json:
"acme-docs": {
"packageName": "docs",
"routing": [{ "paths": ["/docs", "/docs/:path*"] }]
}The default app has no routing. It catches every path the other apps don't claim. Its development.fallback tells the local proxy where to send requests for apps you aren't running locally, so it points at the marketing app's production domain. That project doesn't exist until Lesson 2.5, so use acme-marketing.vercel.app for now and swap in your real domain then. Child apps without their own fallback borrow this one.
Part 3: Wrap Next.js Configs
Update each application's next.config.ts to use the wrapper.
Marketing (apps/marketing/next.config.ts):
import type { NextConfig } from "next";
import { withMicrofrontends } from "@vercel/microfrontends/next/config";
const nextConfig: NextConfig = {
// Your existing config
};
export default withMicrofrontends(nextConfig);Docs (apps/docs/next.config.ts):
import type { NextConfig } from "next";
import { withMicrofrontends } from "@vercel/microfrontends/next/config";
const nextConfig: NextConfig = {
// Routes live under app/docs/, so no basePath
};
export default withMicrofrontends(nextConfig);Dashboard (apps/dashboard/next.config.ts):
import type { NextConfig } from "next";
import { withMicrofrontends } from "@vercel/microfrontends/next/config";
const nextConfig: NextConfig = {
// Routes live under app/app/ and app/settings/
};
export default withMicrofrontends(nextConfig);All three configs look the same. withMicrofrontends handles the asset prefixes, and each app's folders handle the routes.
Part 4: Keep Routes at Their Full Paths
If you've built Next.js multi-zones before, your hand is probably reaching for basePath right about now:
// Don't do this
const nextConfig: NextConfig = {
basePath: "/docs",
};Vercel microfrontends don't support Next.js apps that use basePath. The docs app receives /docs/getting-started with the full path intact, so it needs a route at that full path. That's why Lesson 1.4 put the docs pages under app/docs/ instead of at the root.
There's nothing new to create here. Confirm both child apps match these trees:
apps/docs/app/
├── layout.tsx
└── docs/
└── page.tsx # handles /docs
apps/dashboard/app/
├── layout.tsx
├── app/
│ └── page.tsx # handles /app
└── settings/
└── page.tsx # handles /settings
The folder names repeat the URL. app/app/page.tsx looks like a typo, and it's the correct path for /app.
Why Asset Prefixes Matter
Without withMicrofrontends, every app serves static assets at /_next/:
marketing: /_next/static/chunks/main.js
docs: /_next/static/chunks/main.js ← CONFLICT!
dashboard: /_next/static/chunks/main.js ← CONFLICT!
The wrapper adds unique prefixes (an obfuscated hash like vc-ap-b3331f):
marketing: /_next/static/chunks/main.js
docs: /vc-ap-a1b2c3/_next/static/chunks/main.js
dashboard: /vc-ap-d4e5f6/_next/static/chunks/main.js
This prevents JavaScript and CSS from one app overwriting another's.
Try It
At this point, the apps still run independently. The configuration prepares them for the microfrontends proxy, which we'll enable in Lesson 2.3.
Run the apps:
pnpm devVisit each and verify the Header still renders correctly:
- http://localhost:3000 - Marketing
- http://localhost:3001/docs - Docs
- http://localhost:3002/app - Dashboard
Commit
git add -A
git commit -m "feat: add microfrontends configuration"Done-When
@vercel/microfrontendsinstalled in all three appsmicrofrontends.jsoncreated in marketing app with correct schema (usingpathsarray)- Application keys in
microfrontends.jsonmatch the Vercel project names (acme-marketing,acme-docs,acme-dashboard), which also match thepackage.jsonnames - All
next.config.tsfiles wrapped withwithMicrofrontends - No app uses
basePath, and the docs pages live underapps/docs/app/docs/ - Apps run without console errors
Troubleshooting
Asset 404s on /_next/ paths: You forgot withMicrofrontends in next.config.ts. Easy to miss.
does_not_match_schema error: You used path (string) instead of paths (array). The schema validator is picky about this.
Build fails with Could not find a microfrontends.json file in the repository that contains the "acme-docs" application: The key in microfrontends.json doesn't match the Vercel project name. Rename the key to the project name. If the package.json name is different, add packageName with that name. See the troubleshooting docs.
/docs returns a 404 from the docs app: Check for a leftover basePath in apps/docs/next.config.ts, and confirm the page lives at apps/docs/app/docs/page.tsx.
What's Next
Configuration done. Next lesson covers path routing in detail, including the execution order that trips up most developers.
Was this helpful?