Home / Docs / Usage / HTML to Image Laravel Package

HTML to Image Laravel package

The official Laravel package wraps the HTML to Image API in an auto-registered facade with a published config file, filesystem storage helpers, and typed request and response objects. It builds on the PHP SDK and adds the Laravel conveniences — config, service container binding, and an artisan command to verify your setup.

Best for: Laravel apps that want a facade, config file and disk-aware storage helpers out of the box. If you would rather call the API directly with the Http facade, see the raw Laravel guide.

The package is open source on GitHub: html2img/html2img-laravel.

Requirements

  • PHP 8.3 or newer
  • Laravel 11 or 12
  • An API key — see the quick start if you don’t have one yet

Installation

Install the package with Composer. The service provider and facade register automatically:

composer require html2img/html2img-laravel

Add your API key to .env:

HTML2IMG_API_KEY=your-api-key

Optionally publish the config file:

php artisan vendor:publish --tag=html2img-config

Configuration

The published config/html2img.php looks like this:

return [
    'api_key'  => env('HTML2IMG_API_KEY'),
    'base_uri' => env('HTML2IMG_BASE_URI', 'https://app.html2img.com'),
    'timeout'  => env('HTML2IMG_TIMEOUT', 35),
    'storage'  => [
        'disk' => env('HTML2IMG_DISK'),
    ],
];

Verify your setup

Run the built-in command to confirm your API key works. It prints the resulting image URL and your remaining credits, or an error if misconfigured:

php artisan html2img:test

Converting HTML to an image

Use the Html2img facade with an HtmlRequest. You can render a Blade view straight into the request:

use Html2img\Laravel\Facades\Html2img;
use Html2img\Request\HtmlRequest;

$response = Html2img::html(new HtmlRequest(
    html: view('og.post', ['post' => $post])->render(),
    css: 'body { background: #0f172a; color: #fff; }',
    width: 1200,
    height: 630,
    dpi: 2,
));

return $response->url;

Taking a screenshot

use Html2img\Laravel\Facades\Html2img;
use Html2img\Request\ScreenshotRequest;

$response = Html2img::screenshot(new ScreenshotRequest(
    url: 'https://example.com',
    width: 1200,
    height: 630,
    selector: '#hero',
    css: '.cookie-banner { display: none !important; }',
    dpi: 2,
));

Rendering a template

Skip the HTML step with a named template. Pass the slug and a data array:

$response = Html2img::template('invoice-image', [
    'number'   => 1042,
    'amount'   => '£240.00',
    'due_date' => '2026-07-01',
]);

Storing and downloading images

The package can save a rendered image straight to a filesystem disk, or hand you the raw bytes:

// Store on the default disk (or the one set via HTML2IMG_DISK)
$path = Html2img::store($response, "og/{$post->id}.png");

// Store on a specific disk
Html2img::store($response, "og/{$post->id}.png", 's3');

// Get the raw image bytes without storing
$bytes = Html2img::download($response);

Queued job example

Rendering in a queued job keeps image generation off the request cycle. Inject the Html2img manager and it resolves from the container:

use Html2img\Laravel\Html2img;
use Html2img\Request\HtmlRequest;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Queue\Queueable;

class GenerateOgImage implements ShouldQueue
{
    use Queueable;

    public function __construct(public Post $post) {}

    public function handle(Html2img $html2img): void
    {
        $response = $html2img->html(new HtmlRequest(
            html: view('og.post', ['post' => $this->post])->render(),
            width: 1200,
            height: 630,
        ));

        $this->post->update([
            'og_image_path' => $html2img->store($response, "og/{$this->post->id}.png"),
        ]);
    }
}

The response object

Every method returns a readonly RenderResponse:

$response->success;          // bool
$response->id;               // string|null
$response->url;              // string|null (CDN URL)
$response->creditsRemaining; // int|null
$response->status;           // string|null ("processing" for async)
$response->message;          // string|null
$response->isProcessing();   // bool
$response->raw();            // array (full JSON payload)

Error handling

All API errors throw Html2img\Exception\Html2imgException or a specific subclass:

use Html2img\Exception\{Html2imgException, ValidationException, InsufficientCreditsException};

try {
    $response = Html2img::html(new HtmlRequest(html: $document));
} catch (ValidationException $e) {
    foreach ($e->details() as $field => $messages) { /* handle per-field errors */ }
} catch (InsufficientCreditsException $e) {
    $left = $e->creditsRemaining();
} catch (Html2imgException $e) {
    $e->statusCode();
    $e->errorCode();
    $e->payload();
}