Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
pwa:
manifest:
enabled: true
description: "This application helps you donate to worthy causes."pwa:
manifest:
enabled: true
id: "/?homescreen=1"composer require spomky-labs/pwa-bundlepwa: ~<!DOCTYPE html>
<html lang="en">
<head>
{{ pwa() }}
</head>
<body>
...
</body>
</html>pwa:
manifest:
enabled: true
iarc_rating_id: "e.g. IARC certificate code"<html dir="ltr" lang="en">
</html>pwa:
manifest:
enabled: true
dir: "ltr"
lang: "en"pwa:
manifest:
enabled: true
name: "My PWA"
short_name: "PWA"
start_url: "/index.html"
display: "standalone"
background_color: "#ffffff"
theme_color: "#4285f4"pwa:
manifest:
enabled: true
categories: ['games', 'kids']src Parameterpwa:
manifest:
enabled: true
icons:
- src: "icons/icon-192x192.png"
sizes: [192]
- src: "icons/icon-192x192.png"
sizes: [192]
purpose: "maskable"
- src: "icons/icon.svg"
sizes: 0pwa:
manifest:
icons:
- src: "icons/icon-48x48.png"
sizes: [48]
- src: "/home/project/foo/bar/icon-48x48.png"
sizes: [48]
- src: "src/resources/data/icon-48x48.png"
sizes: [48]pwa:
manifest:
icons:
- src: "icons/icon-192x192.png"
sizes: [48, 96, 192]
- src: "icons/icon.svg"
sizes: 0







