1

Problem

I have an issue with generating PDFs via Browsershot on a queue. The PDFs do not load any images or stylesheets for some reason however, when generating the same PDF via a browser request the images and stylesheets are loaded as expected.

I suspect the issue is related to the paths used for the images and styles, but I'm not sure beyond that.

The first image shows the expected output, and the second shows what the actual output looks like. Here is the expected output when generated via a web request.

This is the actual output when generated from a queue.

Tried so far

  • Checked the queue is configured properly
  • Checked for queue errors
  • Checked the css/js resources exist on the server
  • Tried various config settings for Browsershot

Browsershot code

$content = view('site-report.cover-template', ['site' => $this->site])->render();

Browsershot::html($content)
  ->waitUntilNetworkIdle()
  ->noSandbox()
  ->ignoreHttpsErrors()
  ->setNodeBinary('/usr/bin/node')
  ->setNpmBinary('/usr/bin/npm')
  ->margins(0, 2, 0, 2)
  ->format('A4')
  ->noSandbox()
  ->setOption('args', ['--disable-web-security'])
  ->showBackground()
  ->waitUntilNetworkIdle()
  ->save($targetFullPath);

PDF Blade layout

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="csrf-token" content="{{ csrf_token() }}">

    <title>{{ config('app.name', 'Laravel') }}</title>

    <!-- Fonts -->
    <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Nunito:wght@400;600;700&display=swap">

    <!-- Styles -->
    <link rel="stylesheet" href="{{ asset('css/pdf.css') }}">

    <!-- Scripts -->
    <script src="{{ asset('js/app.js') }}"></script>
</head>
[program:test_worker]
command=/RunCloud/Packages/php81rc/bin/php  /RunCloud/Packages/php81rc/bin/php /server/path/laravel/artisan queue:work database --queue=default --sleep=3 --tries=3 --timeout=1000000
redirect_stderr=true
autostart=true
autorestart=true
user=runcloud
numprocs=2
directory=/
process_name=%(program_name)s_%(process_num)s
null

Any help would be much appreciated!

thursday_dan
  • 553
  • 6
  • 17

2 Answers2

1

I had a similar issue with devfactory/imagecache.

In my case, it was because database queues run from the Laravel root "/" path, and the website (and sync queues) run from the Laravel public path "/public".

I created a github issue (that was closed with no fix). https://github.com/laravel/framework/issues/45679

My solution was to add the following to all my jobs:

if(config('queue.default') == "database" && !str_ends_with(getcwd(), 'public')) { chdir('public'); }
Keith Turkowski
  • 751
  • 7
  • 11
0

The problem with this issue is using the incorrect helper method to generate the asset paths.

In this scenario using the typical helpers from Laravel will not work as expected, e.g asset(), mix().

Instead, to get around this problem I've used the public_path() helper instead:

    <link rel="stylesheet" href="{{ asset('css/pdf.css') }}">

    <!-- Becomes this... -->

    <link rel="stylesheet" href="{{ public_path('css/pdf.css') }}">

Hope this helps anyone else with the same issue in the future!

Edit

This is only a workaround for the problem, for the root cause and an alternative solution please see the accepted answer.

thursday_dan
  • 553
  • 6
  • 17