DEV Community

sunshey
sunshey

Posted on

How to Rotate PDF Pages in the Browser with Vue 3 and pdf-lib

Rotating PDF pages seems simple, but there are important considerations around page orientation and data safety. Here's how to build a browser-based PDF rotation tool with Vue 3 and pdf-lib.

The challenge: Selective page rotation

When rotating PDF pages, you need to:

  1. Display page thumbnails with current rotation state
  2. Allow users to select specific pages
  3. Apply rotation without affecting other pages
  4. Handle the case where a page is already rotated 90° and needs another 90°

The stack

  • Vue 3 with Composition API
  • pdf-lib for PDF manipulation
  • Vite for bundling

The core implementation

<script setup lang="ts">
import { ref } from 'vue'
import { PDFDocument } from 'pdf-lib'

const file = ref<File | null>(null)
const pageRotations = ref<Map<number, number>>(new Map())
const rotating = ref(false)
const result = ref<Uint8Array | null>(null)

async function rotatePages(degrees: number) {
  if (!file.value) return
  rotating.value = true

  const arrayBuffer = await file.value.arrayBuffer()
  const pdf = await PDFDocument.load(arrayBuffer)
  const pages = pdf.getPages()

  for (const [pageIndex, rotation] of pageRotations.value) {
    const page = pages[pageIndex]
    const currentRotation = page.getRotation().angle
    page.setRotation(PDFRotation.degrees(currentRotation + rotation))
  }

  result.value = await pdf.save()
  rotating.value = false
}

function toggleRotation(pageIndex: number) {
  const current = pageRotations.value.get(pageIndex) || 0
  const newRotation = (current + 90) % 360
  const updated = new Map(pageRotations.value)
  if (newRotation === 0) {
    updated.delete(pageIndex)
  } else {
    updated.set(pageIndex, newRotation)
  }
  pageRotations.value = updated
}
</script>
Enter fullscreen mode Exit fullscreen mode

Key implementation details

1. Rotation state management

Use a Map to track which pages have non-zero rotation:

const pageRotations = ref<Map<number, number>>(new Map())
Enter fullscreen mode Exit fullscreen mode

This keeps the state lightweight — only modified pages are stored.

2. Cumulative rotation

PDF-lib stores rotation as an angle. Adding rotations is straightforward:

const currentRotation = page.getRotation().angle
page.setRotation(PDFRotation.degrees(currentRotation + rotation))
Enter fullscreen mode Exit fullscreen mode

3. Visual feedback

Show rotation state in the thumbnail:

<div
  v-for="(page, index) in totalPages"
  :key="index"
  :class="['page-item', { rotated: pageRotations.has(index) }]"
  @click="toggleRotation(index)"
>
  <img :src="thumbnails[index]" />
  <span v-if="pageRotations.has(index)" class="rotation-badge">
    {{ pageRotations.get(index) }}°
  </span>
</div>
Enter fullscreen mode Exit fullscreen mode

4. Undo support

Since pdf-lib doesn't support undo, offer a "reset all" option:

function resetAll() {
  pageRotations.value = new Map()
}
Enter fullscreen mode Exit fullscreen mode

Limitations

No undo

Once rotated, pages cannot be reverted without the original file.

Solution: Always keep a backup of the original PDF.

Large files

Very large PDFs may cause memory issues when loading thumbnails.

Solution: Load thumbnails lazily or use Web Workers for rendering.

Summary

Building a browser-based PDF rotation tool involves:

  1. Loading the PDF with pdf-lib
  2. Displaying page thumbnails with rotation state
  3. Applying rotation to selected pages only
  4. Saving and downloading the modified PDF

Try it at en.sotool.top/rotate.


Top comments (0)