/\.(css|js|json|xml|txt|map|ico|png|jpe?g|gif|svg|webp|bmp)$/pwa:
serviceworker:
enabled: true
src: "sw.js"
workbox:
asset_cache:
enabled: true
regex: '/\.(css|jsx?)$/'pwa:
serviceworker:
workbox:
cache_manifest: truepwa:
serviceworker:
enabled: true
src: "sw.js"
workbox:
use_cdn: true
version: 6.5.4/\.(ttf|eot|otf|woff2)$/pwa:
serviceworker:
enabled: true
src: "sw.js"
workbox:
font_cache:
enabled: true
max_entries: 10
max_age: 30 dayspwa:
manifest:
enabled: true
edge_side_panel: ~pwa:
manifest:
enabled: true
display: "browser"
edge_side_panel:
preferred_width: 400pwa:
manifest:
enabled: true
name: "app.name"
short_name: "app.short_name"
start_url: "/index.html"
displa": "standalone"
background_color: "#ffffff"
theme_color: "#4285f4"
shortcuts:
- name: "app.feature1.shorcut.name"
short_name: "app.feature1.shorcut.short_name"
description: "app.feature1.shorcut.description"
url: "/start-chat"
icons":
- src: "icons/feature1-96x96.png"
sizes: [96]pwa:
serviceworker:
enabled: true
src: "sw.js"
workbox:
offline_fallback:
page: 'app_offline_page'
image: 'images/offline.svg'
font: 'fonts/normal.ttf'/\.(ico|png|jpe?g|gif|svg|webp|bmp)$/pwa:
serviceworker:
enabled: true
src: "sw.js"
workbox:
image_cache:
enabled: true
max_age: 30 days
max_entries: 200
regex: '/\.(png|jpe?g|svg|webp)$/'<!DOCTYPE html>
<html lang="en">
<head>
{{ pwa(swAttributes= {nonce: csp_nonce('script')}) }}
</head>
<body>
...
</body>
</html>pwa:
serviceworker:
enabled: true
src: "sw.js"
workbox:
google_fonts:
enabled: true
cache_prefix: 'goolge-fonts'
max_entries: 20
max_age: 1 day<section {{ stimulus_controller('@pwa/prefetch-on-demand') }}>
<main>
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</main>
<aside {{ stimulus_action('@pwa/prefetch-on-demand', 'mouseover', 'prefetch', {urls: ['/author-18', '/article-2', '/article-3']}) }}>
Author: <a href="/author-18">John Doe</a>
Other articles: <a href="/article-2">How to Foo</a>
Other articles: <a href="/article-3">How to Bar</a>
</aside>
</section>pwa:
manifest:
enabled: true
file_handlers:
- action: "/open"
accept:
- "image/png": [".png"]
- "image/jpeg": [".jpg", ".jpeg"]pwa:
manifest:
enabled: true
share_target:
action: "/share-target"
method: "POST"
enctype: "multipart/form-data"
params:
files:
- name: "file",
accept: ["image/*"]pwa:
manifest:
enabled: true
background_color: "#ffffff"
theme_color: "#212529"
name: 'My Awesome Application'
short_name: 'awesome-app'
id: '/?manifest=1'
description: 'With application will help you to change the world'
orientation: "any"
display: "standalone"
scope: "/"
display_override: ['fullscreen', 'minimal-ui', 'window-controls-overlay']
id: "/"
start_url: "./"
icons:
- src: "images/favicon.ico"
sizes: [48]
- src: "images/favicon-512x512.png"
sizes: [512]
- src: "images/favicon.svg"
sizes: [0]
- src: "images/favicon.svg"
purpose: 'maskable'
sizes: [0]
screenshots:
- "images/screenshots/homepage-1303x1718.png"
- src: "images/screenshots/feature1-1303x1718.png"
label: "Feature 1 in action"
- src: "images/screenshots/feature2-2056x1080.png"
label: "Feature 2 and available options"
- src: "images/screenshots/feature3-2056x1080.png"
label: "Feature 3 at its best"
categories: ['utility', 'productivity']
shortcuts:
- name: "Feature 1"
short_name: "feature1"
description: "See Feature #1 in live action"
url: "app_feature1"
icons:
- src: "images/feature1.svg"
sizes: [0]
- src: "images/feature1-96x96.png"
sizes: [96]
<?php
declare(strict_types=1);
namespace Acme;
use SpomkyLabs\PwaBundle\ServiceWorkerRule\ServiceWorkerRule;
final readonly class MyCustomRule implements ServiceWorkerRule
{
private Workbox $workbox;
public function __construct(
ServiceWorker $serviceWorker,
) {
$this->workbox = $serviceWorker->workbox;
}
public function process(bool $debug = false): string
{
return <<<HELLO_WORLD
// This will be added to the Service Worker
console.log('FOO-BAR from the Service Worker!');
HELLO_WORLD;
}
}focus-existingpwa:
manifest:
enabled: true
launch_handler:
client_mode: "focus-existing""chrome_web_store": Google Chrome Web Store.pwa:
manifest:
enabled: true
protocol_handlers:
- protocol: "mailto"
url: "/compose?to=%s"
title: "Compose Email"
- protocol: "web+custom"
url:
path: "app_feature1"
params:
foo: "bar"
title: "Open with Feature #1"pwa:
manifest:
prefer_related_applications: true
related_applications:
- platform: "play"
url: "https://play.google.com/store/apps/details?id=com.example.app1"
id: "com.example.app1"
- platform: "itunes"
url: "https://itunes.apple.com/app/example-app1/id123456789"
- platform: "windows"
url: "https://apps.microsoft.com/store/detail/example-app1/id123456789"pwa:
manifest:
enabled: true
display: "standalone"
display_override: ["fullscreen", "minimal-ui"]<div class="mx-auto max-w-screen-xl text-center px-4" {{ stimulus_controller('@pwa/connection-status') }}>
<div
{{ stimulus_target('@pwa/connection-status', 'attribute') }}
class="flex items-center p-4 mb-4 text-sm border rounded-lg online:text-green-800 online:bg-green-50 online:dark:bg-gray-800 online:dark:text-green-400 offline:text-yellow-800 offline:bg-yellow-50 offline:dark:bg-gray-800 offline:dark:text-yellow-300"
role="alert"
>
<div>
<span class="font-medium">
Connection status
</span>:
<span {{ stimulus_target('@pwa/connection-status', 'message') }}>
We are trying to guess what is the current status of your Internet connection
</span>
</div>
</div>
</div>pwa:
image_processor: 'pwa.image_processor.imagick'symfony console pwa:create:icons /path/to/the/image.pngpwa:
manifest:
icons:
- src: icons/icon-16x16.jpg
sizes:
- 16
type: image/png
- ...symfony console pwa:create:icons /path/to/the/image.png --format="jpg" 48 96 256symfony console pwa:create:icons /path/to/the/image.png --output="/foo/bar"pwa:
serviceworker: "sw.js"pwa:
serviceworker:
enabled: true
src: "sw.js"pwa:
serviceworker:
enabled: true
src: "sw.js"
dest: "/foo/service-worker.js"symfony console importmap:require workbox-windowpwa:
serviceworker:
enabled: true
src: "sw.js"
dest: "/foo/service-worker.js"
scope: "/"
use_cache: true
skip_waiting: false2: relativepath (e.g. ../bar)


