From 4b385fa20206d3dfb033c97ff1ad7e0e3af34c0f Mon Sep 17 00:00:00 2001 From: Kevin Beier Date: Tue, 11 Aug 2026 20:20:09 +0200 Subject: [PATCH 1/3] docs(bridge): meta-framework host recipes for export-app Document one Bridge remote loaded from Nuxt, Next, and Modern.js hosts with catch-all basename guidance and slashed expose names for Nuxt MF. Co-authored-by: Cursor --- .changeset/bridge-meta-framework-hosts.md | 5 ++ .../docs/en/guide/bridge/overview.mdx | 10 ++++ .../docs/en/integrations/practice/vue.mdx | 51 +++++++++++++++++++ 3 files changed, 66 insertions(+) create mode 100644 .changeset/bridge-meta-framework-hosts.md diff --git a/.changeset/bridge-meta-framework-hosts.md b/.changeset/bridge-meta-framework-hosts.md new file mode 100644 index 00000000000..5affcef0057 --- /dev/null +++ b/.changeset/bridge-meta-framework-hosts.md @@ -0,0 +1,5 @@ +--- +'website-new': patch +--- + +Document loading the same Bridge export-app from Nuxt, Next, and Modern.js hosts. diff --git a/apps/website-new/docs/en/guide/bridge/overview.mdx b/apps/website-new/docs/en/guide/bridge/overview.mdx index 613139d0c5b..746028c9946 100644 --- a/apps/website-new/docs/en/guide/bridge/overview.mdx +++ b/apps/website-new/docs/en/guide/bridge/overview.mdx @@ -16,6 +16,16 @@ Through Bridge, you can: These capabilities make Bridge the core infrastructure for building modern, scalable micro-frontend architectures. +## Meta-framework hosts + +Bridge remotes are framework-agnostic at the host boundary: export once with `createBridgeComponent`, load with the host’s `createRemoteAppComponent`. + +- **Nuxt** (Vue consumer): catch-all route + `@module-federation/bridge-vue3` — see [Vue Bridge practice](/integrations/practice/vue#meta-framework-hosts-nuxt-next-modernjs). +- **Next.js / Modern.js** (React consumer): `/remote/*` + `@module-federation/bridge-react` (or `@module-federation/modern-js-v3/react`). +- The **same** Vue `./bridge/export-app` can be mounted in Nuxt **and** React/Next without a second remote build. + +Component-level SSR inside Nuxt remains `@module-federation/nuxt`; Bridge is for application-level routing remotes. + ## Supported Frameworks ### React Bridge (`@module-federation/bridge-react`) diff --git a/apps/website-new/docs/en/integrations/practice/vue.mdx b/apps/website-new/docs/en/integrations/practice/vue.mdx index 39cd21dd6e8..b5b2e65326a 100644 --- a/apps/website-new/docs/en/integrations/practice/vue.mdx +++ b/apps/website-new/docs/en/integrations/practice/vue.mdx @@ -131,6 +131,54 @@ const router = createRouter({ export default router; ``` +## Meta-framework hosts (Nuxt, Next, Modern.js) + +One Bridge remote (`createBridgeComponent` → `./bridge/export-app`) can be loaded by many hosts. The remote does not need a per-host build. + +| Host | Consumer API | Typical mount route | +| --- | --- | --- | +| Vue / Nuxt | `@module-federation/bridge-vue3` `createRemoteAppComponent` | `/remote/:pathMatch(.*)*` | +| React / Next / Modern.js | `@module-federation/bridge-react` `createRemoteAppComponent` | `/remote/*` | + +### Nuxt host tips + +- Mount the Bridge remote as a **client island** (`ClientOnly` / `ssr: false` for that page). Bridge SSR for meta-framework adapters is out of scope of the Vue Bridge CSR path. +- Prefer a host catch-all that uses Vue Router’s `:pathMatch(.*)*`, or pass an explicit `basename` (recommended) once available on `createRemoteAppComponent`. +- If you also use `@module-federation/nuxt` component federation, expose the Bridge entry with a **slashed** name (for example `./bridge/export-app`) so host manifest discovery does not register it as a Vue component. + +```ts +// Nuxt host — catch-all page (client only) +import { createRemoteAppComponent } from '@module-federation/bridge-vue3'; + +const RemoteApp = createRemoteAppComponent({ + loader: () => import('remote/bridge/export-app'), + basename: '/bridge', + asyncComponentOptions: { suspensible: false }, +}); +``` + +### React / Next / Modern.js host tips + +Load the **same Vue Bridge remote** with the React consumer. Basename comes from the host route (or an explicit `basename` prop): + +```tsx +import { createRemoteAppComponent } from '@module-federation/bridge-react'; + +const RemoteVueApp = createRemoteAppComponent({ + loader: () => import('remote/bridge/export-app'), + fallback:
failed
, + loading:
loading
, +}); + +// route: { path: '/bridge/*', element: } +``` + +Modern.js re-exports React Bridge APIs from `@module-federation/modern-js-v3/react` — use the same `createRemoteAppComponent` pattern. + +### What this is not + +Bridge remotes are isolated Vue/React apps with their own router. They do not share Nuxt `#app` / Nitro or Next App Router internals across the boundary. For Nuxt↔Nuxt **component** SSR, keep using `@module-federation/nuxt` component federation. + ## Parameters ### createRemoteAppComponent @@ -171,6 +219,9 @@ const Remote1App = createRemoteAppComponent({ loader: () => loadRemote('remote1/ * `rootAttrs` * type: `Record` * Purpose: Attributes that will be bound to the root container where the remote Vue application will be mounted + * `basename` + * type: `string` + * Purpose: Optional host mount prefix for the remote router. When set, skips route-based basename derivation (useful for Nuxt and other meta-framework catch-all pages). ```tsx // remote export const provider = createBridgeComponent({ From 959023becaf52af2819e8da0e070a3825cc03165 Mon Sep 17 00:00:00 2001 From: Kevin Beier Date: Tue, 11 Aug 2026 20:23:30 +0200 Subject: [PATCH 2/3] docs(bridge): align meta-framework recipes with shipped APIs Drop unreleased basename option from snippets, fix .html deep link, and use a React fallback component type. Co-authored-by: Cursor --- .../website-new/docs/en/guide/bridge/overview.mdx | 2 +- .../docs/en/integrations/practice/vue.mdx | 15 ++++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/apps/website-new/docs/en/guide/bridge/overview.mdx b/apps/website-new/docs/en/guide/bridge/overview.mdx index 746028c9946..2eb7f534dfd 100644 --- a/apps/website-new/docs/en/guide/bridge/overview.mdx +++ b/apps/website-new/docs/en/guide/bridge/overview.mdx @@ -20,7 +20,7 @@ These capabilities make Bridge the core infrastructure for building modern, scal Bridge remotes are framework-agnostic at the host boundary: export once with `createBridgeComponent`, load with the host’s `createRemoteAppComponent`. -- **Nuxt** (Vue consumer): catch-all route + `@module-federation/bridge-vue3` — see [Vue Bridge practice](/integrations/practice/vue#meta-framework-hosts-nuxt-next-modernjs). +- **Nuxt** (Vue consumer): catch-all route + `@module-federation/bridge-vue3` — see [Vue Bridge practice](/integrations/practice/vue.html#meta-framework-hosts-nuxt-next-modernjs). - **Next.js / Modern.js** (React consumer): `/remote/*` + `@module-federation/bridge-react` (or `@module-federation/modern-js-v3/react`). - The **same** Vue `./bridge/export-app` can be mounted in Nuxt **and** React/Next without a second remote build. diff --git a/apps/website-new/docs/en/integrations/practice/vue.mdx b/apps/website-new/docs/en/integrations/practice/vue.mdx index b5b2e65326a..b4e16d382a4 100644 --- a/apps/website-new/docs/en/integrations/practice/vue.mdx +++ b/apps/website-new/docs/en/integrations/practice/vue.mdx @@ -143,30 +143,34 @@ One Bridge remote (`createBridgeComponent` → `./bridge/export-app`) can be loa ### Nuxt host tips - Mount the Bridge remote as a **client island** (`ClientOnly` / `ssr: false` for that page). Bridge SSR for meta-framework adapters is out of scope of the Vue Bridge CSR path. -- Prefer a host catch-all that uses Vue Router’s `:pathMatch(.*)*`, or pass an explicit `basename` (recommended) once available on `createRemoteAppComponent`. +- Prefer a host catch-all that uses Vue Router’s `:pathMatch(.*)*` so basename auto-detect works. An explicit `basename` option on `createRemoteAppComponent` is tracked in [core#4984](https://github.com/module-federation/core/pull/4984). - If you also use `@module-federation/nuxt` component federation, expose the Bridge entry with a **slashed** name (for example `./bridge/export-app`) so host manifest discovery does not register it as a Vue component. ```ts // Nuxt host — catch-all page (client only) +// Register route path: '/bridge/:pathMatch(.*)*' import { createRemoteAppComponent } from '@module-federation/bridge-vue3'; const RemoteApp = createRemoteAppComponent({ loader: () => import('remote/bridge/export-app'), - basename: '/bridge', asyncComponentOptions: { suspensible: false }, }); ``` ### React / Next / Modern.js host tips -Load the **same Vue Bridge remote** with the React consumer. Basename comes from the host route (or an explicit `basename` prop): +Load the **same Vue Bridge remote** with the React consumer. Basename comes from the host route (or an explicit `basename` prop on the React wrapper): ```tsx import { createRemoteAppComponent } from '@module-federation/bridge-react'; +function BridgeFallback() { + return
failed
; +} + const RemoteVueApp = createRemoteAppComponent({ loader: () => import('remote/bridge/export-app'), - fallback:
failed
, + fallback: BridgeFallback, loading:
loading
, }); @@ -219,9 +223,6 @@ const Remote1App = createRemoteAppComponent({ loader: () => loadRemote('remote1/ * `rootAttrs` * type: `Record` * Purpose: Attributes that will be bound to the root container where the remote Vue application will be mounted - * `basename` - * type: `string` - * Purpose: Optional host mount prefix for the remote router. When set, skips route-based basename derivation (useful for Nuxt and other meta-framework catch-all pages). ```tsx // remote export const provider = createBridgeComponent({ From d9841ad65b22cd64a17e8941feaa08370217200d Mon Sep 17 00:00:00 2001 From: Kevin Beier Date: Tue, 11 Aug 2026 20:37:34 +0200 Subject: [PATCH 3/3] docs(bridge): pass explicit basename in Next.js recipe Next has no React Router context for basename auto-detect, so document RemoteVueApp basename="/bridge" for App Router catch-alls. Co-authored-by: Cursor --- .../website-new/docs/en/integrations/practice/vue.mdx | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/apps/website-new/docs/en/integrations/practice/vue.mdx b/apps/website-new/docs/en/integrations/practice/vue.mdx index b4e16d382a4..d1936291093 100644 --- a/apps/website-new/docs/en/integrations/practice/vue.mdx +++ b/apps/website-new/docs/en/integrations/practice/vue.mdx @@ -159,7 +159,7 @@ const RemoteApp = createRemoteAppComponent({ ### React / Next / Modern.js host tips -Load the **same Vue Bridge remote** with the React consumer. Basename comes from the host route (or an explicit `basename` prop on the React wrapper): +Load the **same Vue Bridge remote** with the React consumer: ```tsx import { createRemoteAppComponent } from '@module-federation/bridge-react'; @@ -173,8 +173,15 @@ const RemoteVueApp = createRemoteAppComponent({ fallback: BridgeFallback, loading:
loading
, }); +``` + +- **React Router / Modern.js**: a host route like `/bridge/*` can supply basename via router context. +- **Next.js** (no React Router context): pass `basename` explicitly on the wrapper, e.g. under `app/bridge/[[...path]]/page.tsx`: -// route: { path: '/bridge/*', element: } +```tsx +export default function BridgePage() { + return ; +} ``` Modern.js re-exports React Bridge APIs from `@module-federation/modern-js-v3/react` — use the same `createRemoteAppComponent` pattern.