asp.net-coreblazorblazor-webassemblymanifest.jsonblazor-pwa

Blazor WASM PWA Cannot Change Icon, Cannot Change Name


I'm struggling with a case where I've done good research on how to it. It works for everyone but not for me!!

Environment:

So I've created a project and selected Progressive Web Application (PWA) from the get-go to have everything I need auto-generated. Also made the app ASP.NET Core hosted.

The startup project is Rihal.Server in standalone mode (not IIS or Docker).

When I launch the application I get the default prompt in Chrome to install app. When I click the "+" icon I get the default Blazor icon and the app's name "Rihal". So far so good. When I change the icon and name, I still keep getting the defaults! enter image description here

  1. I've tried cleaning and rebuilding all projects one by one, no errors.
  2. I've tried restarting Visual Studio.
  3. I've tried changing other things in the manifest like background color to see any change, nothing changes.
  4. I've checked the Build Action (Content). The default Copy to Output Directory is (Do Not Copy), Changing to (Copy Always) has no effect.

It's like the manifest is completely ignored.

I've developed other parts of this app and then came around to change the icon and name:

  1. Replaced the default icon (same icon used for 192 at a smaller resolution) enter image description here

  2. Updated my manifest.json for the 192 size and name/short name: (I've also tried adding multiple sizes).

{
  "name": "Rihal Timesheet",
  "short_name": "Timesheet",
  "start_url": "./",
  "display": "standalone",
  "background_color": "#ffffff",
  "theme_color": "#03173d",
  "icons": [
    {
      "src": "icon-512.png",
      "type": "image/png",
      "sizes": "512x512"
    },
    {
      "src": "icon-192.png",
      "type": "image/png",
      "sizes": "192x192"
    }
  ]
}

Other files if relevant:

Rihal.Client service-worker.js

// In development, always fetch from the network and do not enable offline support.
// This is because caching would make development more difficult (changes would not
// be reflected on the first load after each change).
self.addEventListener('fetch', () => { });

Rihal.Client service-worker.published.js

// Caution! Be sure you understand the caveats before publishing an application with
// offline support. See https://aka.ms/blazor-offline-considerations

self.importScripts('./service-worker-assets.js');
self.addEventListener('install', event => event.waitUntil(onInstall(event)));
self.addEventListener('activate', event => event.waitUntil(onActivate(event)));
self.addEventListener('fetch', event => event.respondWith(onFetch(event)));

const cacheNamePrefix = 'offline-cache-';
const cacheName = `${cacheNamePrefix}${self.assetsManifest.version}`;
const offlineAssetsInclude = [ /\.dll$/, /\.pdb$/, /\.wasm/, /\.html/, /\.js$/, /\.json$/, /\.css$/, /\.woff$/, /\.png$/, /\.jpe?g$/, /\.gif$/, /\.ico$/ ];
const offlineAssetsExclude = [ /^service-worker\.js$/ ];

async function onInstall(event) {
    console.info('Service worker: Install');

    // Fetch and cache all matching items from the assets manifest
    const assetsRequests = self.assetsManifest.assets
        .filter(asset => offlineAssetsInclude.some(pattern => pattern.test(asset.url)))
        .filter(asset => !offlineAssetsExclude.some(pattern => pattern.test(asset.url)))
        .map(asset => new Request(asset.url, { integrity: asset.hash }));
    await caches.open(cacheName).then(cache => cache.addAll(assetsRequests));
}

async function onActivate(event) {
    console.info('Service worker: Activate');

    // Delete unused caches
    const cacheKeys = await caches.keys();
    await Promise.all(cacheKeys
        .filter(key => key.startsWith(cacheNamePrefix) && key !== cacheName)
        .map(key => caches.delete(key)));
}

async function onFetch(event) {
    let cachedResponse = null;
    if (event.request.method === 'GET') {
        // For all navigation requests, try to serve index.html from cache
        // If you need some URLs to be server-rendered, edit the following check to exclude those URLs
        const shouldServeIndexHtml = event.request.mode === 'navigate';

        const request = shouldServeIndexHtml ? 'index.html' : event.request;
        const cache = await caches.open(cacheName);
        cachedResponse = await cache.match(request);
    }

    return cachedResponse || fetch(event.request);
}

Rihal.Client csproj file

<Project Sdk="Microsoft.NET.Sdk.Web">
  <PropertyGroup>
    <TargetFramework>netstandard2.1</TargetFramework>
    <RazorLangVersion>3.0</RazorLangVersion>
    <ServiceWorkerAssetsManifest>service-worker-assets.js</ServiceWorkerAssetsManifest>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
    <DebugType>embedded</DebugType>
    <DebugSymbols>true</DebugSymbols>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.Blazor.HttpClient" Version="3.2.0-preview3.20168.3" />
    <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="3.2.0" />
    <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Build" Version="3.2.0" PrivateAssets="all" />
    <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="3.2.0" PrivateAssets="all" />
    <PackageReference Include="Microsoft.Authentication.WebAssembly.Msal" Version="3.2.0" />
    <PackageReference Include="Microsoft.Extensions.Http" Version="3.1.5" />
    <PackageReference Include="System.Net.Http.Json" Version="3.2.1" />
  </ItemGroup>

  <ItemGroup>
    <ProjectReference Include="..\Shared\Rihal.Shared.csproj" />
  </ItemGroup>

  <ItemGroup>
    <ServiceWorker Include="wwwroot\service-worker.js" PublishedContent="wwwroot\service-worker.published.js" />
  </ItemGroup>
</Project>

Solution

  • Open the browsers debug window. Chrome or the new Edge. While it is open right click the refresh button on your page select => Empty cache and hard reload.

    I found you can do this in the clients csproj file. Forcing and update in the service worker.

    
    <Target Name="PublishServiceWorker" AfterTargets="CopyFilesToPublishDirectory">
            <WriteLinesToFile File="$(PublishDir)wwwroot\service-worker.js" Lines="/* $([System.Guid]::NewGuid()) */" />
    </Target>