DEV Community

Elio Struyf
Elio Struyf

Posted on • Originally published at eliostruyf.com on

#DevHack: Dynamic manifests for Progressive Web App aka PWA

In the previous #DevHack, I told you how to use deep links in your PWA for Microsoft Teams. This approach I currently implemented in one of my proof of concepts. Another functionality that my POC needed to have is to have dynamic manifest creating for the PWA.

Info: #DevHack: Deep linking to Microsoft Teams in Android and iOS

In this #DevHack, I will tell you how you can make it possible to get dynamic manifests for your PWA using Azure Static Web Apps and Azure Functions.

Approaches

When I started my journey with PWAs and dynamic manifests, I found two approaches:

  1. Create the manifest on the fly with JavaScript;
  2. Use a dynamically generated manifest.

The first approach is what I used from the start. This approach does not require anything special, except some extra JavaScript code to add the page’s manifest data.

This approach worked fine on iOS and Windows/macOS, but we noticed a different behavior when testing it on Android devices. Android never recognized our PWA as a “real” PWA. Instead, Android created it as a bookmark to the site.

Solution

The only working solution for dynamically generated manifests is to make use of an API. My POC created as an Azure Static Web App can handle this by adding an Azure Function.

import { AzureFunction, Context, HttpRequest } from "@azure/functions"

const httpTrigger: AzureFunction = async function (context: Context, req: HttpRequest): Promise<void> {

  const name = req.query.name;
  const enityId = req.query.enityId;
  const appId = req.query.appId;

  context.res = {
    body: {
      name,
      short_name: name,
      description: name,
      background_color: "#ffffff",
      theme_color: "#ffffff",
      display: "standalone",
      start_url: `/entity/?appId=${appId}&enityId=${enityId}&name=${name}`,
      icons: [
        {
          "src": "/android-chrome-192x192.png",
          "sizes": "192x192",
          "type": "image/png"
        },
        {
          "src": "/android-chrome-512x512.png",
          "sizes": "512x512",
          "type": "image/png"
        },
        {
          "src": "/maskable_icon.png",
          "sizes": "196x196",
          "type": "image/png",
          "purpose": "any maskable"
        }
      ]
    },
    headers: {
      "Content-Type": "text/html"
    }
  };
};

export default httpTrigger;
Enter fullscreen mode Exit fullscreen mode

In my React application, I call the Azure Function with the following logic:

<Helmet>
  <link id="teams_manifest" rel="manifest" href={`/api/manifest.webmanifest?${QS_APP_ID}=${encodeURIComponent(appId)}&${QS_ENTITY_ID}=${encodeURIComponent(enityId)}&${QS_NAME}=${appName}`} />
</Helmet>
Enter fullscreen mode Exit fullscreen mode

Info: using react-helmet-async to do changes to the document head.

Speedy emails, satisfied customers

Postmark Image

Are delayed transactional emails costing you user satisfaction? Postmark delivers your emails almost instantly, keeping your customers happy and connected.

Sign up

Top comments (0)

The best way to debug slow web pages cover image

The best way to debug slow web pages

Tools like Page Speed Insights and Google Lighthouse are great for providing advice for front end performance issues. But what these tools can’t do, is evaluate performance across your entire stack of distributed services and applications.

Watch video

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay