{"id":15037,"library":"vue-letter","title":"Vue Letter Email Display Component","description":"Vue-letter is a Vue.js component designed for displaying HTML or plain text email messages within Vue applications. It functions as a direct port of the `react-letter` library, offering features like wrapping content in an iframe, rewriting external resource and link URLs, and specifying allowed URL schemas. The package helps developers render email bodies while addressing potential security and styling concerns. Currently at an early version (0.2.1), it is under active development, implying its API and features are still evolving. Its main purpose is to simplify the secure rendering of email content, particularly targeting rendering compatibility similar to Gmail's approach.","status":"active","version":"0.2.1","language":"javascript","source_language":"en","source_url":"https://github.com/mat-sz/vue-letter","tags":["javascript","vue","vue-component","email","e-mail","mail","mime-message","ui","typescript"],"install":[{"cmd":"npm install vue-letter","lang":"bash","label":"npm"},{"cmd":"yarn add vue-letter","lang":"bash","label":"yarn"},{"cmd":"pnpm add vue-letter","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Peer dependency as it's a Vue.js component.","package":"vue","optional":false},{"reason":"Internally used for DOM-based HTML email sanitization.","package":"lettersanitizer","optional":false}],"imports":[{"note":"The component is designed for Vue 3's Composition API (`<script setup>`) and modern ESM environments. CommonJS `require` is not supported for direct component import.","wrong":"const Letter = require('vue-letter');","symbol":"Letter","correct":"import { Letter } from 'vue-letter';"}],"quickstart":{"code":"<script setup>\n  import { Letter } from 'vue-letter';\n</script>\n\n<template>\n  <div id=\"app\">\n    <Letter html=\"<p>Hello <strong>World</strong>!</p><img src='https://example.com/logo.png'>\" />\n    <Letter text=\"This is a plain text email. Line breaks should be preserved.\" />\n    <Letter\n      :html=\"`<p style='color: red;'>Malicious script: <script>alert('XSS')</script></p>`\"\n      :useIframe=\"true\"\n      iframeTitle=\"Email Subject\"\n      :rewriteExternalLinks=\"(url) => `https://example.com/redirect?url=${encodeURIComponent(url)}`\"\n      :allowedSchemas=\"['http', 'https']\"\n    />\n  </div>\n</template>","lang":"typescript","description":"This quickstart demonstrates importing and using the `Letter` component to display HTML and plain text email content, including advanced props for iframe usage, link rewriting, and schema control."},"warnings":[{"fix":"Pin exact versions (e.g., `\"vue-letter\": \"0.2.1\"`) in `package.json` to prevent unexpected breaking changes on update. Regularly check the GitHub repository for updates and migration guides.","message":"The package is at an early version (0.2.1), which means its API is highly unstable and subject to significant breaking changes in minor or even patch releases. Developers should pin to exact versions and review changelogs closely for updates.","severity":"breaking","affected_versions":">=0.1.0"},{"fix":"Always pre-sanitize untrusted HTML input using a robust, well-maintained library like `DOMPurify` before passing it to the `html` prop. Example: `import DOMPurify from 'dompurify'; const safeHtml = DOMPurify.sanitize(untrustedHtml);`","message":"Despite its `react-letter` origin mentioning 'automatic sanitization', `vue-letter`'s README explicitly labels the `html` and `text` props as taking 'Unsanitized e-mail HTML contents'. This creates a critical security ambiguity. Users MUST assume the component does not perform sufficient sanitization and are responsible for pre-sanitizing any untrusted HTML or text input to prevent Cross-Site Scripting (XSS) vulnerabilities.","severity":"gotcha","affected_versions":">=0.1.0"},{"fix":"Carefully consider the trade-offs of using `useIframe`. If used, ensure robust CSS within the email content itself handles responsiveness, or implement post-load JavaScript to adjust iframe dimensions if necessary. Use the `iframeTitle` prop for accessibility.","message":"The `useIframe` prop, when set to `true`, wraps the email content in an `<iframe>`. While this provides strong style isolation, it can introduce challenges for responsive design, inter-frame communication, and accessing elements within the iframe from the parent application.","severity":"gotcha","affected_versions":">=0.1.0"},{"fix":"Explicitly configure the `allowedSchemas` array to only include the minimum necessary URL schemes for your application's security policy. For example, to disallow `mailto`, remove it from the array.","message":"The `allowedSchemas` prop defaults to `['http', 'https', 'mailto']`. Depending on the application's security requirements, this list might be too permissive or too restrictive, potentially allowing unintended protocols or blocking necessary ones.","severity":"gotcha","affected_versions":">=0.1.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Ensure `import { Letter } from 'vue-letter';` is present in your `<script setup>` block or in the component's script section. If not using `<script setup>`, register it globally with `app.component('Letter', Letter)` or locally in your component's `components` option.","cause":"The `Letter` component was not correctly imported or registered in your Vue application. This typically happens in Single File Components (SFCs) if the import path is wrong or in non-SFC setups if `app.component('Letter', Letter)` is missing.","error":"Failed to resolve component: Letter"},{"fix":"Verify that you are passing `html` and `text` props as `String` types, as specified in the component's attributes. Ensure your TypeScript setup correctly recognizes the `vue-letter` types. If you're on an older Vue/TypeScript version, updating might resolve the issue, or you might need to cast the prop type temporarily.","cause":"This TypeScript error indicates that you might be passing properties to the `Letter` component that are not explicitly defined in its type declarations, or there's a type mismatch for the `html` or `text` prop.","error":"Property 'html' / 'text' does not exist on type 'IntrinsicAttributes & ...'"}],"ecosystem":"npm"}