Introduction to Remote Components
Throughout this course, you've built vertical microfrontends: splitting by route where each page belongs to one application. Remote components are the horizontal approach: embedding components from different applications on the same page.
Outcome
Understand the difference between vertical and horizontal microfrontends and know when to consider remote components.
Vertical vs Horizontal Recap
Vertical (what you've built):
Page at /docs/api
└── Entirely served by docs app
├── Header (shared package)
├── Content
└── Footer (shared package)
Horizontal (remote components):
Page at /
└── Served by marketing app
├── Header (REMOTE from header-app)
├── Hero (local component)
├── Features (local component)
└── Footer (REMOTE from footer-app)
With horizontal microfrontends, components from different applications render on the same page at runtime.
When to Consider Horizontal
Remote components solve specific problems:
| Scenario | Why Remote Components Help |
|---|---|
| Shared header across portfolio | One header app, embedded everywhere |
| Different teams own page sections | Team A owns header, Team B owns content |
| Runtime updates without redeploy | Update header without rebuilding all hosts |
| Embedded widgets | Checkout widget on multiple sites |
| Section-level migration from legacy | Modernize page sections incrementally without rewriting the whole route |
How Remote Components Work
Remote Components build on your Microfrontends setup. The remote-components package adds the runtime helpers; @vercel/microfrontends handles the routing through microfrontends.json. Install both in the host and in the app exposing the component:
pnpm add @vercel/microfrontends remote-componentsThe exposing app wraps the page in ExposeRemoteComponent:
import { ExposeRemoteComponent } from "remote-components/remote/nextjs/app";
export default function Page() {
return (
<ExposeRemoteComponent>
<h2>Hello from the header!</h2>
</ExposeRemoteComponent>
);
}The host app consumes it with ConsumeRemoteComponent. By default this is a Server Component, so the remote content is SSR'd:
import { ConsumeRemoteComponent } from "remote-components/host/nextjs/app";
export default function Page() {
return (
<div>
<ConsumeRemoteComponent src="/components/header" />
<main>Page content</main>
<ConsumeRemoteComponent src="/components/footer" />
</div>
);
}The path /components/header resolves through the Microfrontends proxy to whichever app exposes that route. The remote component:
- Fetches from the exposing application (components-app)
- Renders the component as if it were local
- No iframes - It's embedded directly in the DOM
- SSR by default - Server-renders like native Server Components
Configuration
Both the host and the exposing app wrap their next.config with withRemoteComponentsConfig and withMicrofrontends:
import { withRemoteComponentsConfig } from "remote-components/config/nextjs";
import { withMicrofrontends } from "@vercel/microfrontends/next/config";
export default withRemoteComponentsConfig(
withMicrofrontends({
// your Next.js config
}),
);Routing is declared in microfrontends.json the same way you've done throughout the course. The exposing app gets a path like /components/:path*, and the host resolves remote src values against it.
State Sharing
The most common question: "How do I share state between host and remote?"
To pass shared modules like next/image, next/link, next/navigation, or client-side configuration to remote components, add RemoteComponentsClientProvider to the host's layout:
"use client";
import { RemoteComponentsClientProvider } from "remote-components/host/nextjs/app/client-only";
export function Providers({ children }: { children: React.ReactNode }) {
return (
<RemoteComponentsClientProvider>
{children}
</RemoteComponentsClientProvider>
);
}The provider lives in a Client Component, but ConsumeRemoteComponent continues to render on the server. With this in place, both host and remote can share React context across the boundary, so a theme toggle in the host updates the remote header.
Vertical-First Philosophy
For most teams, the recommendation is:
- Start with vertical microfrontends (this course)
- Use shared packages for common components
- Consider horizontal only when shared packages aren't enough
Horizontal adds complexity:
- Module sharing configuration
- Cache invalidation when remotes update
- More moving parts to debug
Vertical is simpler and solves most use cases.
When Vertical Isn't Enough
Consider remote components when:
- Same component, many hosts - A header used by 10+ separate applications (not in a monorepo)
- Independent deployment of components - Marketing wants to update the header without docs redeploying
- Different teams, same page - Team A owns navigation, Team B owns search, Team C owns content
Example: Multi-Site Header
Imagine you have:
- marketing.example.com
- docs.example.com
- app.example.com
All need the same header. With shared packages in a monorepo, you'd need to redeploy all three when the header changes.
With remote components:
- header-app deploys
- All hosts pick up the new header (via ISR revalidation)
- No coordination needed
SSG/ISR with Remotes
Remote components support static generation:
Build time:
Host fetches remote component → Renders → Saves static HTML
Runtime (ISR):
Remote updates → Host revalidates → New HTML includes updated remote
On Vercel with the App Router, invalidation is automatic. Remote Components tag their fetch calls, and Vercel triggers revalidation on the host whenever a remote redeploys, no manual configuration required.
Done-When
- You understand vertical vs horizontal microfrontends
- You know when to consider remote components
- You can identify the
remote-componentspackage and its host/remote entry points - You understand how state is shared via
RemoteComponentsClientProvider
Decision Guide
| Situation | Recommendation |
|---|---|
| Monorepo with shared packages | Use shared packages (simpler) |
| Multiple repos, same header | Consider remote components |
| Single team | Probably don't need horizontal |
| 3+ teams on same page | Remote components may help |
| You want runtime updates | Remote components |
| You want simplicity | Vertical + shared packages |
What's Next
In the final lesson, you'll review the key decisions and get resources for continuing your microfrontends journey.
Was this helpful?