Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,7 @@ The steps described above will get you up and running with minimal setup. Howeve
* [Swashbuckle.AspNetCore.SwaggerUI](#swashbuckleaspnetcoreswaggerui)
* [Change Relative Path to the UI](#change-relative-path-to-the-ui)
* [Change Document Title](#change-document-title)
* [Change CSS or JS Paths](#change-css-or-js-paths)
* [List Multiple Swagger Documents](#list-multiple-swagger-documents)
* [Apply swagger-ui Parameters](#apply-swagger-ui-parameters)
* [Inject Custom JavaScript](#inject-custom-javascript)
Expand Down Expand Up @@ -1254,6 +1255,19 @@ app.UseSwaggerUI(c =>
}
```

### Change CSS or JS Paths ###

By default, the Swagger UI inclide default CSS and JS, but if you need to change path or URL (ex CDN):

```csharp
app.UseSwaggerUI(c =>
{
c.StylesPath = "https://cdnjs.cloudflare.com/ajax/libs/swagger-ui/5.17.10/swagger-ui.min.css";
c.ScriptBundlePath = "https://cdnjs.cloudflare.com/ajax/libs/swagger-ui/5.17.10/swagger-ui-bundle.min.js";
c.ScriptPresetsPath = "https://cdnjs.cloudflare.com/ajax/libs/swagger-ui/5.17.10/swagger-ui-standalone-preset.min.js";
}
```

### List Multiple Swagger Documents ###

When enabling the middleware, you're required to specify one or more Swagger endpoints (fully qualified or relative to the UI page) to power the UI. If you provide multiple endpoints, they'll be listed in the top right corner of the page, allowing users to toggle between the different documents. For example, the following configuration could be used to document different versions of an API.
Expand Down
3 changes: 3 additions & 0 deletions src/Swashbuckle.AspNetCore.SwaggerUI/SwaggerUIMiddleware.cs
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,9 @@ private Dictionary<string, string> GetIndexArguments()
{
{ "%(DocumentTitle)", _options.DocumentTitle },
{ "%(HeadContent)", _options.HeadContent },
{ "%(StylesPath)", _options.StylesPath },
{ "%(ScriptBundlePath)", _options.ScriptBundlePath },
{ "%(ScriptPresetsPath)", _options.ScriptPresetsPath },
{ "%(ConfigObject)", configObject },
{ "%(OAuthConfigObject)", oauthConfigObject },
{ "%(Interceptors)", interceptors },
Expand Down
15 changes: 15 additions & 0 deletions src/Swashbuckle.AspNetCore.SwaggerUI/SwaggerUIOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,21 @@ public class SwaggerUIOptions
/// Gets or sets the optional JSON serialization options to use to serialize options to the HTML document.
/// </summary>
public JsonSerializerOptions JsonSerializerOptions { get; set; }

/// <summary>
/// Gets or sets the path or URL to the Swagger UI JavaScript bundle file.
/// </summary>
public string ScriptBundlePath { get; set; } = "./swagger-ui-bundle.js";

/// <summary>
/// Gets or sets the path or URL to the Swagger UI JavaScript standalone presets file.
/// </summary>
public string ScriptPresetsPath { get; set; } = "./swagger-ui-standalone-preset.js";

/// <summary>
/// Gets or sets the path or URL to the Swagger UI CSS file.
/// </summary>
public string StylesPath { get; set; } = "./swagger-ui.css";
}

public class ConfigObject
Expand Down
6 changes: 3 additions & 3 deletions src/Swashbuckle.AspNetCore.SwaggerUI/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<head>
<meta charset="UTF-8">
<title>%(DocumentTitle)</title>
<link rel="stylesheet" type="text/css" href="./swagger-ui.css">
<link rel="stylesheet" type="text/css" href="%(StylesPath)">
<link rel="icon" type="image/png" href="./favicon-32x32.png" sizes="32x32" />
<link rel="icon" type="image/png" href="./favicon-16x16.png" sizes="16x16" />
<style>
Expand Down Expand Up @@ -40,8 +40,8 @@
}
</script>

<script src="./swagger-ui-bundle.js"></script>
<script src="./swagger-ui-standalone-preset.js"></script>
<script src="%(ScriptBundlePath)"></script>
<script src="%(ScriptPresetsPath)"></script>
<script>
/* Source: https://gist.github.com/lamberta/3768814
* Parse a string function definition and return a function object. Does not use eval.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,5 +88,26 @@ public async Task SwaggerUIMiddleware_CanBeConfiguredMultipleTimes(string swagge
Assert.Contains(version, content);
}
}

[Theory]
[InlineData(typeof(Basic.Startup), "/index.html", "./swagger-ui.css", "./swagger-ui-bundle.js", "./swagger-ui-standalone-preset.js")]
[InlineData(typeof(CustomUIConfig.Startup), "/swagger/index.html", "/ext/custom-stylesheet.css", "/ext/custom-javascript.js", "/ext/custom-javascript.js")]
public async Task IndexUrl_Returns_ExpectedAssetPaths(
Type startupType,
string indexPath,
string cssPath,
string scriptBundlePath,
string scriptPresetsPath)
{
var client = new TestSite(startupType).BuildClient();

var indexResponse = await client.GetAsync(indexPath);
Assert.Equal(HttpStatusCode.OK, indexResponse.StatusCode);
var content = await indexResponse.Content.ReadAsStringAsync();

Assert.Contains($"<link rel=\"stylesheet\" type=\"text/css\" href=\"{cssPath}\">", content);
Assert.Contains($"<script src=\"{scriptBundlePath}\">", content);
Assert.Contains($"<script src=\"{scriptPresetsPath}\">", content);
}
}
}
3 changes: 3 additions & 0 deletions test/WebSites/CustomUIConfig/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env)

// Other
c.DocumentTitle = "CustomUIConfig";
c.StylesPath = "/ext/custom-stylesheet.css";
c.ScriptBundlePath = "/ext/custom-javascript.js";
c.ScriptPresetsPath = "/ext/custom-javascript.js";
c.InjectStylesheet("/ext/custom-stylesheet.css");
c.InjectJavascript("/ext/custom-javascript.js");
c.UseRequestInterceptor("(req) => { req.headers['x-my-custom-header'] = 'MyCustomValue'; return req; }");
Expand Down