{"id":21015579,"url":"https://github.com/lostbeard/blazorserviceworkerdemo","last_synced_at":"2025-05-15T05:32:12.007Z","repository":{"id":201835168,"uuid":"707402062","full_name":"LostBeard/BlazorServiceWorkerDemo","owner":"LostBeard","description":"This Blazor WASM demos using a Blazor WASM ServiceWorker!","archived":false,"fork":false,"pushed_at":"2025-04-19T14:54:32.000Z","size":24307,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-05-12T01:36:47.620Z","etag":null,"topics":["blazor","blazor-webassembly","csharp","dotnet","multithreading","service-worker","webassembly"],"latest_commit_sha":null,"homepage":"https://lostbeard.github.io/BlazorServiceWorkerDemo/","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/LostBeard.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-10-19T20:27:25.000Z","updated_at":"2025-04-19T14:54:36.000Z","dependencies_parsed_at":"2024-07-23T01:41:10.918Z","dependency_job_id":"2b5e50e2-d42b-4d02-ac01-c474dbead78b","html_url":"https://github.com/LostBeard/BlazorServiceWorkerDemo","commit_stats":null,"previous_names":["lostbeard/blazorserviceworkerdemo"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LostBeard%2FBlazorServiceWorkerDemo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LostBeard%2FBlazorServiceWorkerDemo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LostBeard%2FBlazorServiceWorkerDemo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LostBeard%2FBlazorServiceWorkerDemo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/LostBeard","download_url":"https://codeload.github.com/LostBeard/BlazorServiceWorkerDemo/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254282236,"owners_count":22045123,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["blazor","blazor-webassembly","csharp","dotnet","multithreading","service-worker","webassembly"],"created_at":"2024-11-19T10:10:28.116Z","updated_at":"2025-05-15T05:32:11.620Z","avatar_url":"https://github.com/LostBeard.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Blazor WASM ServiceWorker Demo\n\nBlazor WASM running as your ServiceWorker! Thanks to [SpawnDev.BlazorJS.WebWorkers](https://github.com/LostBeard/SpawnDev.BlazorJS#spawndevblazorjswebworkers) it is now possible to run Blazor WASM in all browser Worker contexts: DedicatedWorker, SharedWorker, and ServiceWorker.\n\n[Live Demo](https://lostbeard.github.io/BlazorServiceWorkerDemo/)\n\nThe live demo is nothing special at the moment. In Chrome you can see the Blazor messages from the worker handler handling events. Firefox ServiceWorker console can be found at \"about:debugging#/runtime/this-firefox\"\n\nThis code demonstrates loading a Blazor WASM inside a ServiceWorker context and handling any events a ServiceWorker may want. Like install, fetch, push, sync, etc.\n\nThis is currently a working proof of concept and likely to change. Any and all feedback is welcome!\n\nThis project relies on a couple of my other projects [SpawnDev.BlazorJS](https://github.com/LostBeard/SpawnDev.BlazorJS) and [SpawnDev.BlazorJS.WebWorkers](https://github.com/LostBeard/SpawnDev.BlazorJS.WebWorkers)\n\n## Quick Start\nA very basic and verbose example. Create a new .Net 8 Blazor WebAssembly Standalone App project. `Progressive Web Application` is optional, but not needed for this example.\n\n### Add Nuget\nAdd Nuget SpawnDev.BlazorJS.WebWorkers to the project.  \n[![NuGet](https://img.shields.io/nuget/dt/SpawnDev.BlazorJS.WebWorkers.svg?label=SpawnDev.BlazorJS.WebWorkers)](https://www.nuget.org/packages/SpawnDev.BlazorJS.WebWorkers)  \n\n### wwwroot/index.html\nIf your project is a PWA, remove the ServiceWorker registration from `index.html`. SpawnDev.BlazorJS.WebWorkers will register the service worker on its own when called in the `Program.cs`.\n  \nDelete below line (if found) in `index.html`:  \n`\u003cscript\u003enavigator.serviceWorker.register('service-worker.js');\u003c/script\u003e`\n\n### Program.cs\nA minimal Program.cs\n```cs\nvar builder = WebAssemblyHostBuilder.CreateDefault(args);\nbuilder.RootComponents.Add\u003cApp\u003e(\"#app\");\nbuilder.RootComponents.Add\u003cHeadOutlet\u003e(\"head::after\");\n// SpawnDev.BlazorJS\nbuilder.Services.AddBlazorJSRuntime();\n// SpawnDev.BlazorJS.WebWorkers\nbuilder.Services.AddWebWorkerService();\n// Register a ServiceWorker handler (AppServiceWorker here) that inherits from ServiceWorkerEventHandler\nbuilder.Services.RegisterServiceWorker\u003cAppServiceWorker\u003e();\n// Or Unregister the ServiceWorker if no longer desired\n//builder.Services.UnregisterServiceWorker();\n// SpawnDev.BlazorJS startup (replaces RunAsync())\nawait builder.Build().BlazorJSRunAsync();\n```\n\n### AppServiceWorker.cs\nA verbose service worker implementation.\n- Handle ServiceWorker events by overriding the ServiceWorkerEventHandler base class virtual methods.\n- The ServiceWorker event handlers are only called when running in a ServiceWorkerGlobalScope context.\n- The AppServiceWorker singleton may be started in any scope and therefore must be scope aware. (For example, do not try to use localStorage in a Worker scope.)\n\n```cs\npublic class AppServiceWorker : ServiceWorkerEventHandler\n{\n    public AppServiceWorker(BlazorJSRuntime js) : base(js)\n    {\n\n    }\n\n    // called before any ServiceWorker events are handled\n    protected override async Task OnInitializedAsync()\n    {\n        // This service may start in any scope. This will be called before the app runs.\n        // If JS.IsWindow == true be careful not stall here.\n        // you can do initialization based on the scope that is running\n        Log(\"GlobalThisTypeName\", JS.GlobalThisTypeName);\n    }\n\n    protected override async Task ServiceWorker_OnInstallAsync(ExtendableEvent e)\n    {\n        Log($\"ServiceWorker_OnInstallAsync\");\n        _ = ServiceWorkerThis!.SkipWaiting();   // returned task can be ignored\n    }\n\n    protected override async Task ServiceWorker_OnActivateAsync(ExtendableEvent e)\n    {\n        Log($\"ServiceWorker_OnActivateAsync\");\n        await ServiceWorkerThis!.Clients.Claim();\n    }\n\n    protected override async Task\u003cResponse\u003e ServiceWorker_OnFetchAsync(FetchEvent e)\n    {\n        Log($\"ServiceWorker_OnFetchAsync\", e.Request.Method, e.Request.Url);\n        Response ret;\n        try\n        {\n            ret = await JS.Fetch(e.Request);\n        }\n        catch (Exception ex)\n        {\n            ret = new Response(ex.Message, new ResponseOptions { Status = 500, StatusText = ex.Message, Headers = new Dictionary\u003cstring, string\u003e { { \"Content-Type\", \"text/plain\" } } });\n            Log($\"ServiceWorker_OnFetchAsync failed: {ex.Message}\");\n        }\n        return ret;\n    }\n\n    protected override async Task ServiceWorker_OnMessageAsync(ExtendableMessageEvent e)\n    {\n        Log($\"ServiceWorker_OnMessageAsync\");\n    }\n\n    protected override async Task ServiceWorker_OnPushAsync(PushEvent e)\n    {\n        Log($\"ServiceWorker_OnPushAsync\");\n    }\n\n    protected override void ServiceWorker_OnPushSubscriptionChange(Event e)\n    {\n        Log($\"ServiceWorker_OnPushSubscriptionChange\");\n    }\n\n    protected override async Task ServiceWorker_OnSyncAsync(SyncEvent e)\n    {\n        Log($\"ServiceWorker_OnSyncAsync\");\n    }\n\n    protected override async Task ServiceWorker_OnNotificationCloseAsync(NotificationEvent e)\n    {\n        Log($\"ServiceWorker_OnNotificationCloseAsync\");\n    }\n\n    protected override async Task ServiceWorker_OnNotificationClickAsync(NotificationEvent e)\n    {\n        Log($\"ServiceWorker_OnNotificationClickAsync\");\n    }\n}\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flostbeard%2Fblazorserviceworkerdemo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flostbeard%2Fblazorserviceworkerdemo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flostbeard%2Fblazorserviceworkerdemo/lists"}