Skip to content

Commit bdd29df

Browse files
dayportmadskristensen
authored andcommitted
Modifications to allow running the application from an IIS virtual directory (#59)
1 parent e5feec1 commit bdd29df

6 files changed

Lines changed: 71 additions & 5 deletions

File tree

README.md

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,5 +263,63 @@ This strategy will always try the network first for all resources and then fall
263263

264264
This strategy is completely safe to use and is primarily useful for offline-only scenarios since it isn't giving any performance benefits.
265265

266+
## .Net Core Application hosted as Virtual Directory
267+
You can now specify a specific BaseURL if you plan to host your application as a Virtual Directory in IIS:
268+
269+
```c#
270+
private const string _baseURL = "/PWAApp";
271+
272+
public void ConfigureServices(IServiceCollection services)
273+
{
274+
services.AddMvc();
275+
services.AddServiceWorker(new PwaOptions
276+
{
277+
BaseRoute = _baseURL;
278+
Strategy = ServiceWorkerStrategy.CacheFirst
279+
});
280+
}
281+
282+
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
283+
{
284+
//...
285+
app.UsePathBase(_baseURL);
286+
//...
287+
}
288+
```
289+
290+
...or in `appsettings.json`:
291+
292+
```json
293+
{
294+
"serviceworker": {
295+
"baseRoute": "/PWAApp",
296+
"strategy": "cacheFirst"
297+
}
298+
}
299+
```
300+
301+
Make sure to update your `wwwroot/manifest.json` file:
302+
303+
```json
304+
{
305+
"name": "Awesome Application",
306+
"short_name": "Awesome",
307+
"description": "The most awesome application in the world",
308+
"icons": [
309+
{
310+
"src": "/PWAApp/img/icon192x192.png",
311+
"sizes": "192x192"
312+
},
313+
{
314+
"src": "/PWAApp/img/icon512x512.png",
315+
"sizes": "512x512"
316+
}
317+
],
318+
"display": "standalone",
319+
"start_url": "/PWAApp"
320+
}
321+
```
322+
323+
266324
## License
267325
[Apache 2.0](LICENSE)

src/PwaController.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public async Task<IActionResult> ServiceWorkerAsync()
4242
string modified = js
4343
.Replace("{version}", _options.CacheId + "::" + _options.Strategy)
4444
.Replace("{routes}", string.Join(",", _options.RoutesToPreCache.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(r => "'" + r.Trim() + "'")))
45-
.Replace("{offlineRoute}", _options.OfflineRoute);
45+
.Replace("{offlineRoute}", _options.BaseRoute + _options.OfflineRoute);
4646

4747
return Content(modified);
4848
}

src/PwaOptions.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ public PwaOptions()
1616
CacheId = Constants.DefaultCacheId;
1717
Strategy = ServiceWorkerStrategy.CacheFirstSafe;
1818
RoutesToPreCache = "";
19+
BaseRoute = "";
1920
OfflineRoute = Constants.Offlineroute;
2021
RegisterServiceWorker = true;
2122
RegisterWebmanifest = true;
@@ -29,6 +30,7 @@ internal PwaOptions(IConfiguration config)
2930
{
3031
CacheId = config["pwa:cacheId"] ?? CacheId;
3132
RoutesToPreCache = config["pwa:routesToPreCache"] ?? RoutesToPreCache;
33+
BaseRoute = config["pwa:baseRoute"] ?? BaseRoute;
3234
OfflineRoute = config["pwa:offlineRoute"] ?? OfflineRoute;
3335

3436
if (bool.TryParse(config["pwa:registerServiceWorker"] ?? "true", out bool register))
@@ -78,6 +80,11 @@ internal PwaOptions(IConfiguration config)
7880
/// </summary>
7981
public string RoutesToPreCache { get; set; }
8082

83+
/// <summary>
84+
/// The base route to the application.
85+
/// </summary>
86+
public string BaseRoute { get; set; }
87+
8188
/// <summary>
8289
/// The route to the page to show when offline.
8390
/// </summary>

src/ServiceCollectionExtensions.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ public static class ServiceCollectionExtensions
1717
/// </summary>
1818
public static IServiceCollection AddServiceWorker(this IServiceCollection services)
1919
{
20-
2120
services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
2221
services.AddTransient<ITagHelperComponent, ServiceWorkerTagHelperComponent>();
2322
services.AddTransient(svc => new PwaOptions(svc.GetRequiredService<IConfiguration>()));
@@ -40,12 +39,13 @@ public static IServiceCollection AddServiceWorker(this IServiceCollection servic
4039
/// <summary>
4140
/// Adds ServiceWorker services to the specified <see cref="IServiceCollection"/>.
4241
/// </summary>
43-
public static IServiceCollection AddServiceWorker(this IServiceCollection services, string offlineRoute = Constants.Offlineroute, ServiceWorkerStrategy strategy = ServiceWorkerStrategy.CacheFirstSafe, bool registerServiceWorker = true, bool registerWebManifest = true, string cacheId = Constants.DefaultCacheId, string routesToPreCache = "")
42+
public static IServiceCollection AddServiceWorker(this IServiceCollection services, string baseRoute = "", string offlineRoute = Constants.Offlineroute, ServiceWorkerStrategy strategy = ServiceWorkerStrategy.CacheFirstSafe, bool registerServiceWorker = true, bool registerWebManifest = true, string cacheId = Constants.DefaultCacheId, string routesToPreCache = "")
4443
{
4544
services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
4645
services.AddTransient<ITagHelperComponent, ServiceWorkerTagHelperComponent>();
4746
services.AddTransient(factory => new PwaOptions
4847
{
48+
BaseRoute = baseRoute,
4949
OfflineRoute = offlineRoute,
5050
Strategy = strategy,
5151
RegisterServiceWorker = registerServiceWorker,

src/ServiceWorker/ServiceWorkerTagHelperComponent.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public ServiceWorkerTagHelperComponent(IHostingEnvironment env, IHttpContextAcce
1919
_accessor = accessor;
2020
_options = options;
2121

22-
_script = "\r\n\t<script" + (_options.EnableCspNonce ? Constants.CspNonce : string.Empty) + ">'serviceWorker'in navigator&&navigator.serviceWorker.register('" + Constants.ServiceworkerRoute + "')</script>";
22+
_script = "\r\n\t<script" + (_options.EnableCspNonce ? Constants.CspNonce : string.Empty) + ">'serviceWorker'in navigator&&navigator.serviceWorker.register('" + options.BaseRoute + Constants.ServiceworkerRoute + "')</script>";
2323
}
2424

2525
/// <inheritdoc />

src/Webmanifest/WebmanifestTagHelperComponent.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,15 @@ namespace WebEssentials.AspNetCore.Pwa
55
{
66
internal class WebmanifestTagHelperComponent : TagHelperComponent
77
{
8-
private const string _link = "\t<link rel=\"manifest\" href=\"" + Constants.WebManifestRoute + "\" />\r\n";
8+
private string _link;
99
private const string _themeFormat = "\t<meta name=\"theme-color\" content=\"{0}\" />\r\n";
1010
private PwaOptions _options;
1111
private readonly IServiceProvider _serviceProvider;
1212

1313
public WebmanifestTagHelperComponent(PwaOptions options, IServiceProvider serviceProvider)
1414
{
1515
_options = options;
16+
_link = "\t<link rel=\"manifest\" href=\"" + options.BaseRoute + Constants.WebManifestRoute + "\" />\r\n";
1617
_serviceProvider = serviceProvider;
1718
}
1819

0 commit comments

Comments
 (0)