Skip to content

Screenshots

Taking screenshots of your application has great benefits. It may become difficult to manage screenshot updates as the application evolves, in particular if multiple sizes are managed.

This command requires dependencies and should be executed in dev environment only.

composer require --dev symfony/panther
composer require --dev dbrekelmans/bdi && vendor/bin/bdi detect drivers

Image processor

Please read the section on the Icons page.

Using PHP attributes

Declare screenshots directly on your controller methods using the #[Screenshot] attribute. This provides automatic manifest integration.

<?php

namespace App\Controller;

use SpomkyLabs\PwaBundle\Attribute\Screenshot;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;

class HomeController extends AbstractController
{
    #[Route('/', name: 'app_homepage')]
    #[Screenshot(
        sizes: ['fhd', 'ipad/LP', 'iphone-14'],
        name: 'homepage',
        label: 'Application homepage',
        platform: 'windows'
    )]
    public function index(): Response
    {
        return $this->render('home/index.html.twig');
    }
}

Generating screenshots

The pwa:compile command automatically generates screenshots from attributes before compiling the manifest:

php bin/console pwa:compile

Use --no-screenshots to skip screenshot generation:

php bin/console pwa:compile --no-screenshots

The command will automatically discover all routes with #[Screenshot] attributes and generate the screenshots.

Attribute parameters

Parameter Type Required Description
sizes array Yes Array of size profiles or explicit dimensions with optional orientation selectors
parameters array No Route parameters (e.g., ['id' => 123]). Note: use locales parameter for _locale
locales array No Locales to generate screenshots for (e.g., ['fr', 'en']). Each locale generates separate screenshots
name string No Base filename (defaults to route name)
label string No Label for the screenshot in the manifest (supports translation)
platform string No Target platform (android, ios, windows, etc.)
output string No Custom output directory (defaults to assets/screenshots/)
format string No Output format: png, jpg, webp (defaults to png)

Automatic manifest integration

Screenshots declared with #[Screenshot] attributes are automatically integrated into your PWA manifest. The ManifestScreenshotListener discovers all controller methods with the attribute and adds the corresponding screenshot files to your manifest during compilation.

When a screenshot file exists, it's automatically added to the manifest with: - src: The asset path (via AssetMapper if available) - width and height: From the generated filename - form_factor: Auto-calculated (wide/narrow based on dimensions) - platform: From the attribute - type: Based on format (e.g., "image/webp") - label: From the attribute (supports translation via the pwa domain) - reference: The generated URL for the route

No manual configuration needed!

Multi-locale support

For internationalized applications, use the locales parameter to generate screenshots for multiple locales with a single attribute:

#[Route('/{_locale}/dashboard', name: 'app_dashboard')]
#[Screenshot(
    sizes: ['desktop-lg', 'tablet/LP'],
    locales: ['fr', 'en', 'de'],
    label: 'Dashboard'
)]
public function dashboard(): Response
{
    return $this->render('dashboard/index.html.twig');
}

This generates screenshots for each locale with appropriate filenames (e.g., app-dashboard-fr-1920x1080.png, app-dashboard-en-1920x1080.png).

The manifest compiler filters screenshots by the current locale, ensuring only relevant screenshots are included in the localized manifest.

Routes with parameters

For routes with other parameters (like entity IDs), use the parameters attribute. Use multiple #[Screenshot] attributes for different parameter combinations:

#[Route('/product/{id}', name: 'app_product')]
#[Screenshot(
    sizes: ['fhd', 'iphone-14'],
    parameters: ['id' => 1],
    name: 'product-featured',
    label: 'Featured Product'
)]
#[Screenshot(
    sizes: ['fhd', 'iphone-14'],
    parameters: ['id' => 42],
    name: 'product-popular',
    label: 'Popular Product'
)]
public function show(int $id): Response
{
    return $this->render('product/show.html.twig');
}

Size profiles

The sizes array accepts: - Predefined profile names: "fhd", "iphone-14", "ipad", "desktop-lg", etc. - Explicit dimensions: "1920x1080", "390x844", etc. - Orientation selectors: /L (landscape), /P (portrait), /LP (both)

Example: "ipad/LP" generates both 768x1024 (portrait) and 1024x768 (landscape) screenshots.

Available size profiles

Standard resolutions (landscape)

Profile Dimensions Form Factor
hd 1280×720 wide
fhd 1920×1080 wide
2k 2560×1440 wide
4k 3840×2160 wide
8k 7680×4320 wide

Portrait resolutions

Profile Dimensions Form Factor
480p 640×480 wide
720p 720×1280 narrow
1080p 1080×1920 narrow
1440p 1440×2560 narrow

iPhone models

Profile Dimensions Form Factor
iphone-se 375×667 narrow
iphone-8 375×667 narrow
iphone-12 390×844 narrow
iphone-13 390×844 narrow
iphone-14 390×844 narrow
iphone-14-plus 428×926 narrow
iphone-14-pro 393×852 narrow
iphone-14-pro-max 430×932 narrow
iphone-15 393×852 narrow
iphone-15-pro-max 430×932 narrow

Android devices

Profile Dimensions Form Factor
pixel-5 393×851 narrow
pixel-6 412×915 narrow
pixel-7 412×915 narrow
pixel-7-pro 412×915 narrow
galaxy-s21 360×800 narrow
galaxy-s22 360×800 narrow
galaxy-s23 360×780 narrow

Tablets

Profile Dimensions Form Factor
ipad 768×1024 narrow
ipad-pro-11 834×1194 narrow
ipad-pro-129 1024×1366 narrow

Info

For tablets, use orientation selectors to generate both portrait and landscape: ipad/LP

Web breakpoints

Profile Dimensions Form Factor
mobile-sm 320×568 narrow
mobile-md 375×667 narrow
mobile-lg 414×896 narrow
tablet 768×1024 narrow
desktop-sm 1024×768 wide
desktop-md 1366×768 wide
desktop-lg 1920×1080 wide
desktop-xl 2560×1440 wide

Configuration

User agent

During screenshot generation, the bundle uses a special user agent (PWAScreenshotBot by default) to identify screenshot requests. When this user agent is detected, the Symfony profiler and debug toolbar are automatically disabled to ensure clean screenshots.

You can customize this user agent in your configuration:

# config/packages/pwa.yaml
pwa:
    web_client:
        user_agent: 'MyCustomScreenshotBot'

Custom web client

For advanced use cases, you can provide a custom Panther client:

# config/packages/pwa.yaml
pwa:
    web_client:
        web_client: 'my_custom_panther_client'  # Service ID