Vue Document Preview Component
Vue-doc-preview is a Vue.js component designed to embed and display various document types directly within a web application. It supports rendering markdown, plain text, code with syntax highlighting, and can even fetch and display office documents (docx, pptx, xlsx) from a provided URL. The current stable version is 0.3.2, with recent minor releases indicating active development and feature additions like URL-based document loading and request configuration since v0.3.0. A key differentiator is its ability to handle multiple formats and integrate custom styling for markdown and text, while maintaining a relatively small footprint. It offers flexibility by allowing content to be passed directly via a `value` prop or fetched remotely via a `url` prop.
Common errors
-
Module not found: Error: Can't resolve 'vue-doc-preview' in '[path/to/your/project]' or Cannot find module 'vue-doc-preview'
cause The `vue-doc-preview` package has not been installed, or your package manager's cache is corrupted, or it's not correctly listed in `node_modules`.fixRun `npm install vue-doc-preview` or `yarn add vue-doc-preview` in your project directory to install the package. -
Property or method 'VueDocPreview' is not defined on the instance but referenced during render. Make sure to declare reactive data properties in the data option.
cause The `VueDocPreview` component has been imported into your `.vue` file's `<script>` section but has not been registered with your Vue component's `components` option.fixEnsure your component's `<script>` section explicitly registers it: `export default { components: { VueDocPreview }, ... }`. -
Document content is not updating or displaying from a new URL after a prop change, even though the `url` prop is being updated.
cause This often occurs because the `value` prop is still set to a non-empty string, which takes priority over `url`. The component will continuously render content from `value`.fixWhen you want to switch to loading from `url`, make sure to set the `value` prop to an empty string (`''`) or `null`. -
When attempting to load an office document from a `url`, the browser console shows CORS errors (e.g., 'No 'Access-Control-Allow-Origin' header is present').
cause The server hosting the document at the specified `url` is not configured to allow cross-origin requests from your application's domain. The browser blocks the request for security reasons.fixEnsure the server hosting the document sends the appropriate `Access-Control-Allow-Origin` HTTP headers, allowing your domain to fetch the resource. If you control the server, configure it for CORS. If not, you may need to proxy the request through your own backend or use a `value` prop with pre-fetched content.
Warnings
- gotcha The `value` prop takes precedence over the `url` prop. If both are provided and `value` is non-empty, the `url` will be ignored, and content will be rendered directly from `value`.
- gotcha Custom styling is applied using specific props: `mdStyle` for documents of `type='markdown'` or `type='code'`, and `textStyle` for `type='text'`. Using the wrong style prop for the document type will have no effect.
- gotcha The `height` prop interprets its value based on magnitude: if `height` > 100, it's treated as pixels (`px`); otherwise, it's treated as a percentage (`%`). This can lead to unexpected sizing if not carefully managed.
- gotcha Office document rendering for formats like `docx`, `pptx`, `xlsx` typically relies on internal processing that might involve external services or browser capabilities. While the component fetches the document via `url`, the actual display quality and feature support can vary and might not always replicate a native office application view. Publicly accessible URLs with appropriate CORS headers are crucial for fetching.
- gotcha Code highlighting is powered by `highlight.js`. The component includes a default set of languages, but if you need to support additional languages or apply a custom `highlight.js` theme, you may need to extend or modify the internal `highlight.js` configuration as hinted in the README (e.g., `src/lib/highlight.js`).
Install
-
npm install vue-doc-preview -
yarn add vue-doc-preview -
pnpm add vue-doc-preview
Imports
- VueDocPreview
const VueDocPreview = require('vue-doc-preview')import VueDocPreview from 'vue-doc-preview'
Quickstart
<template>
<div style="padding: 20px; font-family: sans-serif;">
<h1>Document Previews</h1>
<h2>Markdown Preview</h2>
<VueDocPreview
:value="markdownContent"
type="markdown"
:mdStyle="mdStyle"
style="border: 1px solid #ddd; border-radius: 6px; padding: 15px; margin-bottom: 30px; background-color: #fff;"
/>
<h2>Office Document from URL</h2>
<!-- Note: Ensure the URL is publicly accessible and provides appropriate CORS headers for preview. -->
<VueDocPreview
url="https://newteach.pbworks.com/f/ele%20newsletter.docx"
type="office"
height="500"
style="border: 1px solid #ddd; border-radius: 6px; margin-bottom: 30px; background-color: #f9f9f9;"
/>
<h2>Code Preview (TypeScript)</h2>
<VueDocPreview
:value="codeSnippet"
type="code"
language="typescript"
style="border: 1px solid #ddd; border-radius: 6px; padding: 15px; margin-bottom: 30px; background-color: #2d2d2d; color: #f8f8f2;"
/>
</div>
</template>
<script>
import VueDocPreview from 'vue-doc-preview'
export default {
components: {
VueDocPreview
},
data() {
return {
markdownContent: "# VueDocPreview Demo\n\nThis is a **markdown** test with `code snippets`.\n\n```javascript\nfunction helloWorld() {\n console.log('Hello from VueDocPreview!');\n}\n\nhelloWorld();\n```\n\n- List item one\n- List item two\n\nA blockquote example:\n> This is a quote.\n",
mdStyle: {
pre: {
'background-color': '#282c34',
'color': '#abb2bf',
'padding': '1em',
'border-radius': '6px',
'overflow-x': 'auto'
},
code: {
'color': '#abb2bf',
'font-family': 'monospace',
'font-size': '0.9em'
}
},
codeSnippet: `interface User {
id: number;
name: string;
email?: string;
}
const users: User[] = [
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob', email: 'bob@example.com' }
];
function findUserById(id: number): User | undefined {
return users.find(user => user.id === id);
}
console.log(findUserById(1));
`
}
}
}
</script>