Yesterday I was trying to tweak the invoice design for Addrow, a SaaS application I made with Laravel. I have basically two templates for the invoice, one for web display and a PDF-version.
I tried to use one template for both versions, but using Dompdf I found myself having to tweak quite a lot to get the PDF anywhere near the HTML-version so ended up with two separate versions.
As I was trying to tweak the design, I decided to look for alternatives to Dompdf and try to get to a situation where I only needed to maintain one template file. I then stumbled upon this tweet by David Hemphill.
Generating PDFs with @vuejs components: I have a public invoice "print" view, styled with @tailwindcss, and served by a @vuejs SPA. I'm using spatie/browsershot to hit the page and generate a PDF download response of that public page: pic.twitter.com/yIXXCk7Nge
And that sort of blew my mind. David is using Spatie's Browsershot package to utilize the headless version of Chrome and generate a PDF download that way. A massive advantage is the template reusability and the PDF looks pretty darn close to the web-version. I can also use TailwindCSS to style the invoice. Pretty cool!
The package requires you to have Node and the Puppeteer library installed. But that is pretty easy to install. The package readme file, even includes instructions how to install this on a Forge provisioned server which is exactly my use case.
What does the code look like?
You can get the idea from David's screenshot, but I thought it would be nice to share some more code to give an indication of how I implemented this. I have added a pdf method on my Invoice class like this:
In the end I am very happy with this refactor. I can now use one template and use TailwindCSS for styling. Thanks to Spatie for providing this package and David for mentioning this on Twitter. Also, thanks to Dompdf since I've used this for years and in a lot cases it might very well still be the way to go.