pwa:
manifest:
enabled: true
shortcuts:
- name: "Start New Conversation"
short_name: "New Chat"
description: "Create a new conversation."
url: "/start-chat"
icons":
- src: "icons/feature1-96x96.png"
sizes: [96]
- name: "View Unread Messages"
short_name: "Unread"
description: "View unread messages."
url: "/unread-messages"
icons:
- src: "icons/feature2-96x96.png"
sizes: [96]pwa:
manifest:
shortcuts:
- name: "Feature #1"
short_name: "feature-1"
url: "app_feature1" # route name
- name: "Feature #2"
short_name: "feature-2"
url:
path: "app_feature2" # route name
params: # route parameters
key: "value2"
- name: "Feature #3"
short_name: "feature-3"
url: "/feature/3" # relative URL
- name: "Feature #4"
short_name: "feature-4"
url: "https://foo.com/bar/feature-4" # absolute URL
- name: "Feature #5"
short_name: "feature-5"
url:
path: "app_feature5" # route name
path_type_reference: 3 # Network URL
pwa:
manifest:
enabled: true
screenshots:
- "images/screenshot-feature1.png"
-
src: "images/screenshot-feature2.png"
platform: "android"
type: "image/png"
-
src: "images/screenshot-feature3.png"
label: "Feature #3 in action"
form_factor: "narrow"label: "Main dashboard view"platform: "android"form_factor: "narrow"self.addEventListener('push', async function (event) {
if (!(self.Notification && self.Notification.permission === 'granted')) {
return;
}
const {title, options}= event.data.json();
event.waitUntil(self.registration.showNotification(title, options));
});pwa:
serviceworker:
enabled: true
src: "sw.js"
workbox:
resource_caches:
- match_callback: 'startsWith: /pages/'
cache_name: 'static-pages'
strategy: 'NetworkFirst'
network_timeout: 2 # Wait only 2 seconds (only when strategy is networkFirst or NetworkOnly)
preload_urls: # List of URLs to preload. The URLs shall match the value in match_callback option
- 'page_tos'
- 'page_legal'
- match_callback: 'regex: \/articles\/.*$'
cache_name: 'articles'
strategy: 'StaleWhileRevalidate'
broadcast: true # Broadcast changes only when strategy = staleWhileRevalidate
preload_urls: # List of URLs to precache. The URL shall be comprised within the regex
- 'app_articles'
- path: 'app_top_articles'
params:
display: 5symfony console pwa:create:screenshot https://example.com<?php
declare(strict_types=1);
use SpomkyLabs\PwaBundle\MatchCallbackHandler\MatchCallbackHandler;
namespace Acme\MatchCallbackHandler;
final readonly class MyVideosMatchCallbackHandler implements MatchCallbackHandler
{
public function supports(string $matchCallback): bool
{
return $matchCallback === 'my-videos';
}
public function handle(string $matchCallback): string
{
return sprintf("({url, request}) => (url.origin === 'videos.s3.storage.com' && request.destination === 'video');
}
}navigator.serviceWorker.addEventListener('message', async event => {
if (event.data.meta === 'workbox-broadcast-update') {
const {updatedURL} = event.data.payload;
if (updatedURL === window.location.href) {
const toast = document.getElementById('toast-refresh');
toast.classList.remove('hidden');
setTimeout(() => {
toast.classList.add('hidden');
}, 5000);
}
}
});pwa:
serviceworker:
workbox:
resource_caches:
- ...
broadcast_headers:
- 'X-App-Cache'pwa:
serviceworker:
enabled: true
src: "sw.js"
workbox:
resource_caches:
- match_callback: 'startsWith: /pages/'
cacheable_response_headers:
'X-Is-Cacheable': 'true'
cacheable_response_statuses: [200]composer require --dev symfony/panther
composer require --dev dbrekelmans/bdi && vendor/bin/bdi detect driverspwa:
manifest:
screenshots:
- src: screenshots/screenshot-1200x1100.png
width: 1200
height: 1100
type: image/png
- ...symfony console pwa:create:screenshot https://example.com --format="webp" --width=750 --height=1334symfony console pwa:create:screenshot https://example.com --output="/foo/bar"pwa:
serviceworker:
enabled: true
src: "sw.js"
workbox:
background_sync:
- queue_name: 'api'
match_callback: startsWith: /api/ # All requests starting with /api/
method: POST
max_retention_time: 7_200 # 5 days in minutes
force_sync_fallback: true #Optional
broadcast_channel: 'api-list'
- queue_name: 'contact'
regex: /\/contact-form\// # All requests starting with /contact-form/
method: POST
max_retention_time: 120 # 2 hours in minutespwa:
serviceworker:
enabled: true
src: "sw.js"
workbox:
enabled: falsepwa:
serviceworker:
enabled: true
workbox:
clear_cache: false # Default to truepwa:
manifest:
enabled: true
orientation: "landscape"<!DOCTYPE html>
<html lang="en">
<head>
...
<link rel="manifest" href="/manifest.json">
</head>
<body>
...
</body>
</html>
{
"name": "My Progressive Web App",
"short_name": "PWA",
"description": "An example Progressive Web App",
"start_url": "/index.html",
"display": "standalone",
"background_color": "#ffffff",
"theme_color": "#4285f4",
"icons": [
{
"src": "/icons/icon-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "/icons/icon-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
]
}self.addEventListener('install', (event) => {
event.waitUntil(
caches.open('my-cache').then((cache) => {
return cache.addAll([
'/',
'/index.html',
'/styles/main.css',
'/scripts/main.js',
'/images/logo.png'
]);
})
);
});
self.addEventListener('fetch', (event) => {
event.respondWith(
caches.match(event.request).then((response) => {
return response || fetch(event.request);
})
);
});<!DOCTYPE html>
<html lang="en">
<head>
<script defer>
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/service-worker.js')
.then(function(registration) {
console.log('Service Worker registered with scope:', registration.scope);
})
.catch(function(error) {
console.error('Service Worker registration failed:', error);
});
}
</script>
</head>
<body>
...
</body>
</html>
symfony console asset-map:compile