PHPackages                             html2img/html2img-laravel - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Image &amp; Media](/categories/media)
4. /
5. html2img/html2img-laravel

ActiveLibrary[Image &amp; Media](/categories/media)

html2img/html2img-laravel
=========================

Official Laravel integration for the html2img HTML-to-image API: a facade, config and Storage helpers around the html2img PHP SDK.

v1.0.0(2d ago)01↑2900%MITPHPPHP ^8.3CI passing

Since Jun 7Pushed 2d agoCompare

[ Source](https://github.com/html2img/html2img-laravel)[ Packagist](https://packagist.org/packages/html2img/html2img-laravel)[ Docs](https://html2img.com)[ RSS](/packages/html2img-html2img-laravel/feed)WikiDiscussions main Synced 2d ago

READMEChangelogDependencies (7)Versions (2)Used By (0)

[![html2img — HTML to image API, rendered in real Chrome](https://camo.githubusercontent.com/f56458281ca597b90aa9a057c211e05fc011bf71c8525b908f6cccd7c992d061/68747470733a2f2f68746d6c32696d672e636f6d2f6f672d696d6167652e706e67)](https://html2img.com)

html2img for Laravel
====================

[](#html2img-for-laravel)

[![Packagist Version](https://camo.githubusercontent.com/71a9e7ddb2833755e75c85476a7ae8c62ff048b0aef75c1b03e379aaf78924e5/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f68746d6c32696d672f68746d6c32696d672d6c61726176656c)](https://packagist.org/packages/html2img/html2img-laravel)[![PHP Version](https://camo.githubusercontent.com/69770b8bcebcfdeec1d0384adea5bdd40158a30f776112ddd41c838899bcf903/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f68746d6c32696d672f68746d6c32696d672d6c61726176656c)](https://packagist.org/packages/html2img/html2img-laravel)[![Laravel Version](https://camo.githubusercontent.com/5b4bbbd656efc00058c110063bd0a69e6b26d7f0f78d57d5113e013ba49d36e9/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c61726176656c2d31312e7825323025374325323031322e782d464632443230)](https://laravel.com)[![Total Downloads](https://camo.githubusercontent.com/1b2f60da6c15f3b2240faace184fe22a7913bfccd76742098e80d00dbb668d03/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f68746d6c32696d672f68746d6c32696d672d6c61726176656c)](https://packagist.org/packages/html2img/html2img-laravel)[![License](https://camo.githubusercontent.com/b8a64297ec747e391e9f1cd5b8470efe193903df6bd1345d7a8d93469f18c801/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f68746d6c32696d672f68746d6c32696d672d6c61726176656c)](LICENSE)

The official [Laravel](https://laravel.com) integration for the [html2img.com](https://html2img.com) API. Turn HTML and CSS into images, capture screenshots of live URLs, and render named templates, all behind a clean facade with zero-config auto-discovery.

It wraps the framework-agnostic [html2img PHP SDK](https://packagist.org/packages/html2img/html2img-php) ([source](https://github.com/html2img/html2img-php)) and adds the Laravel pieces you would otherwise write yourself: a service provider, a published config file, a facade, container bindings, an artisan health check, and one-line saving of a render to any [filesystem disk](https://laravel.com/docs/filesystem).

Every render runs in real Chrome, so flexbox, grid, custom properties, web fonts and inline JavaScript behave exactly as they do in the browser. The full API reference lives in the [documentation](https://html2img.com/docs), with a Laravel-specific guide at [html2img.com/docs/usage/laravel](https://html2img.com/docs/usage/laravel).

Contents
--------

[](#contents)

- [What you can build](#what-you-can-build)
- [Requirements](#requirements)
- [Installation](#installation)
- [Configuration](#configuration)
- [Usage](#usage)
    - [Render HTML](#render-html)
    - [Capture a screenshot](#capture-a-screenshot)
    - [Render a template](#render-a-template)
- [Saving renders to a disk](#saving-renders-to-a-disk)
- [Queues and jobs](#queues-and-jobs)
- [Render options](#render-options)
- [The response](#the-response)
- [Asynchronous delivery](#asynchronous-delivery)
- [Error handling](#error-handling)
- [Verifying your setup](#verifying-your-setup)
- [Other languages](#other-languages)
- [Links](#links)

What you can build
------------------

[](#what-you-can-build)

- **Open Graph and social images**, generated per page or post. See the [Open Graph image template](https://html2img.com/templates/open-graph-image) and [Twitter/X post template](https://html2img.com/templates/twitter-post).
- **Business documents** such as [invoices](https://html2img.com/templates/invoice-image), [receipts](https://html2img.com/templates/receipt-image), [event tickets](https://html2img.com/templates/event-ticket) and [certificates](https://html2img.com/templates/certificate-of-completion).
- **Developer assets** such as [code screenshots](https://html2img.com/templates/code-screenshot) and [GitHub social previews](https://html2img.com/templates/github-social-preview).
- **URL screenshots**, full page or cropped to a single element, with CSS injection to hide cookie banners and chat widgets before capture.

Browse the [full template library](https://html2img.com/templates), or try the no-signup [browser tools](https://html2img.com/tools) to see the output before you write any code.

Requirements
------------

[](#requirements)

- PHP 8.3 or newer
- Laravel 11 or 12
- A html2img API key, issued per account from your [dashboard](https://app.html2img.com/register)

Installation
------------

[](#installation)

```
composer require html2img/html2img-laravel
```

The service provider and the `Html2img` facade are registered automatically through [package discovery](https://laravel.com/docs/packages#package-discovery). Add your API key to `.env`:

```
HTML2IMG_API_KEY=your-api-key
```

That is the whole setup. See the [authentication docs](https://html2img.com/docs/authentication) for issuing and rotating keys, and the [getting started guide](https://html2img.com/docs/getting-started) for a tour of the API.

Optionally publish the config file:

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

Configuration
-------------

[](#configuration)

The published `config/html2img.php` reads from your environment:

```
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'),
    ],
];
```

VariableDefaultPurpose`HTML2IMG_API_KEY`noneYour key, sent as the `X-API-Key` header.`HTML2IMG_BASE_URI``https://app.html2img.com`API base URI. You rarely need to change this.`HTML2IMG_TIMEOUT``35`Request timeout in seconds.`HTML2IMG_DISK`default diskDisk used by `Html2img::store()`.### Custom HTTP client

[](#custom-http-client)

The integration is built on Guzzle. To add your own retry middleware, logging or proxy settings, bind a configured `GuzzleHttp\ClientInterface` as `html2img.http`, for example in a service provider:

```
use GuzzleHttp\Client;
use GuzzleHttp\ClientInterface;

$this->app->bind('html2img.http', fn () => new Client([
    'base_uri' => config('html2img.base_uri'),
    'timeout'  => config('html2img.timeout'),
    // your own handler stack, middleware, proxy settings, etc.
]));
```

The package still sends the `X-API-Key`, `Accept` and `Content-Type` headers on every request.

Usage
-----

[](#usage)

Reach the API through the `Html2img` facade. Each method returns a readonly `Html2img\Response\RenderResponse`. The request objects come from the underlying SDK, so import them from the `Html2img\Request` namespace.

### Render HTML

[](#render-html)

`POST /api/html`. Send a complete HTML document and get back an image of the rendered result. Inline your CSS in a `` block, or reference remote stylesheets and web fonts via `` tags in the document head. See the [`html` parameter docs](https://html2img.com/docs/parameters/html).

```
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; }', // injected after load
    width: 1200,
    height: 630,
    dpi: 2,          // retina
));

return $response->url; // https://i.html2img.com/abc123def456.png
```

Rendering a Blade [view](https://laravel.com/docs/views) into the image, as above, keeps your markup where the rest of your app lives.

### Capture a screenshot

[](#capture-a-screenshot)

`POST /api/screenshot`. Fetch a public URL in a real browser and capture it. Use `selector` to crop to a single element, and `css` to hide cookie banners or chat widgets before the capture. See the [`url` parameter docs](https://html2img.com/docs/parameters/url) and the [`selector` docs](https://html2img.com/docs/parameters/selector).

```
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, .intercom-launcher { display: none !important; }',
    dpi: 2,
));
```

### Render a template

[](#render-a-template)

`POST /api/v1/templates/{slug}`. Render one of the built-in [templates](https://html2img.com/templates) from a JSON data payload. The data is validated server-side per template.

```
use Html2img\Laravel\Facades\Html2img;

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

return $response->url;
```

Saving renders to a disk
------------------------

[](#saving-renders-to-a-disk)

The API returns the CDN URL of the image rather than the raw bytes, so you can cache and re-serve it from your own infrastructure. When you would rather keep a copy, `store()` downloads the image and writes it to any [filesystem disk](https://laravel.com/docs/filesystem) in one line:

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

$response = Html2img::html(new HtmlRequest(html: $document, width: 1200, height: 630));

// Returns the stored path; uses the HTML2IMG_DISK disk, or your default disk.
$path = Html2img::store($response, "og/{$post->id}.png");

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

$post->update(['og_image_path' => $path]);
```

You can also pass a URL string directly, or grab the raw bytes without storing them:

```
$bytes = Html2img::download($response);          // or a URL string
$path  = Html2img::store('https://i.html2img.com/abc.png', 'thumb.png');
```

Queues and jobs
---------------

[](#queues-and-jobs)

Renders are a natural fit for a [queued job](https://laravel.com/docs/queues), especially full-page captures that take a few seconds. Resolve the facade or type-hint the manager:

```
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"),
        ]);
    }
}
```

For very large captures, prefer [asynchronous delivery](#asynchronous-delivery) over a long-running job.

Render options
--------------

[](#render-options)

Both `HtmlRequest` and `ScreenshotRequest` accept the following. Any option left null is omitted from the request, so the server applies its own default. The complete reference is in the [parameter docs](https://html2img.com/docs/parameters).

OptionTypeDocs`css`string[css](https://html2img.com/docs/parameters/css)`width`int[dimensions](https://html2img.com/docs/parameters/dimensions) (1 to 5000)`height`int[dimensions](https://html2img.com/docs/parameters/dimensions) (ignored when `fullpage`)`fullpage`bool[fullpage](https://html2img.com/docs/parameters/fullpage)`dpi`int[dpi](https://html2img.com/docs/parameters/dpi) (1 to 4, use 2 for retina)`webhookUrl`string[webhook-url](https://html2img.com/docs/parameters/webhook-url)`msDelay`int[ms\_delay](https://html2img.com/docs/parameters/ms_delay) (1 to 5000)`waitForSelector`string[wait\_for\_selector](https://html2img.com/docs/parameters/wait_for_selector)`ScreenshotRequest` also accepts [`selector`](https://html2img.com/docs/parameters/selector) to crop the capture to a single element. `HtmlRequest` does not, since you control the markup.

Custom fonts are loaded by referencing them with `` tags in your HTML document head, or by linking a web font from your captured page.

The response
------------

[](#the-response)

Every method returns a readonly `Html2img\Response\RenderResponse`:

```
$response->success;          // bool
$response->id;               // string|null, the render id
$response->url;              // string|null, the CDN URL of the image
$response->creditsRemaining; // int|null, credits left after this call
$response->status;           // string|null, "processing" for async jobs
$response->message;          // string|null
$response->template;         // string|null, the template slug, when applicable
$response->isProcessing();   // bool
$response->raw();            // array, the full decoded JSON payload
```

Asynchronous delivery
---------------------

[](#asynchronous-delivery)

Synchronous requests have a 30 second budget. For captures likely to exceed it, pass a `webhookUrl`. The API responds immediately with `status: "processing"` and `url: null`, then POSTs the final image URL to your endpoint once rendering finishes. See the [`webhook_url` docs](https://html2img.com/docs/parameters/webhook-url).

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

$response = Html2img::screenshot(new ScreenshotRequest(
    url: 'https://example.com/long-report',
    fullpage: true,
    webhookUrl: route('hooks.html2img'),
));

if ($response->isProcessing()) {
    // The final URL will arrive at your webhook, not on this response.
}
```

Error handling
--------------

[](#error-handling)

Every failure throws an `Html2img\Exception\Html2imgException`. Catch that single type to handle any error, or catch a specific subclass. No raw Guzzle exception escapes the package.

```
use Html2img\Laravel\Facades\Html2img;
use Html2img\Request\HtmlRequest;
use Html2img\Exception\Html2imgException;
use Html2img\Exception\ValidationException;
use Html2img\Exception\InsufficientCreditsException;

try {
    $response = Html2img::html(new HtmlRequest(html: $document));
} catch (ValidationException $e) {
    // 400 or 422: inspect the per-field messages
    foreach ($e->details() as $field => $messages) {
        // ...
    }
} catch (InsufficientCreditsException $e) {
    // 402: out of credits
    $left = $e->creditsRemaining();
} catch (Html2imgException $e) {
    // anything else
    $e->statusCode(); // int|null
    $e->errorCode();  // string|null, the API "code" field
    $e->payload();    // array, the decoded body
}
```

ExceptionWhen`AuthenticationException`401, missing or invalid API key.`InsufficientCreditsException`402, no credits remaining.`NotSubscribedException`403, no active subscription.`NotFoundException`404, for example an unknown template slug.`ValidationException`400 or 422, with `details()` per field.`RateLimitException`429, rate or quota exceeded.`TimeoutException`504, the synchronous render budget was exceeded.`ServerException`5xx, an unexpected renderer error.`ConnectionException`the request never reached a response.`Html2imgException`base type for all of the above.Verifying your setup
--------------------

[](#verifying-your-setup)

Confirm your key and configuration with the bundled artisan command, which renders a small test image:

```
php artisan html2img:test
```

It prints the resulting image URL and your remaining credits, or a clear error if the key is missing or rejected. The check uses one credit. There is also a [testing guide](https://html2img.com/docs/testing) for the API itself.

Other languages
---------------

[](#other-languages)

Not on Laravel? The same API has worked guides for [plain PHP](https://html2img.com/docs/usage/php), [Ruby on Rails](https://html2img.com/docs/usage/rails), [Python](https://html2img.com/docs/usage/python), [JavaScript and Node.js](https://html2img.com/docs/usage/javascript), [React](https://html2img.com/docs/usage/react) and [Vue](https://html2img.com/docs/usage/vue).

Development
-----------

[](#development)

This package uses [ddev](https://ddev.com) for a containerised PHP environment. It is optional, and you can use vanilla PHP or whatever you use for local dev if you prefer.

```
ddev composer install
ddev exec vendor/bin/pest      # tests
ddev exec vendor/bin/phpstan analyse
ddev exec vendor/bin/pint --test
```

Links
-----

[](#links)

[Website](https://html2img.com) · [Documentation](https://html2img.com/docs) · [Laravel guide](https://html2img.com/docs/usage/laravel) · [Templates](https://html2img.com/templates) · [Tools](https://html2img.com/tools) · [Features](https://html2img.com/features) · [Comparisons](https://html2img.com/compare) · [Articles](https://html2img.com/articles) · [Pricing](https://html2img.com/pricing) · [PHP SDK](https://github.com/html2img/html2img-php)

Licence
-------

[](#licence)

MIT. See [LICENSE](LICENSE).

###  Health Score

41

—

FairBetter than 87% of packages

Maintenance99

Actively maintained with recent releases

Popularity2

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity48

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

2d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/291512758?v=4)[html2img](/maintainers/html2img)[@html2img](https://github.com/html2img)

---

Top Contributors

[![mikemike](https://avatars.githubusercontent.com/u/91627?v=4)](https://github.com/mikemike "mikemike (3 commits)")

---

Tags

html-to-imagehtml-to-image-converterimage-apiimage-generationlaravel-packageog-imageog-image-generatorphplaravelscreenshotfacadeapi clientopen-graphhtml-to-pdfhtml to imagehtml to pngURL to Imageog-imageimage-generationhtml2imgscreenshot-api

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/html2img-html2img-laravel/health.svg)

```
[![Health](https://phpackages.com/badges/html2img-html2img-laravel/health.svg)](https://phpackages.com/packages/html2img-html2img-laravel)
```

###  Alternatives

[psalm/plugin-laravel

Psalm plugin for Laravel

3325.1M337](/packages/psalm-plugin-laravel)[laravel/horizon

Dashboard and code-driven configuration for Laravel queues.

4.1k91.3M277](/packages/laravel-horizon)[illuminate/database

The Illuminate Database package.

3.0k54.1M11.0k](/packages/illuminate-database)[laravel/ai

The official AI SDK for Laravel.

9782.1M153](/packages/laravel-ai)[moonshine/moonshine

Laravel administration panel

1.3k239.9k72](/packages/moonshine-moonshine)[spatie/laravel-health

Monitor the health of a Laravel application

88011.3M149](/packages/spatie-laravel-health)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
