diff --git a/eng/Versions.props b/eng/Versions.props
index 2a0e6cca66b1..efd1aaa5ed4b 100644
--- a/eng/Versions.props
+++ b/eng/Versions.props
@@ -156,6 +156,9 @@
2.64.0
2.64.0
2.5.187
+
+ 10.0.0
+ 10.0.0
3.14.1
3.14.1
3.14.1
@@ -168,6 +171,11 @@
1.0.2
13.0.3
13.0.4
+
+ 1.10.0
+ 1.10.0
+ 1.10.0
+ 1.10.0
2.5.2
1.56.0
3.0.0
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/BlazorWasmServiceDefaults-CSharp.csproj.in b/src/ProjectTemplates/Web.ProjectTemplates/BlazorWasmServiceDefaults-CSharp.csproj.in
new file mode 100644
index 000000000000..b5293955d3e1
--- /dev/null
+++ b/src/ProjectTemplates/Web.ProjectTemplates/BlazorWasmServiceDefaults-CSharp.csproj.in
@@ -0,0 +1,24 @@
+
+
+
+ ${DefaultNetCoreTargetFramework}
+ enable
+ enable
+ BlazorWasm.ServiceDefaults1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/Microsoft.DotNet.Web.ProjectTemplates.csproj b/src/ProjectTemplates/Web.ProjectTemplates/Microsoft.DotNet.Web.ProjectTemplates.csproj
index 92879cd52586..ad4ba6a0a1da 100644
--- a/src/ProjectTemplates/Web.ProjectTemplates/Microsoft.DotNet.Web.ProjectTemplates.csproj
+++ b/src/ProjectTemplates/Web.ProjectTemplates/Microsoft.DotNet.Web.ProjectTemplates.csproj
@@ -19,10 +19,16 @@
MicrosoftEntityFrameworkCoreToolsVersion=$(MicrosoftEntityFrameworkCoreToolsVersion);
MicrosoftExtensionsHostingVersion=$(MicrosoftExtensionsHostingVersion);
MicrosoftExtensionsHttpVersion=$(MicrosoftExtensionsHttpVersion);
+ MicrosoftExtensionsHttpResilienceVersion=$(MicrosoftExtensionsHttpResilienceVersion);
+ MicrosoftExtensionsServiceDiscoveryVersion=$(MicrosoftExtensionsServiceDiscoveryVersion);
MicrosoftIdentityWebVersion=$(MicrosoftIdentityWebVersion);
MicrosoftIdentityWebGraphServiceClientVersion=$(MicrosoftIdentityWebGraphServiceClientVersion);
MicrosoftIdentityWebUIVersion=$(MicrosoftIdentityWebUIVersion);
MicrosoftIdentityWebDownstreamApiVersion=$(MicrosoftIdentityWebDownstreamApiVersion);
+ OpenTelemetryExporterOpenTelemetryProtocolVersion=$(OpenTelemetryExporterOpenTelemetryProtocolVersion);
+ OpenTelemetryExtensionsHostingVersion=$(OpenTelemetryExtensionsHostingVersion);
+ OpenTelemetryInstrumentationHttpVersion=$(OpenTelemetryInstrumentationHttpVersion);
+ OpenTelemetryInstrumentationRuntimeVersion=$(OpenTelemetryInstrumentationRuntimeVersion);
SystemNetHttpJsonVersion=$(SystemNetHttpJsonVersion);
MicrosoftGraphVersion=$(MicrosoftGraphVersion);
@@ -62,6 +68,7 @@
+
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWasmServiceDefaults-CSharp/.template.config/localize/templatestrings.cs.json b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWasmServiceDefaults-CSharp/.template.config/localize/templatestrings.cs.json
new file mode 100644
index 000000000000..ecb64b39ad67
--- /dev/null
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWasmServiceDefaults-CSharp/.template.config/localize/templatestrings.cs.json
@@ -0,0 +1,10 @@
+{
+ "author": "Microsoft",
+ "name": "Blazor WebAssembly Service Defaults",
+ "description": "A project template for creating a service defaults library for Blazor WebAssembly applications. Includes OpenTelemetry, service discovery, and resilience support for Aspire integration.",
+ "symbols/Framework/description": "The target framework for the project.",
+ "symbols/Framework/choices/net10.0/description": "Target net10.0",
+ "symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
+ "postActions/restore/description": "Restore NuGet packages required by this project.",
+ "postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
+}
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWasmServiceDefaults-CSharp/.template.config/localize/templatestrings.de.json b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWasmServiceDefaults-CSharp/.template.config/localize/templatestrings.de.json
new file mode 100644
index 000000000000..ecb64b39ad67
--- /dev/null
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWasmServiceDefaults-CSharp/.template.config/localize/templatestrings.de.json
@@ -0,0 +1,10 @@
+{
+ "author": "Microsoft",
+ "name": "Blazor WebAssembly Service Defaults",
+ "description": "A project template for creating a service defaults library for Blazor WebAssembly applications. Includes OpenTelemetry, service discovery, and resilience support for Aspire integration.",
+ "symbols/Framework/description": "The target framework for the project.",
+ "symbols/Framework/choices/net10.0/description": "Target net10.0",
+ "symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
+ "postActions/restore/description": "Restore NuGet packages required by this project.",
+ "postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
+}
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWasmServiceDefaults-CSharp/.template.config/localize/templatestrings.en.json b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWasmServiceDefaults-CSharp/.template.config/localize/templatestrings.en.json
new file mode 100644
index 000000000000..ecb64b39ad67
--- /dev/null
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWasmServiceDefaults-CSharp/.template.config/localize/templatestrings.en.json
@@ -0,0 +1,10 @@
+{
+ "author": "Microsoft",
+ "name": "Blazor WebAssembly Service Defaults",
+ "description": "A project template for creating a service defaults library for Blazor WebAssembly applications. Includes OpenTelemetry, service discovery, and resilience support for Aspire integration.",
+ "symbols/Framework/description": "The target framework for the project.",
+ "symbols/Framework/choices/net10.0/description": "Target net10.0",
+ "symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
+ "postActions/restore/description": "Restore NuGet packages required by this project.",
+ "postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
+}
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWasmServiceDefaults-CSharp/.template.config/localize/templatestrings.es.json b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWasmServiceDefaults-CSharp/.template.config/localize/templatestrings.es.json
new file mode 100644
index 000000000000..ecb64b39ad67
--- /dev/null
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWasmServiceDefaults-CSharp/.template.config/localize/templatestrings.es.json
@@ -0,0 +1,10 @@
+{
+ "author": "Microsoft",
+ "name": "Blazor WebAssembly Service Defaults",
+ "description": "A project template for creating a service defaults library for Blazor WebAssembly applications. Includes OpenTelemetry, service discovery, and resilience support for Aspire integration.",
+ "symbols/Framework/description": "The target framework for the project.",
+ "symbols/Framework/choices/net10.0/description": "Target net10.0",
+ "symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
+ "postActions/restore/description": "Restore NuGet packages required by this project.",
+ "postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
+}
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWasmServiceDefaults-CSharp/.template.config/localize/templatestrings.fr.json b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWasmServiceDefaults-CSharp/.template.config/localize/templatestrings.fr.json
new file mode 100644
index 000000000000..ecb64b39ad67
--- /dev/null
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWasmServiceDefaults-CSharp/.template.config/localize/templatestrings.fr.json
@@ -0,0 +1,10 @@
+{
+ "author": "Microsoft",
+ "name": "Blazor WebAssembly Service Defaults",
+ "description": "A project template for creating a service defaults library for Blazor WebAssembly applications. Includes OpenTelemetry, service discovery, and resilience support for Aspire integration.",
+ "symbols/Framework/description": "The target framework for the project.",
+ "symbols/Framework/choices/net10.0/description": "Target net10.0",
+ "symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
+ "postActions/restore/description": "Restore NuGet packages required by this project.",
+ "postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
+}
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWasmServiceDefaults-CSharp/.template.config/localize/templatestrings.it.json b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWasmServiceDefaults-CSharp/.template.config/localize/templatestrings.it.json
new file mode 100644
index 000000000000..ecb64b39ad67
--- /dev/null
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWasmServiceDefaults-CSharp/.template.config/localize/templatestrings.it.json
@@ -0,0 +1,10 @@
+{
+ "author": "Microsoft",
+ "name": "Blazor WebAssembly Service Defaults",
+ "description": "A project template for creating a service defaults library for Blazor WebAssembly applications. Includes OpenTelemetry, service discovery, and resilience support for Aspire integration.",
+ "symbols/Framework/description": "The target framework for the project.",
+ "symbols/Framework/choices/net10.0/description": "Target net10.0",
+ "symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
+ "postActions/restore/description": "Restore NuGet packages required by this project.",
+ "postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
+}
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWasmServiceDefaults-CSharp/.template.config/localize/templatestrings.ja.json b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWasmServiceDefaults-CSharp/.template.config/localize/templatestrings.ja.json
new file mode 100644
index 000000000000..ecb64b39ad67
--- /dev/null
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWasmServiceDefaults-CSharp/.template.config/localize/templatestrings.ja.json
@@ -0,0 +1,10 @@
+{
+ "author": "Microsoft",
+ "name": "Blazor WebAssembly Service Defaults",
+ "description": "A project template for creating a service defaults library for Blazor WebAssembly applications. Includes OpenTelemetry, service discovery, and resilience support for Aspire integration.",
+ "symbols/Framework/description": "The target framework for the project.",
+ "symbols/Framework/choices/net10.0/description": "Target net10.0",
+ "symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
+ "postActions/restore/description": "Restore NuGet packages required by this project.",
+ "postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
+}
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWasmServiceDefaults-CSharp/.template.config/localize/templatestrings.ko.json b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWasmServiceDefaults-CSharp/.template.config/localize/templatestrings.ko.json
new file mode 100644
index 000000000000..ecb64b39ad67
--- /dev/null
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWasmServiceDefaults-CSharp/.template.config/localize/templatestrings.ko.json
@@ -0,0 +1,10 @@
+{
+ "author": "Microsoft",
+ "name": "Blazor WebAssembly Service Defaults",
+ "description": "A project template for creating a service defaults library for Blazor WebAssembly applications. Includes OpenTelemetry, service discovery, and resilience support for Aspire integration.",
+ "symbols/Framework/description": "The target framework for the project.",
+ "symbols/Framework/choices/net10.0/description": "Target net10.0",
+ "symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
+ "postActions/restore/description": "Restore NuGet packages required by this project.",
+ "postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
+}
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWasmServiceDefaults-CSharp/.template.config/localize/templatestrings.pl.json b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWasmServiceDefaults-CSharp/.template.config/localize/templatestrings.pl.json
new file mode 100644
index 000000000000..ecb64b39ad67
--- /dev/null
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWasmServiceDefaults-CSharp/.template.config/localize/templatestrings.pl.json
@@ -0,0 +1,10 @@
+{
+ "author": "Microsoft",
+ "name": "Blazor WebAssembly Service Defaults",
+ "description": "A project template for creating a service defaults library for Blazor WebAssembly applications. Includes OpenTelemetry, service discovery, and resilience support for Aspire integration.",
+ "symbols/Framework/description": "The target framework for the project.",
+ "symbols/Framework/choices/net10.0/description": "Target net10.0",
+ "symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
+ "postActions/restore/description": "Restore NuGet packages required by this project.",
+ "postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
+}
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWasmServiceDefaults-CSharp/.template.config/localize/templatestrings.pt-BR.json b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWasmServiceDefaults-CSharp/.template.config/localize/templatestrings.pt-BR.json
new file mode 100644
index 000000000000..ecb64b39ad67
--- /dev/null
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWasmServiceDefaults-CSharp/.template.config/localize/templatestrings.pt-BR.json
@@ -0,0 +1,10 @@
+{
+ "author": "Microsoft",
+ "name": "Blazor WebAssembly Service Defaults",
+ "description": "A project template for creating a service defaults library for Blazor WebAssembly applications. Includes OpenTelemetry, service discovery, and resilience support for Aspire integration.",
+ "symbols/Framework/description": "The target framework for the project.",
+ "symbols/Framework/choices/net10.0/description": "Target net10.0",
+ "symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
+ "postActions/restore/description": "Restore NuGet packages required by this project.",
+ "postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
+}
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWasmServiceDefaults-CSharp/.template.config/localize/templatestrings.ru.json b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWasmServiceDefaults-CSharp/.template.config/localize/templatestrings.ru.json
new file mode 100644
index 000000000000..ecb64b39ad67
--- /dev/null
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWasmServiceDefaults-CSharp/.template.config/localize/templatestrings.ru.json
@@ -0,0 +1,10 @@
+{
+ "author": "Microsoft",
+ "name": "Blazor WebAssembly Service Defaults",
+ "description": "A project template for creating a service defaults library for Blazor WebAssembly applications. Includes OpenTelemetry, service discovery, and resilience support for Aspire integration.",
+ "symbols/Framework/description": "The target framework for the project.",
+ "symbols/Framework/choices/net10.0/description": "Target net10.0",
+ "symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
+ "postActions/restore/description": "Restore NuGet packages required by this project.",
+ "postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
+}
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWasmServiceDefaults-CSharp/.template.config/localize/templatestrings.tr.json b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWasmServiceDefaults-CSharp/.template.config/localize/templatestrings.tr.json
new file mode 100644
index 000000000000..ecb64b39ad67
--- /dev/null
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWasmServiceDefaults-CSharp/.template.config/localize/templatestrings.tr.json
@@ -0,0 +1,10 @@
+{
+ "author": "Microsoft",
+ "name": "Blazor WebAssembly Service Defaults",
+ "description": "A project template for creating a service defaults library for Blazor WebAssembly applications. Includes OpenTelemetry, service discovery, and resilience support for Aspire integration.",
+ "symbols/Framework/description": "The target framework for the project.",
+ "symbols/Framework/choices/net10.0/description": "Target net10.0",
+ "symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
+ "postActions/restore/description": "Restore NuGet packages required by this project.",
+ "postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
+}
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWasmServiceDefaults-CSharp/.template.config/localize/templatestrings.zh-Hans.json b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWasmServiceDefaults-CSharp/.template.config/localize/templatestrings.zh-Hans.json
new file mode 100644
index 000000000000..ecb64b39ad67
--- /dev/null
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWasmServiceDefaults-CSharp/.template.config/localize/templatestrings.zh-Hans.json
@@ -0,0 +1,10 @@
+{
+ "author": "Microsoft",
+ "name": "Blazor WebAssembly Service Defaults",
+ "description": "A project template for creating a service defaults library for Blazor WebAssembly applications. Includes OpenTelemetry, service discovery, and resilience support for Aspire integration.",
+ "symbols/Framework/description": "The target framework for the project.",
+ "symbols/Framework/choices/net10.0/description": "Target net10.0",
+ "symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
+ "postActions/restore/description": "Restore NuGet packages required by this project.",
+ "postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
+}
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWasmServiceDefaults-CSharp/.template.config/localize/templatestrings.zh-Hant.json b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWasmServiceDefaults-CSharp/.template.config/localize/templatestrings.zh-Hant.json
new file mode 100644
index 000000000000..ecb64b39ad67
--- /dev/null
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWasmServiceDefaults-CSharp/.template.config/localize/templatestrings.zh-Hant.json
@@ -0,0 +1,10 @@
+{
+ "author": "Microsoft",
+ "name": "Blazor WebAssembly Service Defaults",
+ "description": "A project template for creating a service defaults library for Blazor WebAssembly applications. Includes OpenTelemetry, service discovery, and resilience support for Aspire integration.",
+ "symbols/Framework/description": "The target framework for the project.",
+ "symbols/Framework/choices/net10.0/description": "Target net10.0",
+ "symbols/skipRestore/description": "If specified, skips the automatic restore of the project on create.",
+ "postActions/restore/description": "Restore NuGet packages required by this project.",
+ "postActions/restore/manualInstructions/default/text": "Run 'dotnet restore'"
+}
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWasmServiceDefaults-CSharp/.template.config/template.json b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWasmServiceDefaults-CSharp/.template.config/template.json
new file mode 100644
index 000000000000..530df4d5dba9
--- /dev/null
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWasmServiceDefaults-CSharp/.template.config/template.json
@@ -0,0 +1,65 @@
+{
+ "$schema": "https://json.schemastore.org/template",
+ "author": "Microsoft",
+ "classifications": [
+ "Blazor",
+ "WebAssembly",
+ "Library",
+ "OpenTelemetry"
+ ],
+ "name": "Blazor WebAssembly Service Defaults",
+ "generatorVersions": "[1.0.0.0-*)",
+ "description": "A project template for creating a service defaults library for Blazor WebAssembly applications. Includes OpenTelemetry, service discovery, and resilience support for Aspire integration.",
+ "groupIdentity": "Microsoft.Web.Blazor.Wasm.ServiceDefaults",
+ "precedence": "10000",
+ "identity": "Microsoft.Web.Blazor.Wasm.ServiceDefaults.CSharp.10.0",
+ "shortName": "blazor-wasm-servicedefaults",
+ "thirdPartyNotices": "https://aka.ms/aspnetcore/10.0-third-party-notices",
+ "tags": {
+ "language": "C#",
+ "type": "project"
+ },
+ "sourceName": "BlazorWasm.ServiceDefaults1",
+ "preferNameDirectory": true,
+ "symbols": {
+ "Framework": {
+ "type": "parameter",
+ "description": "The target framework for the project.",
+ "datatype": "choice",
+ "choices": [
+ {
+ "choice": "net10.0",
+ "description": "Target net10.0"
+ }
+ ],
+ "replaces": "net10.0",
+ "defaultValue": "net10.0"
+ },
+ "skipRestore": {
+ "type": "parameter",
+ "datatype": "bool",
+ "description": "If specified, skips the automatic restore of the project on create.",
+ "defaultValue": "false"
+ }
+ },
+ "primaryOutputs": [
+ {
+ "path": "BlazorWasm.ServiceDefaults1.csproj"
+ }
+ ],
+ "defaultName": "BlazorWasm.ServiceDefaults",
+ "postActions": [
+ {
+ "id": "restore",
+ "condition": "(!skipRestore)",
+ "description": "Restore NuGet packages required by this project.",
+ "manualInstructions": [
+ {
+ "text": "Run 'dotnet restore'"
+ }
+ ],
+ "actionId": "210D431B-A78B-4D2F-B762-4ED3E3EA9025",
+ "continueOnError": true
+ }
+ ]
+}
diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWasmServiceDefaults-CSharp/Extensions.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWasmServiceDefaults-CSharp/Extensions.cs
new file mode 100644
index 000000000000..258f3870c72b
--- /dev/null
+++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWasmServiceDefaults-CSharp/Extensions.cs
@@ -0,0 +1,96 @@
+using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
+using OpenTelemetry;
+using OpenTelemetry.Logs;
+using OpenTelemetry.Metrics;
+using OpenTelemetry.Resources;
+using OpenTelemetry.Trace;
+
+namespace Microsoft.Extensions.Hosting;
+
+///
+/// Extension methods for configuring service defaults for Blazor WebAssembly clients.
+/// Adds OpenTelemetry, service discovery, and resilience support.
+///
+public static class BlazorClientExtensions
+{
+ private const string DefaultServiceName = "blazor-webassembly-client";
+
+ ///
+ /// Adds common service defaults for Blazor WebAssembly clients including
+ /// OpenTelemetry, service discovery, and resilience.
+ ///
+ /// The to configure.
+ /// The configured .
+ public static WebAssemblyHostBuilder AddBlazorClientServiceDefaults(this WebAssemblyHostBuilder builder)
+ {
+ builder.ConfigureBlazorClientOpenTelemetry();
+
+ builder.Services.AddServiceDiscovery();
+
+ builder.Services.ConfigureHttpClientDefaults(http =>
+ {
+ // Turn on resilience by default
+ http.AddStandardResilienceHandler();
+
+ // Turn on service discovery by default
+ http.AddServiceDiscovery();
+ });
+
+ return builder;
+ }
+
+ ///
+ /// Configures OpenTelemetry for Blazor WebAssembly clients with logging, metrics, and tracing.
+ ///
+ /// The to configure.
+ /// The configured .
+ public static WebAssemblyHostBuilder ConfigureBlazorClientOpenTelemetry(this WebAssemblyHostBuilder builder)
+ {
+ var serviceName = builder.Configuration["OTEL_SERVICE_NAME"] ?? DefaultServiceName;
+
+ builder.Logging.AddOpenTelemetry(logging =>
+ {
+ logging.IncludeFormattedMessage = true;
+ logging.IncludeScopes = true;
+ });
+
+ builder.Services.AddOpenTelemetry()
+ .ConfigureResource(resource => resource.AddService(serviceName))
+ .WithMetrics(metrics =>
+ {
+ // Uncomment the following lines to enable Blazor component metrics
+ // See: https://learn.microsoft.com/aspnet/core/blazor/performance#metrics-and-tracing
+ //metrics.AddMeter("Microsoft.AspNetCore.Components");
+ //metrics.AddMeter("Microsoft.AspNetCore.Components.Lifecycle");
+
+ metrics.AddHttpClientInstrumentation()
+ .AddRuntimeInstrumentation();
+ })
+ .WithTracing(tracing =>
+ {
+ // Uncomment the following line to enable Blazor component tracing
+ //tracing.AddSource("Microsoft.AspNetCore.Components");
+
+ tracing.AddSource(serviceName)
+ .AddHttpClientInstrumentation();
+ });
+
+ builder.AddBlazorClientOpenTelemetryExporters();
+
+ return builder;
+ }
+
+ private static WebAssemblyHostBuilder AddBlazorClientOpenTelemetryExporters(this WebAssemblyHostBuilder builder)
+ {
+ var useOtlpExporter = !string.IsNullOrWhiteSpace(builder.Configuration["OTEL_EXPORTER_OTLP_ENDPOINT"]);
+
+ if (useOtlpExporter)
+ {
+ builder.Services.AddOpenTelemetry().UseOtlpExporter();
+ }
+
+ return builder;
+ }
+}
diff --git a/src/ProjectTemplates/test/Templates.Tests/BlazorWasmServiceDefaultsTemplateTest.cs b/src/ProjectTemplates/test/Templates.Tests/BlazorWasmServiceDefaultsTemplateTest.cs
new file mode 100644
index 000000000000..81d281ce64a7
--- /dev/null
+++ b/src/ProjectTemplates/test/Templates.Tests/BlazorWasmServiceDefaultsTemplateTest.cs
@@ -0,0 +1,46 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using Microsoft.AspNetCore.InternalTesting;
+using Templates.Test.Helpers;
+using Xunit.Abstractions;
+
+namespace Templates.Test;
+
+public class BlazorWasmServiceDefaultsTemplateTest : LoggedTest
+{
+ public BlazorWasmServiceDefaultsTemplateTest(ProjectFactoryFixture projectFactory)
+ {
+ ProjectFactory = projectFactory;
+ }
+
+ public ProjectFactoryFixture ProjectFactory { get; }
+ private ITestOutputHelper _output;
+ public ITestOutputHelper Output
+ {
+ get
+ {
+ if (_output == null)
+ {
+ _output = new TestOutputLogger(Logger);
+ }
+ return _output;
+ }
+ }
+
+ [Fact]
+ public async Task BlazorWasmServiceDefaultsTemplateAsync()
+ {
+ var project = await ProjectFactory.CreateProject(Output);
+
+ await project.RunDotNetNewAsync("blazor-wasm-servicedefaults");
+
+ await project.RunDotNetPublishAsync();
+
+ // Run dotnet build after publish. The reason is that one uses Config = Debug and the other uses Config = Release
+ // The output from publish will go into bin/Release/netcoreappX.Y/publish and won't be affected by calling build
+ // later, while the opposite is not true.
+
+ await project.RunDotNetBuildAsync();
+ }
+}
diff --git a/src/ProjectTemplates/test/Templates.Tests/template-baselines.json b/src/ProjectTemplates/test/Templates.Tests/template-baselines.json
index 61b2ffddf049..a2fbd6063eaf 100644
--- a/src/ProjectTemplates/test/Templates.Tests/template-baselines.json
+++ b/src/ProjectTemplates/test/Templates.Tests/template-baselines.json
@@ -3720,5 +3720,14 @@
"wwwroot/css/app.css"
]
}
+ },
+ "blazor-wasm-servicedefaults": {
+ "Default": {
+ "Template": "blazor-wasm-servicedefaults",
+ "Arguments": "new blazor-wasm-servicedefaults",
+ "Files": [
+ "Extensions.cs"
+ ]
+ }
}
}