---
title: "Add PDF functionality with Nuxt"
canonical_url: "https://www.nutrient.io/sdk/web/getting-started/other-frameworks/nuxt/"
md_url: "https://www.nutrient.io/sdk/web/getting-started/other-frameworks/nuxt.md"
last_updated: "2026-06-08T09:14:14.525Z"
description: "Learn how to integrate Nutrient Web SDK into your Nuxt application. Step-by-step guide for adding PDF viewing, editing, and annotation features."
---

# Add PDF functionality with Nuxt

Nutrient Web SDK is a JavaScript PDF library for viewing, annotating, and editing PDFs directly in the browser. Use it to add PDF capabilities to any web app.

This guide walks you through the steps to integrate Nutrient Web SDK into your project. By the end, you’ll be able to render a PDF document in the user interface (UI).

**Test without installing**

You can test the SDK capabilities in our playground.

[Read more](https://nutrient.io/demo/sandbox)

**Jump to example**

Prefer to jump straight to code? View the example repo on GitHub.

[Read more](https://github.com/PSPDFKit/nutrient-examples/tree/main/examples/nuxtjs)

## Project setup

#### Note: Creating a new project (optional)

If you don’t yet have a Nuxt project set up, create one with:

```sh

npx nuxi@latest init nutrient-nuxt-example

```

## Rendering a PDF

**Steps:**

1. In the `components` folder, create a `NutrientContainer.vue` file with the following content. This creates a component wrapper for the Nutrient library:

   ```js

   <template>
     <div class="pdf-container"></div>
   </template>

   <script>
   let loadPromiseResolve;

   const loadPromise = new Promise((resolve) => {
     loadPromiseResolve = resolve;
   });

   useHead({
     script: [
       {
         src: "https://cdn.cloud.nutrient.io/pspdfkit-web@1.16.1/nutrient-viewer.js",
         type: "text/javascript",
         onload: () => loadPromiseResolve(),
       },
     ],
   });

   /**
   * Nutrient Web SDK example component.
   */
   export default {
     name: "Nutrient",
     /**
     * The component receives `pdfFile` as a prop, which is type of `String` and is required.
     */
     props: {
       pdfFile: {
         type: String,
         required: true,
       },
     },
     Nutrient: null,
     /**
     * We wait until the template has been rendered to load the document into the library.
     */
     mounted() {
       loadPromise.then(() => {
         this.loadNutrient().then((instance) => {
           this.$emit("loaded", instance);
         });
       });
     },
     /**
     * We watch for `pdfFile` prop changes and trigger unloading and loading when there's a new document to load.
     */
     watch: {
       pdfFile(val) {
         if (val) {
           this.loadNutrient();
         }
       },
     },
     /**
     * Our component has the `loadNutrient` method. This unloads and cleans up the component and triggers document loading.
     */
     methods: {
       async loadNutrient() {
         if (this.Nutrient) {
           this.Nutrient.unload(".pdf-container");
         }

         this.Nutrient = window.NutrientViewer;

         return window.NutrientViewer.load({
           document: this.pdfFile,
           container: ".pdf-container",
           useCDN: true,
         });
       },
     },
   };
   </script>

   <style scoped>.pdf-container {
     height: 100vh;
   }
   </style>
   ```

   > **Note:** Adding `useCDN: true` will load the SDK assets from the CDN if `baseUrl` isn’t provided. This flag was introduced in version 1.9.0. If your setup relies on the previous behavior of autodetecting the assets without `baseUrl`, you can omit this flag for now, but be aware that this behavior is deprecated. In future versions, loading from CDN will become a default when `baseUrl` isn’t explicitly provided. `useCDN: true` has no effect if `baseUrl` is set.

2. Add the newly created component to the `pages/index.vue` file:

   ```js

   <template>
     <div id="app">
       <label for="file-upload" class="custom-file-upload"> Open PDF </label>
       <input id="file-upload" type="file" @change="openDocument" class="btn" />
       <NutrientContainer :pdfFile="pdfFile" @loaded="handleLoaded" />
     </div>
   </template>

   <script>
   import NutrientContainer from "../components/NutrientContainer.vue";

   export default {
     name: "app",
     /**
     * Render the `NutrientContainer` component.
     */
     components: {
       NutrientContainer,
     },

     data() {
       return {
         pdfFile: this.pdfFile || "https://www.nutrient.io/downloads/nutrient-web-demo.pdf",
       };
     },

     /**
     * Our component has two methods — one to check when the document is loaded, and the other to open the document.
     */
     methods: {
       handleLoaded(instance) {
         console.log("Nutrient has loaded: ", instance);
         // Do something.
       },

       openDocument(event) {
         if (this.pdfFile?.startsWith("blob:")) {
           window.URL.revokeObjectURL(this.pdfFile);
         }
         this.pdfFile = window.URL.createObjectURL(event.target.files[0]);
       },
     },
   };
   </script>

   <style>
   #app {

     font-family: Avenir, Helvetica, Arial, sans-serif;
     text-align: center;
     color: #2c3e50;

     display: flex;
     flex-direction: column;
     height: 100vh;
   }

   body {
     margin: 0;
   }

   input[type="file"] {
     display: none;
   }.custom-file-upload {
     border: 1px solid #ccc;

     border-radius: 4px;
     display: inline-block;
     padding: 6px 12px;
     cursor: pointer;
     background: #4a8fed;

     padding: 10px;
     color: #fff;

     font: inherit;
     font-size: 16px;
     font-weight: bold;
     margin: auto;
   }.pdf-container {
     flex: 1;
   }
   </style>
   ```

3. Start the development server:

   ```bash

   npm run dev
   # or

   yarn dev
   # or

   pnpm dev
   ```

4. You’ll see the PDF rendered in the user interface (UI).

### Optimizing load performance

If your app doesn't open a PDF immediately — for example, the user navigates to a viewer on a different page — call [`NutrientViewer.preloadWorker()`](https://www.nutrient.io/api/web/functions/NutrientViewer.preloadWorker.html) early in your app to fetch and compile the WebAssembly artifacts in the background. When `NutrientViewer.load()` runs later, it can start rendering without waiting for them.

```js

// Call early — for example, on app init or after login.
NutrientViewer.preloadWorker();

```

Refer to the [performance best practices](https://www.nutrient.io/guides/web/best-practices/performance.md) guide for more optimization techniques.




## Troubleshooting

**Example**

View the example repo on GitHub.

[Read more](https://github.com/PSPDFKit/nutrient-examples/tree/main/examples/nuxtjs)

**Facing issues?**

Visit the troubleshooting guide for solutions to some common errors.

[Read more](https://www.nutrient.io/guides/web/troubleshooting/common-issues.md)
---

## Related pages

- [Add PDF functionality with PHP](/sdk/web/getting-started/other-frameworks/php.md)
- [Add PDF functionality with JavaScript + Vite](/sdk/web/getting-started/other-frameworks/javascript.md)
- [Add PDF functionality with Flutter](/sdk/web/getting-started/other-frameworks/flutter.md)
- [Add PDF functionality with ASP.NET](/sdk/web/getting-started/other-frameworks/aspnet.md)
- [Add PDF functionality with Laravel](/sdk/web/getting-started/other-frameworks/laravel.md)
- [Add PDF functionality with PWA](/sdk/web/getting-started/other-frameworks/pwa.md)
- [Add PDF functionality with Svelte](/sdk/web/getting-started/other-frameworks/svelte.md)
- [Add PDF functionality with jQuery](/sdk/web/getting-started/other-frameworks/jquery.md)
- [Add PDF functionality with Electron](/sdk/web/getting-started/other-frameworks/electron.md)
- [Add PDF functionality with Blazor](/sdk/web/getting-started/other-frameworks/blazor.md)
- [Add PDF functionality with Angular](/sdk/web/getting-started/other-frameworks/angular.md)
- [Add PDF viewing and editing to Vue applications](/sdk/web/getting-started/other-frameworks/vue.md)

