tobidev's avatar
Level 5

Laravel PDF/File/Image Viewer

Does anyone here have experience displaying PDFs, emails (.msg, .eml), and images in Laravel? Preferably with Lightbox and Livewire support? Does anyone happen to know of a package I can install? For images, it should be possible to add arrows or annotations.

Thanks for sharing your experiences and for your help!

0 likes
2 replies
LaryAI's avatar
Level 58

Solution:

You have a few requirements:

  • Display PDFs, images, and email files (.msg, .eml)
  • Lightbox support
  • Laravel Livewire compatibility
  • For images: ability to add arrows/annotations

Let’s address each point:


1. Viewing PDFs

PDF.js is a widely-used JavaScript library to display PDFs. You can easily integrate it with Livewire and Laravel.

Install pdfjs-dist:

npm install pdfjs-dist

Frontend usage: Use a dedicated JS component (or an existing Vue/React component) to render your PDFs. You can trigger modal/lightbox display with Alpine.js or any lightbox library.


2. Viewing Images (with Annotations)

For images, Annotorious or Fabric.js let you draw shapes, arrows, highlights, etc.

Example (with Annotorious):

<img id="your-image" src="/path/to/image.jpg" />
<script src="https://cdn.jsdelivr.net/npm/@recogito/[email protected]/dist/annotorious.min.js"></script>
<script>
  var anno = Annotorious.init({
    image: 'your-image'
  });
</script>

3. Lightbox Integration

Use Fancybox or Lightbox2 to show PDFs and images in a modal/overlay. Most are easy to trigger from Livewire components.

Example:

<a data-fancybox="gallery" href="/path/to/image.jpg">
  <img src="/path/to/thumb.jpg" />
</a>

For PDFs, link a button to open a modal/lightbox with a custom <iframe> or PDF.js viewer.


4. Livewire Compatibility

  • Use Livewire to list files and handle user interactions (e.g., selecting which file to view).
  • Emit events from Livewire to JS for modal/lightbox opening.

Example (Livewire Blade):

@foreach($files as $file)
    <button wire:click="openFile({{ $file->id }})">
        View {{ $file->name }}
    </button>
@endforeach

JavaScript:

// Listen for Livewire events
Livewire.on('openFileModal', fileUrl => {
    // Open modal/lightbox and load either image, PDF, or email preview
});

5. .msg/.eml Email Files

There is no solid JS viewer for .msg/.eml, but you can convert them to HTML server-side:

Sample:

use PhpMimeMailParser\Parser;

$parser = new Parser();
$parser->setPath($pathToEmlFile);

$htmlContent = $parser->getMessageBody('html');
// Pass $htmlContent to your view

6. Packages

There isn’t a single Laravel package that does all this, but here’s how you can combine:

  • PDF display: Use PDF.js JS library
  • Images with annotation: Annotorious or Fabric.js
  • Lightbox/modal: Fancybox, Lightbox2, or similar
  • Livewire: Integrate with your component logic and wire up JS modals
  • Email rendering: php-mime-mail-parser (backend) + your own modal

7. Summary Example

List files with Livewire:

@foreach($files as $file)
    <a href="#" wire:click.prevent="viewFile({{ $file->id }})">
        {{ $file->name }}
    </a>
@endforeach

<!-- Modal area where your PDF/Image/Email will display -->
<div id="viewer-modal" style="display:none;">
    <!-- Dynamic content inserted by JS based on file type -->
</div>

Livewire Component:

public function viewFile($fileId)
{
    $file = File::findOrFail($fileId);

    if ($file->isEmlOrMsg()) {
        // Parse and emit email content
        $html = $this->parseEmail($file->path);
        $this->dispatchBrowserEvent('open-viewer-modal', [
            'content' => $html,
            'type' => 'email'
        ]);
    } elseif ($file->isPdf()) {
        $this->dispatchBrowserEvent('open-viewer-modal', [
            'url' => $file->url,
            'type' => 'pdf'
        ]);
    } elseif ($file->isImage()) {
        $this->dispatchBrowserEvent('open-viewer-modal', [
            'url' => $file->url,
            'type' => 'image'
        ]);
    }
}

Javascript:

window.addEventListener('open-viewer-modal', event => {
    const { url, content, type } = event.detail;
    // Use PDF.js for PDF, Annotorious/Fabric.js for image, basic display for email
    // Show modal/lightbox as needed
});

8. Final Tips

  • You might have to do some wiring between Livewire and JS for optimal UX.
  • Security tip: ALWAYS sanitize and validate emails/html before rendering!

References:

Let me know if you want a more detailed code example for your specific use case!

imrandevbd's avatar

Since you're likely using Livewire 3, avoid Lary's advice of dispatching events from the backend just to open a modal. Keep that state on the frontend with Alpine

Please or to participate in this conversation.