DEV Community

Shahzaib
Shahzaib

Posted on

I Made My Web App Receive Files From WhatsApp — No Backend, Just Web APIs

Series: Building PdfWord — a free, no-backend PDF tools site (Part 5)

My PDF tools site is a PWA — installable, works offline. But last night I asked myself: am I actually using the "app" part, or is it just a bookmark with a nice icon?

So I upgraded it with three real platform integrations. All client-side. Zero backend. Here's how.


1. Share Target: receive PDFs from WhatsApp

This is the big one. On Android, when you share a PDF from WhatsApp, Gmail, or Files, PdfWord now appears in the share sheet — and the file opens pre-loaded in the app.

It takes two pieces:

The manifest declares what you accept:

"share_target": {
  "action": "/share.html",
  "method": "POST",
  "enctype": "multipart/form-data",
  "params": {
    "files": [{ "name": "pdfs", "accept": ["application/pdf", ".pdf"] }]
  }
}
Enter fullscreen mode Exit fullscreen mode

The service worker intercepts the POST (a static host can't parse multipart forms, but the SW can):

self.addEventListener('fetch', e => {
  const url = new URL(e.request.url);
  if (e.request.method === 'POST' && url.pathname === '/share.html') {
    e.respondWith((async () => {
      const fd = await e.request.formData();
      const files = fd.getAll('pdfs').filter(f => f && f.size > 0);
      if (files.length) {
        const cache = await caches.open('pdfword-shared-v1');
        await cache.put('shared-0', new Response(files[0], {
          headers: { 'X-Filename': encodeURIComponent(files[0].name) }
        }));
      }
      return Response.redirect('/share.html?shared=1', 303);
    })());
  }
});
Enter fullscreen mode Exit fullscreen mode

Then share.html reads the file from the cache, shows it, and offers tool buttons (Compress, Merge, PDF to Word…). Clicking one stashes the file in IndexedDB and navigates to the tool page, where a small script in my shared common.js injects it into the file input via DataTransfer — so the tool's existing upload handler just works, no per-tool changes needed.

The whole flow feels native. The user never picks a file twice.

2. App shortcuts: long-press the icon

Three quick actions in the manifest — Merge PDF, Compress PDF, PDF to Word:

"shortcuts": [
  { "name": "Merge PDF", "url": "/merge-pdf.html",
    "icons": [{ "src": "assets/icons/icon-192.png", "sizes": "192x192" }] },
  ...
]
Enter fullscreen mode Exit fullscreen mode

Long-press the installed app icon and jump straight to the tool. Five minutes of work, genuinely useful.

3. iOS install hint (because Apple won't give us the prompt)

iOS Safari doesn't fire beforeinstallprompt, so my install button did nothing there. Now iOS users get the button too — tapping it shows: "Tap Share ⬆️ then 'Add to Home Screen' to install PdfWord." Small, honest, better than a dead button.

The lesson

A PWA isn't an "install button." It's the moment your web app starts behaving like it belongs on the device — receiving shares, offering shortcuts, working offline. Every one of these is a web standard, no app store, no review process, no backend.

Try it: install PdfWord on Android, share any PDF from WhatsApp to it, and watch it open ready to compress. That's the demo I'm proudest of.

What platform API should I wire up next? File Handling? Protocol handlers? Tell me in the comments.

Top comments (0)