{"id":11558,"library":"piral-vue","title":"Piral Vue 2 Plugin","description":"Piral-vue is a plugin designed for integrating Vue 2 components within a Piral microfrontend application. It acts as a converter, allowing developers to seamlessly register and render existing or new Vue 2 components as pilets (microfrontends) or parts of pilets. The package is an integral part of the larger Piral ecosystem, which focuses on building scalable and maintainable web portals using a microfrontend architecture, facilitating the combination of different frontend frameworks. As of version 1.10.3, it continues to receive regular updates, typically with minor point releases addressing bug fixes, dependency updates, and improvements within the broader Piral framework, ensuring compatibility and stability within the Piral ecosystem. Its key differentiator is its explicit support for Vue 2, enabling the reuse of established Vue 2 codebases within a modern microfrontend shell. This provides a clear migration path or coexistence strategy for organizations with significant investments in Vue 2 applications, allowing them to incrementally modernize or integrate without forcing an immediate, large-scale upgrade to Vue 3. The plugin handles the necessary lifecycle management and integration points to make Vue 2 components behave as native Piral extensions or pages.","status":"active","version":"1.10.3","language":"javascript","source_language":"en","source_url":"https://github.com/smapiot/piral","tags":["javascript","piral","pilet-api","smapiot","portal","modules","api","plugin","plugin-converter","typescript"],"install":[{"cmd":"npm install piral-vue","lang":"bash","label":"npm"},{"cmd":"yarn add piral-vue","lang":"bash","label":"yarn"},{"cmd":"pnpm add piral-vue","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Peer dependency for Vue 2 component rendering. Must be Vue 2.x.","package":"vue","optional":false}],"imports":[{"note":"This function is used in your Piral instance's `createInstance` plugins array to enable Vue 2 support for pilets. Piral primarily uses ESM.","wrong":"const createVueApi = require('piral-vue');","symbol":"createVueApi","correct":"import { createVueApi } from 'piral-vue';"},{"note":"This TypeScript interface extends the standard PiletApi with Vue 2-specific functions like `fromVue`. Use `import type` for type-only imports to avoid bundling type definitions.","wrong":"import { PiletVueApi } from 'piral-vue';","symbol":"PiletVueApi","correct":"import type { PiletVueApi } from 'piral-vue';"},{"note":"Refers to the Piral-specific wrapper type for Vue components, ensuring correct integration into the microfrontend context. This is not the raw Vue component constructor directly from the `vue` package.","wrong":"import { VueComponent } from 'vue';","symbol":"VueComponent","correct":"import type { VueComponent } from 'piral-vue';"}],"quickstart":{"code":"import type { PiletApi } from 'piral';\nimport { defineComponent } from 'vue'; // Ensure vue@2 is a dependency in your pilet\n\n// Extend PiletApi with piral-vue specific functions provided by the Piral instance.\n// This assumes 'piral-vue' has been configured in the Piral instance's createInstance call.\ninterface MyPiletApi extends PiletApi {\n  fromVue(component: any): any; // The actual type is VueComponentConverter<VueComponent>\n}\n\n// Define a simple Vue 2 component\nconst MyVueComponent = defineComponent({\n  name: 'MyVueComponent',\n  props: {\n    message: {\n      type: String,\n      default: 'Hello from Vue 2 Pilet!',\n    },\n  },\n  template: `\n    <div style=\"padding: 10px; border: 1px solid #42b983; margin: 10px; border-radius: 5px;\">\n      <h3>{{ message }}</h3>\n      <p>This is a Vue 2 component served by a Pilet.</p>\n      <button @click=\"increment\">Count: {{ count }}</button>\n    </div>\n  `,\n  data() {\n    return {\n      count: 0,\n    };\n  },\n  methods: {\n    increment() {\n      this.count++;\n    },\n  },\n});\n\n/**\n * The setup function for the Pilet.\n * It registers a Vue component as an extension and a page within the Piral application.\n */\nexport function setup(app: MyPiletApi) {\n  // Register the Vue component as an extension.\n  // It can be embedded anywhere in the Piral app using <Extension name=\"vue-pilet-card\" />.\n  app.registerExtension('vue-pilet-card', app.fromVue(MyVueComponent));\n\n  // Register the Vue component as a full page, accessible via a route.\n  app.registerPage('/vue-pilet-page', app.fromVue(MyVueComponent));\n\n  console.log('Vue 2 Pilet: MyVueComponent registered as extension \"vue-pilet-card\" and page \"/vue-pilet-page\".');\n}\n","lang":"typescript","description":"Demonstrates how a Pilet uses `piral-vue` to define and register a Vue 2 component as both a Piral extension and a full page. This quickstart assumes `piral-vue` has been configured in the main Piral instance."},"warnings":[{"fix":"For Vue 3 projects, use the dedicated `piral-vue3` package. Ensure your Pilet's `package.json` specifies `vue@^2.x` and that your Piral instance is consistently configured for Vue 2.","message":"This `piral-vue` package is strictly designed for Vue 2.x applications. Attempting to use it with Vue 3.x or newer will result in runtime errors due to significant API changes between Vue major versions.","severity":"breaking","affected_versions":">=1.0.0"},{"fix":"Utilize Piral's built-in event bus (`app.on(...)`, `app.emit(...)`) or Piral's global state management (`app.readState(...)`, `app.updateState(...)`) for communication and state sharing between pilets. Each Vue Pilet should manage its own local Vuex store if needed.","message":"Vue components registered through `piral-vue` operate within isolated contexts. Relying on global Vue instances or directly modifying globally shared state (e.g., a single Vuex store) across multiple pilets can lead to unpredictable behavior, state collisions, or memory leaks.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Employ robust CSS methodologies like BEM within your Vue components, use CSS Modules, or leverage Piral's built-in CSS isolation features (if available). Regularly review generated CSS to prevent unintended style bleed, and consider using shadow DOM for stricter encapsulation.","message":"While Vue components often use scoped CSS, integration into a microfrontend shell can still lead to styling conflicts. Global styles from the Piral shell or other pilets might unintentionally affect Vue 2 components, and vice-versa.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Verify that `vue@^2.x` is correctly installed in your pilet's `package.json` and that your component definitions strictly adhere to the Vue 2 API. If you intend to use Vue 3, switch to `piral-vue3` instead of `piral-vue`.","cause":"This error typically occurs when a Vue 3 component or API is mistakenly used within a Vue 2 context (or vice versa), or when Vue 2 is not properly loaded/available. The `extend` method is specific to Vue 2's component definition.","error":"TypeError: Cannot read properties of undefined (reading 'extend')"},{"fix":"Ensure your Vue 2 component definition includes either a `template` property (as a string) or a `render` function. Double-check for any syntax errors in your component's options object or if a build step (like a Vue loader) failed to process the component correctly.","cause":"This common Vue 2 error indicates that the component object passed to `app.fromVue()` is missing either a `template` string or a `render` function, both of which are essential for Vue to render the component.","error":"Failed to mount component: template or render function not defined."}],"ecosystem":"npm"}