cloudscribe PwaKit - Easily Build Progressive Web Apps

cloudscribe PwaKit provides tools to facilitate building PWAs (Progressive Web Apps), which can work offline, be installed on the device home screen, and on some devices support push notifications.

We developed PwaKit to meet the needs of a current client project that is mostly comprised of documentation pages created using cloudscribe SimpleContent. But this documentation is meant to be used in the field and therefore ALL of the content needs to be available while offline. The solution works very well on Chrome or Edge for Windows and Android. On iOS Safari there are currently limitations that prevent fully caching all content for offline use, it only caches the pages that user has visited and only up to 50MB. Also push notifications are not currently supported on iOS Safari.

PwaKit is a set of Nuget packages

  • cloudscribe.PwaKit (Nuget | GitHub) - this main library has no dependencies on cloudscribe Core and could be used in any ASP.NET Core application
  • cloudscribe.PwaKit.Integration.CloudscribeCore (NuGet | GitHub)
  • cloudscribe.PwaKit.Integration.SimpleContent (NuGet | GitHub)
  • cloudscribe.PawKit.Storage.EFCore.Common (NuGet | GitHub)
  • cloudscribe.PwaKit.Storage.EFCore.MSSQL (NuGet | GitHub)
  • cloudscribe.PwaKit.Storage.EFCore.MySql (NuGet | GitHub)
  • cloudscribe.PwaKit.Storage.EFCore.PostgreSql (NuGet | GitHub)
  • cloudscribe.PwaKit.Storage.EFCore.SQLite (NuGet | GitHub)
  • cloudscribe.PwaKit.Storage.NoDb (NuGet | GitHub)

The storage libraries currently are just for persisting push notification subscriptions, you only need one of those depending on what storage platform you are using.

General Usage Instructions

These instructions are for those using cloudscribe Core and cloudscribe SimpleContent and with the goal for ALL content to be available offline on supported devices and browsers. It can be configured differently for other scenarios, there are many interfaces, and the default implementations of those can be replaced with your own.

Install all 3 main packages plus the storage package of your choice.

In Startup.cs or in CloudscribeFeatures.cs add this:

var pwaBuilder = services.AddPwaKit(config)
   .AddCloudscribeCoreIntegration()
   .UseSiteLastModifiedAsCacheSuffix()
   .MakeCloudscribeAdminPagesNetworkOnly()
   .PreCacheContentFiles()
   .PreCacheNavigationMenuUrls()
   .PreCacheAllSimpleContentUrls()
    ;

Depending on which storage library you are using you need one of these lines:

services.AddPwaStorageMSSQL(connectionString);
//or
services.AddPwaStorageMySql(connectionString);
//or
services.AddPwaStoragePostgreSql(connectionString);
//or
services.AddPwaStorageSQLite(connectionString);
//or
services.AddPwaNoDbStorage();


//if using any of the EFCore storage libraries you need this in Program.cs:
PwaDatabase.InitializeDatabaseAsync(scopedServices).Wait();

Then you need to add the routing:

routes.AddPwaDefaultRoutes(new cloudscribe.Core.Web.Components.SiteFolderRouteConstraint());

You also need to add an authorization policy:

options.AddPolicy(
   "PushNotificationAdminPolicy",
   authBuilder =>
   {
       authBuilder.RequireRole("Administrators", "Content Administrators");
   });

You also need to add menu items in the navigation.xml file:

<-- as a child of the Manage Node -->
<NavNode key="NotificationSettings"
              controller="Pwa"
              action="NotificationSettings"
              text="Notification Settings"
              componentVisibility="child-dropdown,breadcrumbs"
              excludeFromSearchSiteMap="true"
              hideFromAnonymous="true">
              <Children />
            </NavNode>

<-- as a child of the SiteAdmin Node -->

<NavNode key="PushNotificationConsole"
                    controller="Pwa"
                    action="PushConsole"
                    text="Push Notification"
                    iconCssClass="fas fa-share-square fa-fw"
                    preservedRouteParameters=""
                    componentVisibility="breadcrumbs,childtree,parenttree"
                    authorizationPolicy="ViewContentHistoryPolicy"
                    excludeFromSearchSiteMap="true">
              <Children>
              </Children>
            </NavNode>

Because the serviceworker works like a proxy server between the browser and your web app and it caches page content we need to make the top navigation menu load by ajax so that the user sees the correct items if they are logged in or not. In your _Layout file you need to make some modifications, best to compare yours to this one. Note the additional scripts at the bottom and the partial views. You also need to override the Views/Blog/ToolsPartial.cshtml, and  Views/Page/ToolsPartial.cshtml.

And finally you also need to manually create/add your manifest.json file and related images of different sizes.

If you've done all the needed changes then in Chrome or Edge you should see a prompt to install on Windows, as well as a prompt to subscribe to push notifications. You can also manage that under the My Account link in the top navigation.

You can also test sending push notifications under Administration > Push Notifications.

On supported devices that subscribe to push notifications the offline cache will be updated automatically when content is added, updated, or deleted using non visible push notifications to keep the content up to date for offline use.

Sponsors

This solution was developed as open source under a sponsorship from exeGesIS Spatial Data Management

Comments