Blazor - Get Started with PWA

Blazor - Get Started with Blazor Progressive Web Application(PWA)

Setup The Project

Follow the Getting Started guide to set up your WebAssembly Blazor Application with Smart UI.

Setup PWA

Progressive Web Applications are web apps that utilize service workers, manifests, and other web-platform features to give users an experience on par with native apps such as an available desktop shortcut, offline mode, receiving notifications and others.

  1. Inside the wwwroot folder, create a service-worker.js file with the following content
    <RepeatButton></RepeatButton>
  2. Then, create a manifest.json in the wwwroot folder, which will contain information regarding our application.
    Colors and icon can be customized according to your application:
    {
      "short_name": "Smart Grid",
      "name": "Smart Grid",
      "icons": [
        {
          "src": "icon-192.png",
          "type": "image/png",
          "sizes": "512x512"
        }
      ],
      "start_url": "/",
      "background_color": "#6200ee",
      "display": "standalone",
      "scope": "/",
      "theme_color": "#6200ee"
    }
  3. Finally, enable the service worker and the manifest by adding the following scripts in the <head> of index.html:
                <link rel="manifest" href="manifest.json" />
                <script>navigator.serviceWorker.register('service-worker.js');</script>
  4. The PWA integration is now complete. Optionally, use Smart UI's Grid component to generate a clients' table in the Index.razor page:
    @page "/"
    @inject IJSRuntime JSRuntime
    
    <h3>Smart UI Grid</h3>
    <Grid DataSource="@Clients">
    	<Columns>
    		<Column DataField="Name" Label="Client Name" >
    		</Column>
    		<Column DataField="Balance" Label="Acccount Balance"></Column>
    		<Column DataField="City" Label="City"></Column>
    		<Column DataField="Country" Label="Country"></Column>
    		<Column DataField="LastOrder" Label="Last Order" DataType="date"></Column>
    	</Columns>
    </Grid>
    
    @code{
      class Client {
        public string Name { get; set; }
        public double Balance { get; set; }  
        public string City { get; set; }
        public string Country { get; set; }  
        public DateTime LastOrder {get; set; }
      
        public Client(string name, double balance, string city, string country, DateTime lastOrder){
          Name = name;
          Balance = balance;
          City = city;
          Country = country;
          LastOrder = lastOrder;
        }
      }
      Client[] Clients = new Client[] 
        {
        new Client("Maria Anders",130.00,"Berlin", "Germany", DateTime.Now),
        new Client("Ana Trujillo",230,"Mxico D.F.", "Mexico", DateTime.Now),
        new Client("Antonio Moreno",-3500,"Mxico D.F.", "Mexico", DateTime.Now),
        new Client("Thomas Hardy",55,"London", "UK", DateTime.Now),
        new Client("Christina Berglund",132.86,"Lule", "Sweden", DateTime.Now),
        new Client("Hanna Moos",85,"Mannheim", "Germany", DateTime.Now),
        new Client("Frdrique Citeaux",35.424,"Strasbourg", "France", DateTime.Now),
        new Client("Martn Sommer",0,"Madrid", "Spain", DateTime.Now),
        new Client("Elizabeth Lincoln",-140,"Marseille", "France", DateTime.Now),
        new Client("Victoria Ashworth",200,"Tsawassen", "Canada", DateTime.Now),
        new Client("Patricio Simpson",59.55,"London", "UK", DateTime.Now),
        new Client("Francisco Chang",100,"Buenos Aires", "Argentina", DateTime.Now),
        new Client("Yang Wang",107.44,"Mxico D.F.", "Mexico", DateTime.Now),
        new Client("Pedro Afonso",-200,"Bern", "Switzerland", DateTime.Now),
        new Client("Elizabeth Brown",-390,"Sao Paulo", "Brazil", DateTime.Now),
        new Client("Sven Ottlieb",70,"Berlin", "Germany", DateTime.Now),
        new Client("Janine Labruneo",135.50,"Nantes", "France", DateTime.Now),
        new Client("Ann Devon",0,"London", "UK", DateTime.Now),
        new Client("Roland Mendel",50,"Graz", "Austria", DateTime.Now),
        new Client("Patrick Smith",30,"Liverpool", "UK", DateTime.Now),
        new Client("John Mayers",30,"Liverpool", "UK", DateTime.Now)
        };
      }  
    }

When opening the page in a Chromium-based browser(Google Chrome, Microsoft Edge, etc.), a download icon will be displayed in the search bar:

Download action

After downloading, the user can access the application from the desktop, just like any other native app:

downloaded PWA

Sending Notifications

It is also possible to integrate push notifications in your Blazor Application to notify users about events and updates

  1. First, navigate to wwwroot/index.html and add the JS function, which will send the notifications to the user:
    <script>
      navigator.serviceWorker.register('service-worker.js');
    
      (function (global) {
          global.sendNotification = (message) => {
            if(window.Notification && Notification.permission !== "denied") {
                Notification.requestPermission(function(status) {  
                  // status is "granted", if accepted by user
                  var n = new Notification('Smart UI', { 
                    body: message
                  }); 
                });
            }
          }  
      })(window); 
    </script>
  2. To call the JS from the Blazor application it is necessary to use JSInterop. Inject IJSRuntime at the top of the Index.razor page:
    @inject IJSRuntime JSRuntime
  3. Use Smart.ProgressBar to create a file upload loading bar which will slowly fill up.:
    <div style="margin-top:30px">
      <h3>Uploading files...</h3>
      <ProgressBar  @ref="@progressBar" Class="barber-shop-effect"></ProgressBar>
    </div>
    
    @code{
      ProgressBar progressBar;
      protected override void OnInitialized()
      {
          base.OnInitialized();
          System.Timers.Timer timer = new System.Timers.Timer(5000);
          
          timer = new System.Timers.Timer();
          timer.Elapsed += (sender, eventArgs) => {
            if(progressBar.Value==100){
              //Sending Notification
              JSRuntime.InvokeVoidAsync("sendNotification", "Files succesfully  uploaded!");
              timer.Stop();
            }
            else{
              progressBar.Value+=1; 
            }
          };
          timer.Start();
      }
    }
  4. When the progress bar reaches 100, the app will call the sendNotification() JS function using JSInterop:
    //Sending Notification
    JSRuntime.InvokeVoidAsync("sendNotification", "Files succesfully  uploaded!");
Notification