Last active
March 12, 2024 15:08
-
-
Save guillaume86/8f80aef3ca52fffa77834bdecd997e73 to your computer and use it in GitHub Desktop.
Integrating MiniProfiler into a SPA (React, Angular, Vue, etc)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* GET /mini-profiler-includes returns a <script> element | |
* Re-create it in the DOM and append it to the document. | |
* | |
* Using ES5 for maximum compatibilty. | |
*/ | |
(function (window) { | |
if ("MiniProfiler" in window) return console.warn("MiniProfiler already imported."); | |
var ERROR_MESSAGE = "MiniProfiler could not be loaded: "; | |
function getIncludes(callback) { | |
var xhr = new XMLHttpRequest(); | |
xhr.onload = function () { | |
if (this.status !== 200) return callback(ERROR_MESSAGE + "request error.") | |
callback(null, this.responseText); | |
}; | |
xhr.onerror = function () { | |
callback(ERROR_MESSAGE + "request error.") | |
} | |
xhr.open("GET", "/mini-profiler-includes", true); | |
xhr.send(); | |
} | |
function loadScript(scriptHtml) { | |
if (!("DOMParser" in window) || !DOMParser.prototype.parseFromString) { | |
console.error(ERROR_MESSAGE + "DOMParser::parseFromString not supported (IE9?)"); | |
return; | |
} | |
try { | |
var parser = new DOMParser(); | |
var doc = parser.parseFromString(scriptHtml, "text/html"); | |
var scriptParsed = doc.querySelector("script"); | |
if (!scriptParsed) return; | |
var script = document.createElement("script"); | |
for (var i = 0; i < scriptParsed.attributes.length; i++) { | |
var attribute = scriptParsed.attributes[i]; | |
script.setAttribute(attribute.name, attribute.value); | |
} | |
var target = document.getElementsByTagName("script")[0]; | |
target.parentNode.insertBefore(script, target); | |
} catch (err) { | |
console.error(ERROR_MESSAGE + err.toString()); | |
} | |
} | |
getIncludes(function (err, scriptHTML) { | |
if (err) return console.error(err); | |
if (!scriptHTML) return; | |
loadScript(scriptHTML); | |
}); | |
})(window); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
using System.Threading.Tasks; | |
using Microsoft.AspNetCore.Builder; | |
using Microsoft.AspNetCore.Routing; | |
namespace StackExchange.Profiling | |
{ | |
public static class MiniProfilerSpaExtensions | |
{ | |
public static void MapMiniProfilerIncludes(this IEndpointRouteBuilder endpoints, RenderOptions? options = null, string url = "mini-profiler-includes") | |
{ | |
endpoints.MapGet(url, async (context) => | |
{ | |
context.Response.ContentType = "text/html"; | |
var includes = MiniProfiler.Current.RenderIncludes(context, options); | |
if (String.IsNullOrEmpty(includes.Value)) | |
return; | |
await context.Response.BodyWriter.WriteAsync(Encoding.UTF8.GetBytes(includes.Value)); | |
}); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#nullable enable | |
using Microsoft.AspNetCore.Authentication; | |
using Microsoft.AspNetCore.Builder; | |
using Microsoft.AspNetCore.Hosting; | |
using Microsoft.AspNetCore.HttpsPolicy; | |
using Microsoft.AspNetCore.Identity; | |
using Microsoft.AspNetCore.Identity.UI; | |
using Microsoft.AspNetCore.Routing; | |
using Microsoft.AspNetCore.SpaServices.ReactDevelopmentServer; | |
using Microsoft.EntityFrameworkCore; | |
using Microsoft.Extensions.Configuration; | |
using Microsoft.Extensions.DependencyInjection; | |
using Microsoft.Extensions.Hosting; | |
using StackExchange.Profiling; | |
using System; | |
using System.Globalization; | |
namespace MyApp | |
{ | |
public class Startup | |
{ | |
public Startup(IConfiguration configuration) | |
{ | |
Configuration = configuration; | |
} | |
public IConfiguration Configuration { get; } | |
public void ConfigureServices(IServiceCollection services) | |
{ | |
// ... | |
services.AddMiniProfiler(options => | |
{ | |
// ... | |
}); | |
} | |
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. | |
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) | |
{ | |
// ... | |
app.UseMiniProfiler(); | |
// ... | |
app.UseEndpoints(endpoints => | |
{ | |
endpoints.MapMiniProfilerIncludes(new RenderOptions | |
{ | |
StartHidden = true, | |
PopupToggleKeyboardShortcut = "Ctrl+m", | |
}); | |
// ... | |
}); | |
app.UseSpa(spa => | |
{ | |
// ... | |
}); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Here's the code I use to import MiniProfiler into a React SPA. It should work with any other client side stack. You can import MiniProfiler.js either with a script tag in your index.html or include it in your bundle.