{"id":22889,"date":"2023-10-09T17:07:47","date_gmt":"2023-10-09T15:07:47","guid":{"rendered":"https:\/\/www.angulararchitects.io\/?p=22889"},"modified":"2025-01-11T19:06:52","modified_gmt":"2025-01-11T18:06:52","slug":"micro-frontends-with-modern-angular-part-2-multi-version-and-multi-framework-solutions-with-angular-elements-and-web-components","status":"publish","type":"post","link":"https:\/\/www.angulararchitects.io\/en\/blog\/micro-frontends-with-modern-angular-part-2-multi-version-and-multi-framework-solutions-with-angular-elements-and-web-components\/","title":{"rendered":"Micro Frontends with Modern Angular &#8211; Part 2: Multi-Version and Multi-Framework Solutions with Angular Elements and Web Components"},"content":{"rendered":"<div class=\"wp-post-series-box series-micro-frontends-with-modern-angular wp-post-series-box--expandable\">\n\t\t\t<input id=\"collapsible-series-micro-frontends-with-modern-angular6a14bb0212836\" class=\"wp-post-series-box__toggle_checkbox\" type=\"checkbox\">\n\t\n\t<label\n\t\tclass=\"wp-post-series-box__label\"\n\t\t\t\t\tfor=\"collapsible-series-micro-frontends-with-modern-angular6a14bb0212836\"\n\t\t\ttabindex=\"0\"\n\t\t\t\t>\n\t\t<p class=\"wp-post-series-box__name wp-post-series-name\">\n\t\t\tThis is post 2 of 6 in the series <em>&ldquo;Micro Frontends with Modern Angular&rdquo;<\/em>\t\t<\/p>\n\t\t\t<\/label>\n\n\t\t\t<div class=\"wp-post-series-box__posts\">\n\t\t\t<ol>\n\t\t\t\t\t\t\t\t\t<li><a href=\"https:\/\/www.angulararchitects.io\/en\/blog\/micro-frontends-with-modern-angular-part-1-standalone-and-esbuild\/\">Micro Frontends with Modern Angular &#8211; Part 1: Standalone and esbuild<\/a><\/li>\n\t\t\t\t\t\t\t\t\t<li><span class=\"wp-post-series-box__current\">Micro Frontends with Modern Angular &#8211; Part 2: Multi-Version and Multi-Framework Solutions with Angular Elements and Web Components<\/span><\/li>\n\t\t\t\t\t\t\t\t\t<li><a href=\"https:\/\/www.angulararchitects.io\/en\/blog\/combining-native-federation-and-module-federation\/\">Combining Native Federation and Module Federation<\/a><\/li>\n\t\t\t\t\t\t\t\t\t<li><a href=\"https:\/\/www.angulararchitects.io\/en\/blog\/ssr-and-hydration-with-native-federation-for-angular\/\">SSR and Hydration with Native Federation for Angular<\/a><\/li>\n\t\t\t\t\t\t\t\t\t<li><a href=\"https:\/\/www.angulararchitects.io\/en\/blog\/fixing-dx-friction-automatic-shell-reloading-in-native-federation\/\">Fixing DX Friction: Automatic Shell Reloading in Native Federation<\/a><\/li>\n\t\t\t\t\t\t\t\t\t<li><a href=\"https:\/\/www.angulararchitects.io\/en\/blog\/native-federation-just-got-better-performance-dx-and-simplicity\/\">Native Federation Just Got Better: Performance, DX, and Simplicity<\/a><\/li>\n\t\t\t\t\t\t\t<\/ol>\n\t\t<\/div>\n\t<\/div>\n<p>The first part of this article series showed how to use modern Angular with Native Federation and esbuild. We've assumed that all Micro Frontends and the shell use the same framework in the same version. However, if the goal is to integrate Micro Frontends that are based on different frameworks and\/or framework versions, you need some additional considerations.<\/p>\n<p>As <a href=\"https:\/\/www.angulararchitects.io\/blog\/multi-framework-and-version-micro-frontends-with-module-federation-your-4-steps-guide\/\">discussed in this blog article<\/a>, such an approach is nothing you normally want to introduce without a good reason like dealing with legacy systems or combining existing products to a suite.<\/p>\n<p>\ud83d\udcc2 <a href=\"https:\/\/github.com\/manfredsteyer\/module-federation-plugin-example\/tree\/nf-web-comp-mixed\">Source Code<\/a><br \/>\n(see branch <code>nf-web-comp-mixed<\/code>)<\/p>\n<h2>Abstracting Micro Frontends with Web Components<\/h2>\n<p>The first step when implementing such a scenario is abstracting the different frameworks and versions. A popular way for this is to use Web Components that encapsulate entire Micro Frontends. The result is not a ideal-typical Web Components in the sense of reusable widgets, but rather a coarse-grained web components that represent entire domains. The following image shows a Web Component bootstrapping a React application that is loaded into an Angular-based shell:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/10\/multi.png\" alt=\"React-Micro frontend in Angular Shell\" \/><\/p>\n<p>Actually, it's not difficult to write a Web Component that delegates to a framework instead of writing something into the DOM itself. Angular makes even this task easier with the @angular\/elements converting an Angular component into a Web Component. Technically speaking, it wraps the Angular Component into a Web Component created on the fly.<\/p>\n<p>The package @angular\/elements can be installed with npm (<code>npm i @angular\/elements<\/code>). Together with Standalone Components, it's used in a straight forward manner:<\/p>\n<pre><code class=\"language-typescript\">import { NgZone } from &#039;@angular\/core&#039;;\n\n(async () =&gt; {\n  const app = await createApplication({\n    providers: [\u2026],\n  });\n\n  const mfe2Root = createCustomElement(AppComponent, {\n    injector: app.injector,\n  });\n\n  customElements.define(&#039;mfe2-root&#039;, mfe2Root);\n})();<\/code><\/pre>\n<p>The lines of code shown here replace bootstrapping the application. The <code>createApplication<\/code> function creates an Angular application including a root injector. The latter is configured via the <em>providers<\/em> array. However, instead of bootstrapping a component, <code>createCustomElement<\/code> transforms a standalone component into a web component.<\/p>\n<p>The <code>customElements.define<\/code> method is already part of the browser's API and registers the Web Component under the name <code>mfe2-root<\/code>. This means that from now on the browser will render the web component and thus the Angular component behind it as soon as <code>&lt;mfe2-root&gt;&lt;\/mfe2-root&gt;<\/code> appears in the markup. When assigning the name, please note that by definition it must contain a hyphen. This is to avoid naming conflicts with existing HTML elements.<\/p>\n<p>In order to share this Web Component via Native Federation, the file defining the Web Component must be specified in the <code>federation.config.js<\/code> under <code>exposes<\/code>. In the case considered here, this is <code>bootstrap.ts<\/code>:<\/p>\n<pre><code class=\"language-json\">exposes: {\n  &#039;.\/web-components&#039;: &#039;.\/projects\/mfe2\/src\/bootstrap.ts&#039;,\n},<\/code><\/pre>\n<p>This approach gives us the best of both worlds: Using Native Federation, frameworks and libraries can be shared as long as multiple Micro Frontends use the same version. By abstracting differences via Web Components, different frameworks and framework versions can also be integrated:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/10\/venn.png\" alt=\"Web Component and Native Federation: The best of two worlds\" \/><\/p>\n<h2>Loading Web Components in a Shell<\/h2>\n<p>Providing a Web Component via Native Federation is only one side of the coin: We also have to load the Web Component into a shell. Since the Angular Router can only work with Angular Components, it makes sense to wrap our Web Components into an Angular Component:<\/p>\n<pre><code class=\"language-typescript\">import { loadRemoteModule } from &#039;@softarc\/native-federation-runtime&#039;;\n\n@Component({\n  selector: &#039;app-wrapper&#039;,\n  standalone: true,\n  imports: [CommonModule],\n  templateUrl: &#039;.\/wrapper.component.html&#039;,\n  styleUrls: [&#039;.\/wrapper.component.css&#039;]\n})\nexport class WrapperComponent implements OnInit {\n  elm = inject(ElementRef);\n\n  async ngOnInit() {\n    await loadRemoteModule(&#039;mfe2&#039;, &#039;.\/web-components&#039;);\n    const root = document.createElement(&#039;mfe2-root&#039;);\n    this.elm.nativeElement.appendChild(root);\n  }\n}<\/code><\/pre>\n<p>This <code>WrapperComponent<\/code> loads the Web Component via Native Federation and creates an HTML element into which the browser renders the Web Component. To simplify things, the key data used for this -- the names <code>mfe2<\/code>, <code>.\/web-components<\/code> and <code>mfe2-root<\/code> -- are hard-coded in the example shown. In order to make the <code>WrapperComponent<\/code> universally applicable, it is advisable to make this information parameterizable, e. g. via an @Input:<\/p>\n<pre><code class=\"language-typescript\">@Component([...])\nexport class WrapperComponent implements OnInit {\n  elm = inject(ElementRef);\n\n  @Input() config = initWrapperConfig;\n\n  async ngOnInit() {\n    const { exposedModule, remoteName, elementName } = this.config;\n\n    await loadRemoteModule(remoteName, exposedModule);\n    const root = document.createElement(elementName);\n    this.elm.nativeElement.appendChild(root);\n  }\n}<\/code><\/pre>\n<p>The constant <code>initWrapperConfig<\/code> and its underlying type is defined as follows:<\/p>\n<pre><code class=\"language-typescript\">export interface WrapperConfig {\n    remoteName: string;\n    exposedModule: string;\n    elementName: string;\n}\n\nexport const initWrapperConfig: WrapperConfig = {\n    remoteName: &#039;&#039;,\n    exposedModule: &#039;&#039;,\n    elementName: &#039;&#039;,\n}<\/code><\/pre>\n<p>It's also noteworthy that since Angular 16, the router can directly bind routing parameters to an @Input. For this, activate the following feature during bootstrap:<\/p>\n<pre><code class=\"language-typescript\">bootstrapApplication(AppComponent, {\n  providers: [\n    provideRouter(\n      APP_ROUTES, \n      withComponentInputBinding()\n    )\n  ],\n});<\/code><\/pre>\n<p>This allows routes as the following:<\/p>\n<pre><code class=\"language-typescript\">export const APP_ROUTES: Routes = [\n  [...],\n  {\n    path: &#039;passengers&#039;,\n    component: WrapperComponent,\n    data: {\n      config: {\n        remoteName: &#039;mfe2&#039;,\n        exposedModule: &#039;.\/web-components&#039;,\n        elementName: &#039;mfe2-root&#039;,\n      } as WrapperConfig,\n    },\n  },\n  [...]\u00b4\n];<\/code><\/pre>\n<h2>Sharing Zone.js<\/h2>\n<p>Angular currently still uses <em>Zone.js<\/em> for change detection. The <code>NgZone<\/code> service represents <code>Zone.js<\/code> within Angular. To avoid problems, you should ensure that all Micro Frontends and the shell use the same <code>NgZone<\/code> instance. To achieve this, the shell's <code>AppComponent<\/code> could share its <code>NgZone<\/code> across the global namespace:<\/p>\n<pre><code class=\"language-typescript\">@Component([\u2026])\nexport class AppComponent {\n  constructor() {\n      globalThis.ngZone = inject(NgZone);\n  }\n}<\/code><\/pre>\n<p>The individual Micro Frontends can then use this instance during bootstrapping:<\/p>\n<pre><code class=\"language-typescript\">const app = await createApplication({\n  providers: [\n    globalThis.ngZone ? { provide: NgZone, useValue: globalThis.ngZone } : [],\n    provideRouter(APP_ROUTES),\n  ],\n});<\/code><\/pre>\n<p>Fortunately, with Signals we are looking into a Zone-less future and once Angular works without <em>Zone.js<\/em> we can git rid of this workaround.<\/p>\n<h2>Web Components with own Routes<\/h2>\n<p>Things get a little more exciting when the micro frontend of the web component also uses routing. In this case, two routers duel over the URL - the shell's router and the Micro Frontend's router:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/10\/router.png\" alt=\"Micro Frontend with its own routes\" \/><\/p>\n<p>To ensure that the two routers do not interfere with each other, the following procedure has proven to be effective:<\/p>\n<ul>\n<li>Each route of the Micro Frontend is given a unique prefix.<\/li>\n<li>The shell tells its router to only pay attention to the first URL segment. Based on this segment, the shell loads a Micro Frontend, which makes its own routing decisions based on the remaining segments.<\/li>\n<\/ul>\n<p>To specify which part of the Url is interesting for the respective router, you can use an <code>UrlMatcher<\/code>:<\/p>\n<pre><code class=\"language-typescript\">[\u2026]\nimport { loadRemoteModule } from &#039;@angular-architects\/native-federation&#039;;\nimport { WrapperComponent } from &#039;.\/wrapper\/wrapper.component&#039;;\nimport { WrapperConfig } from &#039;.\/wrapper\/wrapper-config&#039;;\nimport { startsWith } from &#039;.\/starts-with&#039;;\n\nexport const APP_ROUTES: Routes = [\n  [\u2026]\n  {\n    matcher: startsWith(&#039;profile&#039;),\n    component: WrapperComponent,\n    data: {\n      config: {\n        remoteName: &#039;mfe3&#039;,\n        exposedModule: &#039;.\/web-components&#039;,\n        elementName: &#039;mfe3-root&#039;,\n      } as WrapperConfig,\n    },\n  },\n  [\u2026]\n];<\/code><\/pre>\n<p>The Angular router usually decides for or against a route based on the configured paths. <code>UrlMatchers<\/code> are an alternative to this. These are functions telling the router whether the configured route should be activated. The function <a href=\"https:\/\/github.com\/manfredsteyer\/module-federation-plugin-example\/blob\/nf-web-comp-mixed\/projects\/shell\/src\/app\/starts-with.ts\"><code>startsWith<\/code><\/a> for instance checks whether the current URL starts with the passed segment.<\/p>\n<p>In our example, the shell's router uses this matcher to check whether the current URL starts with <code>profile<\/code>.<\/p>\n<h2>Workaround for Routers in Web Component<\/h2>\n<p>In order for the router to react to route changes in the web component, it needs a special invitation. The examples discussed here include an helper method <a href=\"https:\/\/github.com\/manfredsteyer\/module-federation-plugin-example\/blob\/nf-web-comp-mixed\/projects\/mfe3\/src\/app\/connect-router.ts\"><code>connectRouter<\/code><\/a> that calls the Micro Frontend in its <code>AppComponent<\/code>:<\/p>\n<pre><code class=\"language-typescript\">@Component({ \u2026 })\nexport class AppComponent implements OnInit {\n  constructor() {\n    connectRouter();\n  }\n}<\/code><\/pre>\n<h2>What's next? More on Architecture!<\/h2>\n<p>Please find more information on enterprise-scale Angular architectures in our free eBook (5th edition, 12 chapters):<\/p>\n<ul>\n<li>According to which criteria can we subdivide a huge application into sub-domains?<\/li>\n<li>How can we make sure, the solution is maintainable for years or even decades?<\/li>\n<li>Which options from Micro Frontends are provided by Module Federation?<\/li>\n<\/ul>\n<p><a href=\"https:\/\/www.angulararchitects.io\/book\"><img decoding=\"async\" src=\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2022\/12\/cover-5th-small.png\" alt=\"free\" \/><\/a><\/p>\n<p>Feel free to <a href=\"https:\/\/www.angulararchitects.io\/en\/book\">download it here<\/a> now!<\/p>\n<h2>Conclusion<\/h2>\n<p>Combining several frameworks or framework versions is for sure not your first choice. However, if there is a good reason, you can achieve this goal by abstracting the different Micro Frontends. Using Web Components for this is a popular choice. <\/p>\n<p>However, we should be aware that no one is officially testing whether a given framework can peacefully coexist in the same browser window with another framework or another version of it self. Also, we need some workarounds, e.g. for the router or for sharing one Zone.js instance. The latter one is already counted, as Signals will eventually allow to go Zone-less.   <\/p>\n<p>Another concern is increased bundle sizes. Lazy Loading different Micro Frontends with different frameworks or versions can help here. Also the next part of this series shows some approaches to improve performance in an Micro Frontend architecture.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This is post 2 of 6 in the series &ldquo;Micro Frontends with Modern Angular&rdquo; Micro Frontends with Modern Angular &#8211; Part 1: Standalone and esbuild Micro Frontends with Modern Angular &#8211; Part 2: Multi-Version and Multi-Framework Solutions with Angular Elements and Web Components Combining Native Federation and Module Federation SSR and Hydration with Native Federation [&hellip;]<\/p>\n","protected":false},"author":25,"featured_media":22851,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_price":"","_stock":"","_tribe_ticket_header":"","_tribe_default_ticket_provider":"","_ticket_start_date":"","_ticket_end_date":"","_tribe_ticket_show_description":"","_tribe_ticket_show_not_going":false,"_tribe_ticket_use_global_stock":"","_tribe_ticket_global_stock_level":"","_global_stock_mode":"","_global_stock_cap":"","_tribe_rsvp_for_event":"","_tribe_ticket_going_count":"","_tribe_ticket_not_going_count":"","_tribe_tickets_list":"[]","_tribe_ticket_has_attendee_info_fields":false,"footnotes":""},"categories":[18],"tags":[],"class_list":["post-22889","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","post_series-micro-frontends-with-modern-angular"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.1.1 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Micro Frontends with Modern Angular - Part 2: Multi-Version and Multi-Framework Solutions with Angular Elements and Web Components - ANGULARarchitects<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.angulararchitects.io\/en\/blog\/micro-frontends-with-modern-angular-part-2-multi-version-and-multi-framework-solutions-with-angular-elements-and-web-components\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Micro Frontends: Multi-Version and Multi-Framework Solutions\" \/>\n<meta property=\"og:description\" content=\"Angular Elements with Standalone, Web Components, Native Federation\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.angulararchitects.io\/en\/blog\/micro-frontends-with-modern-angular-part-2-multi-version-and-multi-framework-solutions-with-angular-elements-and-web-components\/\" \/>\n<meta property=\"og:site_name\" content=\"ANGULARarchitects\" \/>\n<meta property=\"article:published_time\" content=\"2023-10-09T15:07:47+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-01-11T18:06:52+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/10\/sujet2.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1000\" \/>\n\t<meta property=\"og:image:height\" content=\"500\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Manfred Steyer\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:title\" content=\"Micro Frontends: Multi-Version and Multi-Framework Solutions\" \/>\n<meta name=\"twitter:description\" content=\"Angular Elements with Standalone, Web Components, Native Federation\" \/>\n<meta name=\"twitter:image\" content=\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/10\/sujet3.jpg\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Manfred Steyer\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/micro-frontends-with-modern-angular-part-2-multi-version-and-multi-framework-solutions-with-angular-elements-and-web-components\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/micro-frontends-with-modern-angular-part-2-multi-version-and-multi-framework-solutions-with-angular-elements-and-web-components\/\"},\"author\":{\"name\":\"Manfred Steyer\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/f3de69c1e2bdb5ba04d8d2f5f998b81a\"},\"headline\":\"Micro Frontends with Modern Angular &#8211; Part 2: Multi-Version and Multi-Framework Solutions with Angular Elements and Web Components\",\"datePublished\":\"2023-10-09T15:07:47+00:00\",\"dateModified\":\"2025-01-11T18:06:52+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/micro-frontends-with-modern-angular-part-2-multi-version-and-multi-framework-solutions-with-angular-elements-and-web-components\/\"},\"wordCount\":1123,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/micro-frontends-with-modern-angular-part-2-multi-version-and-multi-framework-solutions-with-angular-elements-and-web-components\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/10\/shutterstock_1071593777.jpg\",\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.angulararchitects.io\/en\/blog\/micro-frontends-with-modern-angular-part-2-multi-version-and-multi-framework-solutions-with-angular-elements-and-web-components\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/micro-frontends-with-modern-angular-part-2-multi-version-and-multi-framework-solutions-with-angular-elements-and-web-components\/\",\"url\":\"https:\/\/www.angulararchitects.io\/en\/blog\/micro-frontends-with-modern-angular-part-2-multi-version-and-multi-framework-solutions-with-angular-elements-and-web-components\/\",\"name\":\"Micro Frontends with Modern Angular - Part 2: Multi-Version and Multi-Framework Solutions with Angular Elements and Web Components - ANGULARarchitects\",\"isPartOf\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/micro-frontends-with-modern-angular-part-2-multi-version-and-multi-framework-solutions-with-angular-elements-and-web-components\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/micro-frontends-with-modern-angular-part-2-multi-version-and-multi-framework-solutions-with-angular-elements-and-web-components\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/10\/shutterstock_1071593777.jpg\",\"datePublished\":\"2023-10-09T15:07:47+00:00\",\"dateModified\":\"2025-01-11T18:06:52+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/micro-frontends-with-modern-angular-part-2-multi-version-and-multi-framework-solutions-with-angular-elements-and-web-components\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.angulararchitects.io\/en\/blog\/micro-frontends-with-modern-angular-part-2-multi-version-and-multi-framework-solutions-with-angular-elements-and-web-components\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/micro-frontends-with-modern-angular-part-2-multi-version-and-multi-framework-solutions-with-angular-elements-and-web-components\/#primaryimage\",\"url\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/10\/shutterstock_1071593777.jpg\",\"contentUrl\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/10\/shutterstock_1071593777.jpg\",\"width\":1000,\"height\":563},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/micro-frontends-with-modern-angular-part-2-multi-version-and-multi-framework-solutions-with-angular-elements-and-web-components\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.angulararchitects.io\/en\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Micro Frontends with Modern Angular &#8211; Part 2: Multi-Version and Multi-Framework Solutions with Angular Elements and Web Components\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#website\",\"url\":\"https:\/\/www.angulararchitects.io\/en\/\",\"name\":\"ANGULARarchitects\",\"description\":\"AngularArchitects.io\",\"publisher\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.angulararchitects.io\/en\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#organization\",\"name\":\"ANGULARarchitects\",\"alternateName\":\"SOFTWAREarchitects\",\"url\":\"https:\/\/www.angulararchitects.io\/en\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/07\/AA-Logo-RGB-horizontal-inside-knowledge-black.svg\",\"contentUrl\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/07\/AA-Logo-RGB-horizontal-inside-knowledge-black.svg\",\"width\":644,\"height\":216,\"caption\":\"ANGULARarchitects\"},\"image\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/github.com\/angular-architects\",\"https:\/\/www.linkedin.com\/company\/angular-architects\/\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/f3de69c1e2bdb5ba04d8d2f5f998b81a\",\"name\":\"Manfred Steyer\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/8778dfb353992fa3a0d909beee085a088891e5bfce65cdb3631801da527cf11b?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/8778dfb353992fa3a0d909beee085a088891e5bfce65cdb3631801da527cf11b?s=96&d=mm&r=g\",\"caption\":\"Manfred Steyer\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Micro Frontends with Modern Angular - Part 2: Multi-Version and Multi-Framework Solutions with Angular Elements and Web Components - ANGULARarchitects","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.angulararchitects.io\/en\/blog\/micro-frontends-with-modern-angular-part-2-multi-version-and-multi-framework-solutions-with-angular-elements-and-web-components\/","og_locale":"en_US","og_type":"article","og_title":"Micro Frontends: Multi-Version and Multi-Framework Solutions","og_description":"Angular Elements with Standalone, Web Components, Native Federation","og_url":"https:\/\/www.angulararchitects.io\/en\/blog\/micro-frontends-with-modern-angular-part-2-multi-version-and-multi-framework-solutions-with-angular-elements-and-web-components\/","og_site_name":"ANGULARarchitects","article_published_time":"2023-10-09T15:07:47+00:00","article_modified_time":"2025-01-11T18:06:52+00:00","og_image":[{"width":1000,"height":500,"url":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/10\/sujet2.jpg","type":"image\/jpeg"}],"author":"Manfred Steyer","twitter_card":"summary_large_image","twitter_title":"Micro Frontends: Multi-Version and Multi-Framework Solutions","twitter_description":"Angular Elements with Standalone, Web Components, Native Federation","twitter_image":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/10\/sujet3.jpg","twitter_misc":{"Written by":"Manfred Steyer","Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.angulararchitects.io\/en\/blog\/micro-frontends-with-modern-angular-part-2-multi-version-and-multi-framework-solutions-with-angular-elements-and-web-components\/#article","isPartOf":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/micro-frontends-with-modern-angular-part-2-multi-version-and-multi-framework-solutions-with-angular-elements-and-web-components\/"},"author":{"name":"Manfred Steyer","@id":"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/f3de69c1e2bdb5ba04d8d2f5f998b81a"},"headline":"Micro Frontends with Modern Angular &#8211; Part 2: Multi-Version and Multi-Framework Solutions with Angular Elements and Web Components","datePublished":"2023-10-09T15:07:47+00:00","dateModified":"2025-01-11T18:06:52+00:00","mainEntityOfPage":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/micro-frontends-with-modern-angular-part-2-multi-version-and-multi-framework-solutions-with-angular-elements-and-web-components\/"},"wordCount":1123,"commentCount":0,"publisher":{"@id":"https:\/\/www.angulararchitects.io\/en\/#organization"},"image":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/micro-frontends-with-modern-angular-part-2-multi-version-and-multi-framework-solutions-with-angular-elements-and-web-components\/#primaryimage"},"thumbnailUrl":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/10\/shutterstock_1071593777.jpg","inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.angulararchitects.io\/en\/blog\/micro-frontends-with-modern-angular-part-2-multi-version-and-multi-framework-solutions-with-angular-elements-and-web-components\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.angulararchitects.io\/en\/blog\/micro-frontends-with-modern-angular-part-2-multi-version-and-multi-framework-solutions-with-angular-elements-and-web-components\/","url":"https:\/\/www.angulararchitects.io\/en\/blog\/micro-frontends-with-modern-angular-part-2-multi-version-and-multi-framework-solutions-with-angular-elements-and-web-components\/","name":"Micro Frontends with Modern Angular - Part 2: Multi-Version and Multi-Framework Solutions with Angular Elements and Web Components - ANGULARarchitects","isPartOf":{"@id":"https:\/\/www.angulararchitects.io\/en\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/micro-frontends-with-modern-angular-part-2-multi-version-and-multi-framework-solutions-with-angular-elements-and-web-components\/#primaryimage"},"image":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/micro-frontends-with-modern-angular-part-2-multi-version-and-multi-framework-solutions-with-angular-elements-and-web-components\/#primaryimage"},"thumbnailUrl":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/10\/shutterstock_1071593777.jpg","datePublished":"2023-10-09T15:07:47+00:00","dateModified":"2025-01-11T18:06:52+00:00","breadcrumb":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/micro-frontends-with-modern-angular-part-2-multi-version-and-multi-framework-solutions-with-angular-elements-and-web-components\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.angulararchitects.io\/en\/blog\/micro-frontends-with-modern-angular-part-2-multi-version-and-multi-framework-solutions-with-angular-elements-and-web-components\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.angulararchitects.io\/en\/blog\/micro-frontends-with-modern-angular-part-2-multi-version-and-multi-framework-solutions-with-angular-elements-and-web-components\/#primaryimage","url":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/10\/shutterstock_1071593777.jpg","contentUrl":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/10\/shutterstock_1071593777.jpg","width":1000,"height":563},{"@type":"BreadcrumbList","@id":"https:\/\/www.angulararchitects.io\/en\/blog\/micro-frontends-with-modern-angular-part-2-multi-version-and-multi-framework-solutions-with-angular-elements-and-web-components\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.angulararchitects.io\/en\/"},{"@type":"ListItem","position":2,"name":"Micro Frontends with Modern Angular &#8211; Part 2: Multi-Version and Multi-Framework Solutions with Angular Elements and Web Components"}]},{"@type":"WebSite","@id":"https:\/\/www.angulararchitects.io\/en\/#website","url":"https:\/\/www.angulararchitects.io\/en\/","name":"ANGULARarchitects","description":"AngularArchitects.io","publisher":{"@id":"https:\/\/www.angulararchitects.io\/en\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.angulararchitects.io\/en\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.angulararchitects.io\/en\/#organization","name":"ANGULARarchitects","alternateName":"SOFTWAREarchitects","url":"https:\/\/www.angulararchitects.io\/en\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.angulararchitects.io\/en\/#\/schema\/logo\/image\/","url":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/07\/AA-Logo-RGB-horizontal-inside-knowledge-black.svg","contentUrl":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/07\/AA-Logo-RGB-horizontal-inside-knowledge-black.svg","width":644,"height":216,"caption":"ANGULARarchitects"},"image":{"@id":"https:\/\/www.angulararchitects.io\/en\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/github.com\/angular-architects","https:\/\/www.linkedin.com\/company\/angular-architects\/"]},{"@type":"Person","@id":"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/f3de69c1e2bdb5ba04d8d2f5f998b81a","name":"Manfred Steyer","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/8778dfb353992fa3a0d909beee085a088891e5bfce65cdb3631801da527cf11b?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/8778dfb353992fa3a0d909beee085a088891e5bfce65cdb3631801da527cf11b?s=96&d=mm&r=g","caption":"Manfred Steyer"}}]}},"_links":{"self":[{"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/posts\/22889","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/users\/25"}],"replies":[{"embeddable":true,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/comments?post=22889"}],"version-history":[{"count":10,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/posts\/22889\/revisions"}],"predecessor-version":[{"id":27575,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/posts\/22889\/revisions\/27575"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/media\/22851"}],"wp:attachment":[{"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/media?parent=22889"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/categories?post=22889"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/tags?post=22889"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}