Create Open Graph images (og:image, twitter:image, vk:image) for each (or some) site pages.
Use page title to create an eye-catching page preview when users share the link on social networks or instant messengers. Learn more about Open Graph.
- Image generation with your text and site name
- Fully customizable (see configuration)
- Small image size (15-50 Kb) with high resolution and quality (check it)
- Aspect ratios presets for popular social networks
- PHP 7.4 - 8.3
- Laravel 8.x - 11.x
- The Imagick PHP extension
You can install the package via composer:
composer require abordage/laravel-og-images
You can publish config file with:
php artisan vendor:publish --tag="og-images-config"
use Abordage\LaravelOpenGraphImages\Facades\OpenGraphImages;
$text = 'The adventures first, explanations take such a dreadful time!';
$path = \Storage::put('first-og-image.png');
$opengraph = OpenGraphImages::make($text)->save($path);
Note
All images are encoded inPNG
format as it provides the best ratio between size/quality. For the same reason, the package uses theImagick
driver - in tests, it showed an advantage in speed and final size of the generated images.
// for <og:image>
OpenGraphImages::make($text)->save($path);
// or
OpenGraphImages::make($text, 'opengraph')->save($path);
// for <twitter:image>
OpenGraphImages::make($text, 'twitter')->save($path);
// for <vk:image>
OpenGraphImages::make($text, 'vk')->save($path);
// custom size
OpenGraphImages::makeCustom($text, 600, 400)->save($path);
After generation, you need to somehow organize the relationship of images with a specific page (for example, attach to a model). If you already have a solution ready to accept an image and attach it to a specific page, you can get the image as a string instead of saving it:
$imageBlob = OpenGraphImages::make($text)->get();
If after generation you need to get sizes of the image, you can get it as follows:
$openGraphImage = OpenGraphImages::make($text, 'twitter');
$openGraphImage->save($path);
$imageSizes = $openGraphImage->getImageSizes();
// return [
// 'width' => 1200,
// 'height' => 600
// ];
spatie/laravel-medialibrary is a great package for associate all sorts of files with Eloquent models. If you are using this package (or similar), all you need to do is to add new collections to the model and attach images using media library.
class Page extends Model implements HasMedia
{
use InteractsWithMedia;
// ...
public function registerMediaCollections(): void
{
// ...
$this->addMediaCollection('opengraph')
->singleFile();
$this->addMediaCollection('twitter')
->singleFile();
}
// ...
}
Next, when creating a new page (or updating), generate an og-image and attach it:
$page = new Page();
$page->title = 'Your awesome title';
$page->save();
// generate image and attach to model
$image = OpenGraphImages::make($page->title);
$page->addMediaFromString($image->get())
->usingFileName(\Str::slug($page->title) . '.png')
->withCustomProperties($image->getImageSizes())
->toMediaCollection('opengraph');
Multiple images:
$page = new Page();
$page->title = 'Your awesome title';
$page->save();
$presets = ['opengraph', 'twitter', 'vk'];
foreach ($presets as $preset) {
$image = OpenGraphImages::make($page->title, $preset);
$page->addMediaFromString($image->get())
->usingFileName(\Str::slug($page->title) . '-' . $preset . '.png')
->withCustomProperties($image->getImageSizes())
->toMediaCollection($preset);
}
Now you can get the link for the og:image meta tag as follows:
$ogImageUrl = $page->getFirstMediaUrl('opengraph');
$twitterImageUrl = $page->getFirstMediaUrl('twitter');
$vkImageUrl = $page->getFirstMediaUrl('vk');
$config = [
/*
|--------------------------------------------------------------------------
| Background Color
|--------------------------------------------------------------------------
|
| Supported: HEX, RGB or RGBA format
|
*/
'background_color' => '#474761',
/*
|--------------------------------------------------------------------------
| Text Color
|--------------------------------------------------------------------------
|
| Supported: HEX, RGB or RGBA format
|
*/
'text_color' => '#eee',
/*
|--------------------------------------------------------------------------
| App Name
|--------------------------------------------------------------------------
|
| Set null to disable
|
| Supported: string or null
|
*/
'app_name' => config('app.name'),
/*
|--------------------------------------------------------------------------
| App Name Text Color
|--------------------------------------------------------------------------
|
| Supported: HEX, RGB or RGBA format
|
*/
'app_name_color' => '#eee',
/*
|--------------------------------------------------------------------------
| App Name Decoration Color
|--------------------------------------------------------------------------
|
| Supported: HEX, RGB or RGBA format
|
*/
'app_name_decoration_color' => '#fb3361',
/*
|--------------------------------------------------------------------------
| Text Alignment
|--------------------------------------------------------------------------
|
| Multiline text alignment
|
| Supported: "left", "center", "right"
|
*/
'text_alignment' => 'left',
/*
|--------------------------------------------------------------------------
| Text Sticky
|--------------------------------------------------------------------------
|
| Supported: "left", "center", "right"
|
*/
'text_sticky' => 'center',
/*
|--------------------------------------------------------------------------
| App Name Position
|--------------------------------------------------------------------------
|
| Supported: "top-left", "top-center", "top-right",
| "bottom-left", "bottom-center", "bottom-right"
|
*/
'app_name_position' => 'bottom-center',
/*
|--------------------------------------------------------------------------
| App Name Decoration Style
|--------------------------------------------------------------------------
|
| Set null to disable
|
| Supported: "line", "label", "rectangle", null
|
*/
'app_name_decoration_style' => 'line',
/*
|--------------------------------------------------------------------------
| Font Size
|--------------------------------------------------------------------------
|
*/
'font_size' => 55,
/*
|--------------------------------------------------------------------------
| App Name Font Size
|--------------------------------------------------------------------------
|
*/
'app_name_font_size' => 30,
/*
|--------------------------------------------------------------------------
| Text Font
|--------------------------------------------------------------------------
|
| If set null, will be used Preset Font (Roboto Regular)
|
| Supported: "absolute/path/to/your/font.ttf", null
|
*/
'font_path' => null,
/*
|--------------------------------------------------------------------------
| App Name Font
|--------------------------------------------------------------------------
|
| If set null, will be used Preset Font (Roboto Medium)
|
| Supported: "absolute/path/to/your/font.ttf", null
|
*/
'app_name_font_path' => null,
];
Method | Returns | Added in | Changed in |
---|---|---|---|
make(string $text, string $preset = 'opengraph') |
self | 0.1.0 | 0.2.0 |
makeCustom(string $text, int $width, int $height) |
self | 0.2.0 | - |
get() |
string | 0.1.0 | - |
save(string $path) |
boolean | 0.1.0 | - |
getImageSizes() |
array | 0.3.0 | - |
Preset | Aspect ratios | Docs |
---|---|---|
make(string $text) |
1200 x 630 (1.91:1) | |
make(string $text, 'opengraph') |
1200 x 630 (1.91:1) | |
make(string $text, 'facebook') |
1200 x 630 (1.91:1) | fb |
make(string $text, 'twitter') |
1200 x 600 (2:1) | |
make(string $text, 'vk') |
1200 x 536 (2.2:1) | vk |
Add ability to use gradients and images for the background.
Run all tests
composer test:all
or
composer test:phpunit
composer test:phpstan
composer test:phpcs
or see https://github.com/abordage/laravel-og-images/actions/workflows/tests.yml
Find a bug or have a feature request? Open an issue, or better yet, submit a pull request - contribution welcome!
Please see CONTRIBUTING for details.
- Pavel Bychko (abordage)
- All Contributors
The MIT License (MIT). Please see License File for more information.