Skip to content

Stream Saver Plugin ​

File Information ​

  • Path: app/plugins/stream-saver.client.ts
  • Purpose: Configure StreamSaver for large file downloads
  • Type: Client-only (runs only in browser)
  • Load Order: 6

Overview ​

The Stream Saver plugin configures StreamSaver.js for handling large file downloads using the Streams API. This allows downloading large files without loading them entirely into memory, making it ideal for downloading large assets.

Key Features ​

  1. Stream-Based Downloads

    • Downloads files as streams
    • Doesn't load entire file into memory
    • Efficient for large files
  2. Large File Support

    • Handles files of any size
    • Prevents memory issues
    • Better performance
  3. Global Availability

    • Available as $streamSaver
    • Type-safe TypeScript definitions
    • Easy to use throughout app

Code Structure ​

typescript
import StreamSaver from 'streamsaver'
import { defineNuxtPlugin } from '#app'

export default defineNuxtPlugin((nuxtApp) => {
  // Expose as $streamSaver
  nuxtApp.provide('streamSaver', StreamSaver)
})

declare module '#app' {
  interface NuxtApp {
    $streamSaver: typeof StreamSaver
  }
}

declare module 'vue' {
  interface ComponentCustomProperties {
    $streamSaver: typeof StreamSaver
  }
}

Usage Examples ​

Basic Download ​

typescript
const { $streamSaver } = useNuxtApp()

// Create writable stream
const fileStream = $streamSaver.createWriteStream('filename.jpg')

// Fetch file and pipe to stream
fetch('/api/file/download')
  .then(response => response.body)
  .then(body => body.pipeTo(fileStream))

Download with Progress ​

typescript
const { $streamSaver } = useNuxtApp()

const fileStream = $streamSaver.createWriteStream('large-file.zip')

fetch('/api/file/download')
  .then(response => {
    const reader = response.body.getReader()
    const stream = new ReadableStream({
      start(controller) {
        function pump() {
          return reader.read().then(({ done, value }) => {
            if (done) {
              controller.close()
              return
            }
            controller.enqueue(value)
            return pump()
          })
        }
        return pump()
      }
    })
    return stream
  })
  .then(stream => stream.pipeTo(fileStream))

Using in Composable ​

typescript
const { $streamSaver } = useNuxtApp()

async function downloadLargeFile(url: string, filename: string) {
  const fileStream = $streamSaver.createWriteStream(filename)
  const response = await fetch(url)
  const stream = response.body
  await stream.pipeTo(fileStream)
}

StreamSaver API ​

createWriteStream(filename, options?) ​

Create a writable stream for file download.

Parameters:

  • filename: string - Name of the file to download
  • options?: object - Optional configuration

Returns: WritableStream

Configuration Options ​

  • size?: number - File size (for progress calculation)
  • writableStrategy?: object - Stream strategy
  • readableStrategy?: object - Stream strategy

Browser Support ​

StreamSaver requires:

  • Streams API - Modern browser support
  • Service Worker - For secure downloads (optional)
  • File System Access API - For better UX (optional)

Security Considerations ​

  • Downloads are initiated by user action
  • Files saved to user's download folder
  • No arbitrary file system access
  • Respects browser download settings

Dependencies ​

  • streamsaver - Stream-based file download library

Notes for Development ​

  • Client-only plugin (.client.ts suffix)
  • Available globally as $streamSaver
  • TypeScript definitions included
  • Ideal for large file downloads
  • Prevents memory issues with large files