I can register my Progressive Web App as a share target for images (supported from Chrome Android 76):
"share_target": {
"action": "/share-target",
"method": "POST",
"enctype": "multipart/form-data",
"params": {
"files": [
{
"name": "myImage",
"accept": ["image/jpeg", "image/png"]
}
]
}
}
I can then intercept attempts to share images to the app in a service worker:
self.addEventListener('fetch', e => {
if (e.request.method === 'POST' && e.request.url.endsWith('/share-target')) {
// todo
}
})
How would I display the shared image in my offline PWA?
Our app is caching its resources on install and serving them with fetch from the cache, so it works even if the user is offline.
In order for your PWA to be offline-capable, service workers pay a part in serving the content, but you'd also need to cache your page's resources as well. To cache your page's resources, first you need to plan out the size of your Cache Storage since there's a limit to it.
PWA is a web application, which can be installed on your system. It works offline when there is no internet connection, leveraging data cached during your last interactions with the app.
You can share to the app by registering it as a share target, with the Web Share Target API. This is done through an entry in the manifest file. These two advanced capabilities help your PWA integrate seamlessly with your platform, and create a smooth, unified sharing experience.
There are a few different steps to take here.
I put together a working example at https://web-share-offline.glitch.me/, with the source at https://glitch.com/edit/#!/web-share-offline
This is a prerequisite, and I accomplished it by generating a service worker that would precache my HTML, JS, and CSS using Workbox.
The JS that runs when the home page is loaded uses the Cache Storage API to read a list of image URLs that have been cached, to creates <img>
elements on the page corresponding to each one.
I also used Workbox for this, but it's a bit more involved. The salient points are:
POST
requests for the configured share target URL.POST
with a HTTP 303
redirected response, so that the browser will display the actual home page for your web app.Here's the Workbox configuration code that I used to handle this:
const shareTargetHandler = async ({event}) => {
const formData = await event.request.formData();
const cache = await caches.open('images');
await cache.put(
// TODO: Come up with a more meaningful cache key.
`/images/${Date.now()}`,
// TODO: Get more meaningful metadata and use it
// to construct the response.
new Response(formData.get('image'))
);
// After the POST succeeds, redirect to the main page.
return Response.redirect('/', 303);
};
module.exports = {
// ... other Workbox config ...
runtimeCaching: [{
// Create a 'fake' route to handle the incoming POST.
urlPattern: '/share-target',
method: 'POST',
handler: shareTargetHandler,
}, {
// Create a route to serve the cached images.
urlPattern: new RegExp('/images/\\d+'),
handler: 'CacheOnly',
options: {
cacheName: 'images',
},
}],
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With