diff --git a/src/frontend/src/content/docs/community/contributor-guide.mdx b/src/frontend/src/content/docs/community/contributor-guide.mdx
index cbff846b1..42205fe3e 100644
--- a/src/frontend/src/content/docs/community/contributor-guide.mdx
+++ b/src/frontend/src/content/docs/community/contributor-guide.mdx
@@ -194,14 +194,12 @@ When contributing to `aspire.dev`, follow these writing guidelines to ensure con
 
 ### AppHost-specific C# and TypeScript content
 
-When you are documenting AppHost-specific content that changes between C# and TypeScript, add an in-page `PivotSelector` with the title `Select your Aspire programming language`, the key `aspire-lang`, and `C#` and `TypeScript` options. Pair it with `Pivot` blocks for the language-specific content.
+When you are documenting AppHost-specific content that changes between C# and TypeScript, use synced `Tabs` and `TabItem` blocks with `syncKey='aspire-lang'`. Each code snippet should have its own C# and TypeScript selector, and the shared sync key keeps the selected language consistent across the page.
 
 Use `Tabs` for other choices such as package managers, deployment targets, IDEs, or CLI variants.
 
 If a feature is only available in the C# AppHost today, show the C# example by itself and add an explanatory note. Do not add a language selector for a single-language example.
 
-If the page already has another `PivotSelector`, stop and review the layout before adding a second selector. Those pages need a manual pass so the page does not end up with competing selector UIs.
-
 For the **On this page** table of contents to pick up a heading reliably, define the heading outside `Pivot` and `Tabs`. Headings inside those components are often missed or can produce incomplete results in the generated table of contents.
 
 ## 📝 Write Markdown
@@ -703,66 +701,15 @@ Here's an example of using the `LearnMore` component:
 
 ### Aspire language selectors
 
-Use an in-page `PivotSelector` plus `Pivot` blocks when the surrounding AppHost content should switch between C# and TypeScript as a single unit.
-
-If a page would otherwise need multiple `PivotSelector` controls with `key="aspire-lang"`, do not repeat the selector. Keep the page-level `PivotSelector` for the main flow, and use synced `Tabs` and `TabItem` blocks for repeated language-specific examples instead.
+Use synced `Tabs` and `TabItem` blocks for AppHost content that switches between C# and TypeScript. Each AppHost code snippet should have its own selector, and every AppHost language selector on the page should share `syncKey='aspire-lang'` so a reader's language choice applies to the whole page.
 
-Keep shared section headings outside the pivots or tabs. For example, write `## Add a Redis resource` before the selector and the `Pivot` blocks, then place the language-specific prose and code inside the `csharp` and `typescript` pivots. This helps the **On this page** navigation stay accurate.
+Keep shared section headings outside the tabs. For example, write `## Add a Redis resource` before the `Tabs` block, then place the language-specific code inside the `csharp` and `typescript` tab items. This helps the **On this page** navigation stay accurate.
 
 ````mdx title="src/content/docs/example.mdx"
 ---
 title: Example MDX Page
 ---
 
-import PivotSelector from '@components/PivotSelector.astro';
-import Pivot from '@components/Pivot.astro';
-
-<PivotSelector
-  title="Select your programming language"
-  key="aspire-lang"
-  options={[
-    { id: 'csharp', title: 'C#' },
-    { id: 'typescript', title: 'TypeScript' },
-  ]}
-/>
-
-<Pivot id="csharp">
-
-  ```csharp title="AppHost.cs"
-  var builder = DistributedApplication.CreateBuilder(args);
-
-  var cache = builder.AddRedis("cache");
-
-  builder.AddProject<Projects.Api>("api")
-      .WithReference(cache);
-
-  builder.Build().Run();
-  ```
-
-</Pivot>
-<Pivot id="typescript">
-
-  ```typescript title="apphost.ts" twoslash
-  import { createBuilder } from './.modules/aspire.js';
-
-  const builder = await createBuilder();
-
-  const cache = await builder.addRedis("cache");
-
-  const api = await builder.addProject("api", "../Api/Api.csproj");
-  await api.withReference(cache);
-
-  await builder.build().run();
-  ```
-
-</Pivot>
-````
-
-Use this pattern when entire sections differ by AppHost language, not just a single code fence. For example, each `Pivot` can contain explanatory prose, steps, asides, and code blocks together.
-
-For repeated language-specific code examples later on the same page, use synced tabs instead of adding another `PivotSelector`:
-
-````mdx title="src/content/docs/example.mdx"
 import { Tabs, TabItem } from '@astrojs/starlight/components';
 
 <Tabs syncKey='aspire-lang'>
@@ -770,15 +717,29 @@ import { Tabs, TabItem } from '@astrojs/starlight/components';
 
 ```csharp title="AppHost.cs"
 var builder = DistributedApplication.CreateBuilder(args);
-builder.AddRedis("cache");
+
+var cache = builder.AddRedis("cache");
+
+builder.AddProject<Projects.Api>("api")
+    .WithReference(cache);
+
+builder.Build().Run();
 ```
 
 </TabItem>
 <TabItem id='typescript' label='TypeScript'>
 
-```typescript title="apphost.ts"
+```typescript title="apphost.ts" twoslash
+import { createBuilder } from './.modules/aspire.js';
+
 const builder = await createBuilder();
-await builder.addRedis("cache");
+
+const cache = await builder.addRedis("cache");
+
+const api = await builder.addProject("api", "../Api/Api.csproj");
+await api.withReference(cache);
+
+await builder.build().run();
 ```
 
 </TabItem>
@@ -787,7 +748,7 @@ await builder.addRedis("cache");
 
 If the difference is not about AppHost language, keep using regular `Tabs`.
 
-The same TOC rule applies to `Tabs` and `Pivot`: if a heading should appear in **On this page**, keep that heading outside the component and only put the variant-specific body content inside.
+The same TOC rule applies to `Tabs`: if a heading should appear in **On this page**, keep that heading outside the component and only put the variant-specific body content inside.
 
 Renders as:
 
@@ -801,4 +762,4 @@ Here's an example of using the `LearnMore` component:
 
 - **Issues** - Report bugs or request features via [GitHub Issues](https://github.com/microsoft/aspire.dev/issues)
 - **Discussions** - Join conversations in [GitHub Discussions](https://github.com/microsoft/aspire.dev/discussions)
-- **Discord** - Connect with the community on the [Aspire Discord](https://discord.com/invite/raNPcaaSj8)
\ No newline at end of file
+- **Discord** - Connect with the community on the [Aspire Discord](https://discord.com/invite/raNPcaaSj8)
diff --git a/src/frontend/src/content/docs/deployment/javascript-apps.mdx b/src/frontend/src/content/docs/deployment/javascript-apps.mdx
index f5c989592..590a896b2 100644
--- a/src/frontend/src/content/docs/deployment/javascript-apps.mdx
+++ b/src/frontend/src/content/docs/deployment/javascript-apps.mdx
@@ -183,9 +183,8 @@ await builder
   .withExternalHttpEndpoints()
   .publishWithStaticFiles(frontend)
   .withConfiguration(async (yarp) => {
-    (
-      await yarp.addRouteFromEndpoint('/api/{**catch-all}', apiEndpoint)
-    ).withTransformPathRemovePrefix('/api');
+    (await yarp.addRoute('/api/{**catch-all}', apiEndpoint))
+      .withTransformPathRemovePrefix('/api');
   });
 
 await builder.build().run();
diff --git a/src/frontend/src/content/docs/integrations/reverse-proxies/yarp.mdx b/src/frontend/src/content/docs/integrations/reverse-proxies/yarp.mdx
index 6e10eb8ce..017390087 100644
--- a/src/frontend/src/content/docs/integrations/reverse-proxies/yarp.mdx
+++ b/src/frontend/src/content/docs/integrations/reverse-proxies/yarp.mdx
@@ -4,7 +4,7 @@ description: Learn how to use the YARP (Yet Another Reverse Proxy) integration f
 ---
 
 import InstallPackage from '@components/InstallPackage.astro';
-import { Aside } from '@astrojs/starlight/components';
+import { Aside, Tabs, TabItem } from '@astrojs/starlight/components';
 import { Image } from 'astro:assets';
 import yarpIcon from '@assets/icons/yarp-icon.svg';
 
@@ -24,25 +24,59 @@ import yarpIcon from '@assets/icons/yarp-icon.svg';
 The YARP hosting integration models a YARP resource as the `YarpResource` type. To access this type and APIs, add the [📦 Aspire.Hosting.Yarp](https://www.nuget.org/packages/Aspire.Hosting.Yarp) NuGet package in your AppHost project:
 
 <InstallPackage packageName="Aspire.Hosting.Yarp" />
+
 ### Add YARP resource
 
-In your AppHost project, call `AddYarp` on the builder instance to add a YARP resource:
+In your AppHost, add a YARP resource and configure routes programmatically:
+
+<Tabs syncKey='aspire-lang'>
+<TabItem id='csharp' label='C#'>
 
-```csharp title="C# — AppHost.cs"
+```csharp title="AppHost.cs"
 var builder = DistributedApplication.CreateBuilder(args);
 
 var catalogService = builder.AddProject<Projects.CatalogService>("catalogservice");
 var basketService = builder.AddProject<Projects.BasketService>("basketservice");
 
 var gateway = builder.AddYarp("gateway")
-                     .WithConfiguration(yarp =>
-                     {
-                         // Configure routes programmatically
-                         yarp.AddRoute(catalogService);
-                         yarp.AddRoute("/api/{**catch-all}", basketService);
-                     });
+    .WithConfiguration(yarp =>
+    {
+        yarp.AddRoute(catalogService);
+        yarp.AddRoute("/api/{**catch-all}", basketService);
+    });
+
+builder.Build().Run();
+```
+
+</TabItem>
+<TabItem id='typescript' label='TypeScript'>
+
+```typescript title="apphost.ts"
+import { createBuilder } from './.modules/aspire.js';
+
+const builder = await createBuilder();
+
+const catalogService = await builder.addProject(
+  'catalogservice',
+  '../CatalogService/CatalogService.csproj'
+);
+const basketService = await builder.addProject(
+  'basketservice',
+  '../BasketService/BasketService.csproj'
+);
+
+const gateway = await builder.addYarp('gateway');
+await gateway.withConfiguration(async (yarp) => {
+  await yarp.addCatchAllRoute(catalogService);
+  await yarp.addRoute('/api/{**catch-all}', basketService);
+});
+
+await builder.build().run();
 ```
 
+</TabItem>
+</Tabs>
+
 When Aspire adds a YARP resource to the AppHost, it creates a new containerized YARP instance using the [mcr.microsoft.com/dotnet/nightly/yarp](https://mcr.microsoft.com/product/dotnet/nightly/yarp/about) container image.
 
 <Aside type="caution">
@@ -56,42 +90,116 @@ When Aspire adds a YARP resource to the AppHost, it creates a new containerized
 
 The YARP integration provides a fluent API for configuring routes, clusters, and transforms programmatically:
 
-```csharp title="C# — AppHost.cs"
+<Tabs syncKey='aspire-lang'>
+<TabItem id='csharp' label='C#'>
+
+```csharp title="AppHost.cs"
 var builder = DistributedApplication.CreateBuilder(args);
 
 var catalogService = builder.AddProject<Projects.CatalogService>("catalogservice");
 var basketService = builder.AddProject<Projects.BasketService>("basketservice");
 
 var gateway = builder.AddYarp("gateway")
-                     .WithConfiguration(yarp =>
-                     {
-                         // Add catch-all route for frontend service
-                         yarp.AddRoute(catalogService);
-
-                         // Add specific path route with transforms
-                         yarp.AddRoute("/api/{**catch-all}", basketService)
-                             .WithTransformPathRemovePrefix("/api");
+    .WithConfiguration(yarp =>
+    {
+        // Add catch-all route for frontend service
+        yarp.AddRoute(catalogService);
+
+        // Add specific path route with transforms
+        yarp.AddRoute("/api/{**catch-all}", basketService)
+            .WithTransformPathRemovePrefix("/api");
+
+        // Configure route matching
+        yarp.AddRoute("/catalog/api/{**catch-all}", catalogService)
+            .WithMatchMethods("GET", "POST")
+            .WithTransformPathRemovePrefix("/catalog");
+    });
+
+builder.Build().Run();
+```
 
-                         // Configure route matching
-                         yarp.AddRoute("/catalog/api/{**catch-all}", catalogService)
-                             .WithMatchMethods("GET", "POST")
-                             .WithTransformPathRemovePrefix("/catalog");
-                     });
+</TabItem>
+<TabItem id='typescript' label='TypeScript'>
+
+```typescript title="apphost.ts"
+import { createBuilder } from './.modules/aspire.js';
+
+const builder = await createBuilder();
+
+const catalogService = await builder.addProject(
+  'catalogservice',
+  '../CatalogService/CatalogService.csproj'
+);
+const basketService = await builder.addProject(
+  'basketservice',
+  '../BasketService/BasketService.csproj'
+);
+
+const gateway = await builder.addYarp('gateway');
+await gateway.withConfiguration(async (yarp) => {
+  // Add catch-all route for frontend service
+  await yarp.addCatchAllRoute(catalogService);
+
+  // Add specific path route with transforms
+  (
+    await yarp.addRoute('/api/{**catch-all}', basketService)
+  ).withTransformPathRemovePrefix('/api');
+
+  // Configure route matching
+  (await yarp.addRoute('/catalog/api/{**catch-all}', catalogService))
+    .withMatch({
+      path: '/catalog/api/{**catch-all}',
+      methods: ['GET', 'POST'],
+    })
+    .withTransformPathRemovePrefix('/catalog');
+});
+
+await builder.build().run();
 ```
 
-#### Route configuration
+</TabItem>
+</Tabs>
 
-Routes define how incoming requests are matched and forwarded to backend services:
+#### Route configuration
 
-- `AddRoute(resource)` - Creates a catch-all route for the specified resource
-- `AddRoute(path, resource)` - Creates a route with a specific path pattern
-- `AddRoute(path, externalService)` - Creates a route targeting an external service
+Routes define how incoming requests are matched and forwarded to backend services.
+
+| Scenario                       | C#                                | TypeScript                        |
+| ------------------------------ | --------------------------------- | --------------------------------- |
+| Catch-all route for a resource | `AddRoute(resource)`              | `addCatchAllRoute(resource)`      |
+| Route for a resource           | `AddRoute(path, resource)`        | `addRoute(path, resource)`        |
+| Route for an external service  | `AddRoute(path, externalService)` | `addRoute(path, externalService)` |
+| Route for an endpoint          | `AddRoute(path, cluster)`         | `addRoute(path, cluster)`        |
+| Route for a URL destination    | `AddRoute(path, destination)`     | `addRoute(path, destination)`     |
+
+TypeScript AppHosts use unified route helpers. Pass any supported target to `addRoute(path, target)` or `addCatchAllRoute(target)`: a YARP cluster, endpoint, service-discovery resource, external service, or URL string.
+
+```typescript title="apphost.ts"
+await gateway.withConfiguration(async (yarp) => {
+  const httpEndpoint = await catalogService.getEndpoint('http');
+  const externalApi = await builder.addExternalService(
+    'external-api',
+    'https://api.example.com'
+  );
+  const endpointCluster = await yarp.addClusterFromEndpoint(httpEndpoint);
+
+  await yarp.addRoute('/from-cluster/{**catch-all}', endpointCluster);
+  await yarp.addRoute('/from-endpoint/{**catch-all}', httpEndpoint);
+  await yarp.addRoute('/from-resource/{**catch-all}', catalogService);
+  await yarp.addRoute('/from-external/{**catch-all}', externalApi);
+  await yarp.addRoute('/from-url/{**catch-all}', 'https://api.example.net');
+  await yarp.addCatchAllRoute(catalogService);
+});
+```
 
 #### Transforms
 
 Transforms modify requests and responses as they pass through the proxy:
 
-```csharp
+<Tabs syncKey='aspire-lang'>
+<TabItem id='csharp' label='C#'>
+
+```csharp title="AppHost.cs"
 yarp.AddRoute("/api/{**catch-all}", basketService)
     .WithTransformPathRemovePrefix("/api")
     .WithTransformPathPrefix("/v1")
@@ -99,121 +207,283 @@ yarp.AddRoute("/api/{**catch-all}", basketService)
     .WithTransformResponseHeader("X-Powered-By", "YARP");
 ```
 
+</TabItem>
+<TabItem id='typescript' label='TypeScript'>
+
+```typescript title="apphost.ts"
+(await yarp.addRoute('/api/{**catch-all}', basketService))
+  .withTransformPathRemovePrefix('/api')
+  .withTransformPathPrefix('/v1')
+  .withTransformRequestHeader('X-Forwarded-Host', 'gateway.example.com')
+  .withTransformResponseHeader('X-Powered-By', 'YARP');
+```
+
+</TabItem>
+</Tabs>
+
 Common transform methods include:
 
-- **Path transforms**: `WithTransformPathRemovePrefix`, `WithTransformPathPrefix`, `WithTransformPathSet`
-- **Header transforms**: `WithTransformRequestHeader`, `WithTransformResponseHeader`
-- **Query transforms**: `WithTransformQueryParameter`, `WithTransformQueryRemoveParameter`
-- **Custom transforms**: `WithTransform` for custom transformation logic
+- **Path transforms**: `WithTransformPathRemovePrefix`, `WithTransformPathPrefix`, `WithTransformPathSet`; TypeScript uses `withTransformPathRemovePrefix`, `withTransformPathPrefix`, and `withTransformPathSet`.
+- **Header transforms**: `WithTransformRequestHeader`, `WithTransformResponseHeader`; TypeScript uses `withTransformRequestHeader` and `withTransformResponseHeader`.
+- **Query transforms**: `WithTransformQueryParameter`, `WithTransformQueryRemoveParameter`; TypeScript uses `withTransformQueryValue`, `withTransformQueryRouteValue`, and `withTransformQueryRemoveKey`.
+- **Custom transforms**: `WithTransform` or `withTransform` for custom transformation logic.
 
 ### Customize host port
 
-To configure the host port that the YARP resource is exposed on, use the `WithHostPort` method:
+To configure the host port that the YARP resource is exposed on, use the host port API:
+
+<Tabs syncKey='aspire-lang'>
+<TabItem id='csharp' label='C#'>
 
-```csharp title="C# — AppHost.cs"
+```csharp title="AppHost.cs"
 var builder = DistributedApplication.CreateBuilder(args);
 
 var gateway = builder.AddYarp("gateway")
-                     .WithHostPort(8080)
-                     .WithConfiguration(yarp =>
-                     {
-                         // Configure routes...
-                     });
+    .WithHostPort(8080)
+    .WithConfiguration(yarp =>
+    {
+        // Configure routes...
+    });
+
+builder.Build().Run();
 ```
 
+</TabItem>
+<TabItem id='typescript' label='TypeScript'>
+
+```typescript title="apphost.ts"
+import { createBuilder } from './.modules/aspire.js';
+
+const builder = await createBuilder();
+
+const gateway = await builder.addYarp('gateway').withHostPort({ port: 8080 });
+
+await gateway.withConfiguration(async (yarp) => {
+  // Configure routes...
+});
+
+await builder.build().run();
+```
+
+</TabItem>
+</Tabs>
+
 ### Service discovery integration
 
-The YARP integration automatically works with .NET service discovery when targeting resources:
+The YARP integration automatically works with service discovery when targeting resources:
 
-```csharp title="C# — AppHost.cs"
+<Tabs syncKey='aspire-lang'>
+<TabItem id='csharp' label='C#'>
+
+```csharp title="AppHost.cs"
 var builder = DistributedApplication.CreateBuilder(args);
 
 var catalogService = builder.AddProject<Projects.CatalogService>("catalogservice");
 
 var gateway = builder.AddYarp("gateway")
-                     .WithConfiguration(yarp =>
-                     {
-                         // Service discovery automatically resolves catalogservice endpoints
-                         yarp.AddRoute("/catalog/{**catch-all}", catalogService);
-                     });
+    .WithConfiguration(yarp =>
+    {
+        // Service discovery automatically resolves catalogservice endpoints
+        yarp.AddRoute("/catalog/{**catch-all}", catalogService);
+    });
+
+builder.Build().Run();
 ```
 
-For external services, use `AddExternalService`:
+</TabItem>
+<TabItem id='typescript' label='TypeScript'>
+
+```typescript title="apphost.ts"
+import { createBuilder } from './.modules/aspire.js';
+
+const builder = await createBuilder();
+
+const catalogService = await builder.addProject(
+  'catalogservice',
+  '../CatalogService/CatalogService.csproj'
+);
+
+const gateway = await builder.addYarp('gateway');
+await gateway.withConfiguration(async (yarp) => {
+  // Service discovery automatically resolves catalogservice endpoints
+  await yarp.addRoute('/catalog/{**catch-all}', catalogService);
+});
+
+await builder.build().run();
+```
+
+</TabItem>
+</Tabs>
+
+For external services, use `AddExternalService` or `addExternalService`:
+
+<Tabs syncKey='aspire-lang'>
+<TabItem id='csharp' label='C#'>
+
+```csharp title="AppHost.cs"
+var builder = DistributedApplication.CreateBuilder(args);
 
-```csharp
 var externalApi = builder.AddExternalService("external-api")
-                         .WithHttpsEndpoint("https://api.example.com");
+    .WithHttpsEndpoint("https://api.example.com");
 
 var gateway = builder.AddYarp("gateway")
-                     .WithConfiguration(yarp =>
-                     {
-                         yarp.AddRoute("/external/{**catch-all}", externalApi);
-                     });
+    .WithConfiguration(yarp =>
+    {
+        yarp.AddRoute("/external/{**catch-all}", externalApi);
+    });
+
+builder.Build().Run();
+```
+
+</TabItem>
+<TabItem id='typescript' label='TypeScript'>
+
+```typescript title="apphost.ts"
+import { createBuilder } from './.modules/aspire.js';
+
+const builder = await createBuilder();
+
+const externalApi = await builder.addExternalService(
+  'external-api',
+  'https://api.example.com'
+);
+
+const gateway = await builder.addYarp('gateway');
+await gateway.withConfiguration(async (yarp) => {
+  await yarp.addRoute('/external/{**catch-all}', externalApi);
+});
+
+await builder.build().run();
 ```
 
+</TabItem>
+</Tabs>
+
 ### Static file serving
 
-YARP can serve static files alongside proxied routes. Use the `WithStaticFiles` method to copy files from a local directory:
+YARP can serve static files alongside proxied routes. Use the static files API to enable static file serving:
 
-```csharp title="C# — AppHost.cs"
+<Tabs syncKey='aspire-lang'>
+<TabItem id='csharp' label='C#'>
+
+```csharp title="AppHost.cs"
 var builder = DistributedApplication.CreateBuilder(args);
 
 var staticServer = builder.AddYarp("static")
-                          .WithStaticFiles("../static");
+    .WithStaticFiles("../static");
+
+builder.Build().Run();
 ```
 
+</TabItem>
+<TabItem id='typescript' label='TypeScript'>
+
+```typescript title="apphost.ts"
+import { createBuilder } from './.modules/aspire.js';
+
+const builder = await createBuilder();
+
+const staticServer = await builder.addYarp('static').withStaticFiles();
+
+await builder.build().run();
+```
+
+</TabItem>
+</Tabs>
+
 For building frontend applications, you can use a Docker multi-stage build:
 
-```csharp title="C# — AppHost.cs"
+<Tabs syncKey='aspire-lang'>
+<TabItem id='csharp' label='C#'>
+
+```csharp title="AppHost.cs"
 var builder = DistributedApplication.CreateBuilder(args);
 
 var frontend = builder.AddYarp("frontend")
-                      .WithStaticFiles()
-                      .WithDockerfile("../npmapp");
+    .WithStaticFiles()
+    .WithDockerfile("../npmapp");
+
+builder.Build().Run();
 ```
 
-When using `WithStaticFiles` together with `WithDockerfile`, the YARP container expects static files to be placed at the `/wwwroot` directory inside the container. Your Dockerfile must use the YARP base image (`mcr.microsoft.com/dotnet/nightly/yarp`) as its final stage so the YARP server can start and serve the files. The following example shows a multi-stage Dockerfile that builds a Node.js frontend app and copies the output to `/app/wwwroot`:
+</TabItem>
+<TabItem id='typescript' label='TypeScript'>
+
+```typescript title="apphost.ts"
+import { createBuilder } from './.modules/aspire.js';
 
-```dockerfile title="Dockerfile"
-FROM node:22-slim AS build
-WORKDIR /app
-COPY package*.json ./
-RUN npm ci
-COPY . .
-RUN npm run build
+const builder = await createBuilder();
 
-FROM mcr.microsoft.com/dotnet/nightly/yarp
-COPY --from=build /app/dist /wwwroot
+const frontend = await builder
+  .addYarp('frontend')
+  .withDockerfile('../npmapp')
+  .withStaticFiles();
+
+await builder.build().run();
 ```
 
-<Aside type="caution">
-If the built assets aren't copied to `/app/wwwroot`, the container starts successfully but returns 404 for all static file requests. Look for the log message `The WebRootPath was not found: /wwwroot. Static files may be unavailable.` as an indicator that the path is misconfigured.
-</Aside>
+</TabItem>
+</Tabs>
 
 #### Combining static files with routing
 
 You can combine static file serving with dynamic routing:
 
-```csharp title="C# — AppHost.cs"
+<Tabs syncKey='aspire-lang'>
+<TabItem id='csharp' label='C#'>
+
+```csharp title="AppHost.cs"
 var builder = DistributedApplication.CreateBuilder(args);
 
 var apiService = builder.AddProject<Projects.ApiService>("api");
 
 var gateway = builder.AddYarp("gateway")
-                     .WithStaticFiles("../webapp/dist")
-                     .WithConfiguration(yarp =>
-                     {
-                         // API routes take precedence over static files
-                         yarp.AddRoute("/api/{**catch-all}", apiService);
-                         // Static files are served for all other routes
-                     });
+    .WithStaticFiles("../webapp/dist")
+    .WithConfiguration(yarp =>
+    {
+        // API routes take precedence over static files
+        yarp.AddRoute("/api/{**catch-all}", apiService);
+        // Static files are served for all other routes
+    });
+
+builder.Build().Run();
 ```
 
+</TabItem>
+<TabItem id='typescript' label='TypeScript'>
+
+```typescript title="apphost.ts"
+import { createBuilder } from './.modules/aspire.js';
+
+const builder = await createBuilder();
+
+const apiService = await builder.addProject(
+  'api',
+  '../ApiService/ApiService.csproj'
+);
+
+const gateway = await builder.addYarp('gateway').withStaticFiles();
+
+await gateway.withConfiguration(async (yarp) => {
+  // API routes take precedence over static files
+  await yarp.addRoute('/api/{**catch-all}', apiService);
+  // Static files are served for all other routes
+});
+
+await builder.build().run();
+```
+
+</TabItem>
+</Tabs>
+
 ## HTTPS endpoints
 
-When both the YARP gateway and backend services use HTTPS, configure HTTPS endpoints using `WithHttpsEndpoint` and the developer certificate. YARP can proxy HTTPS-to-HTTPS when the backend service exposes an HTTPS endpoint:
+When both the YARP gateway and backend services use HTTPS, configure HTTPS endpoints using `WithHttpsEndpoint` or `withHttpsEndpoint` and the developer certificate. YARP can proxy HTTPS-to-HTTPS when the backend service exposes an HTTPS endpoint:
 
-```csharp title="C# — AppHost.cs"
+<Tabs syncKey='aspire-lang'>
+<TabItem id='csharp' label='C#'>
+
+```csharp title="AppHost.cs"
 var builder = DistributedApplication.CreateBuilder(args);
 
 // Backend service with HTTPS
@@ -222,18 +492,49 @@ var razorPages = builder.AddProject<Projects.RazorPagesApp>("razorpages")
 
 // YARP gateway proxying to the HTTPS backend
 var gateway = builder.AddYarp("gateway")
-                     .WithHttpsEndpoint()
-                     .WithHttpsDeveloperCertificate()
-                     .WithConfiguration(yarp =>
-                     {
-                         yarp.AddRoute("/{**catch-all}", razorPages);
-                     });
+    .WithHttpsEndpoint()
+    .WithHttpsDeveloperCertificate()
+    .WithConfiguration(yarp =>
+    {
+        yarp.AddRoute("/{**catch-all}", razorPages);
+    });
+
+builder.Build().Run();
+```
+
+</TabItem>
+<TabItem id='typescript' label='TypeScript'>
 
-// After adding all resources, run the app...
+```typescript title="apphost.ts"
+import { createBuilder } from './.modules/aspire.js';
+
+const builder = await createBuilder();
+
+// Backend service with HTTPS
+const razorPages = await builder
+  .addProject('razorpages', '../RazorPagesApp/RazorPagesApp.csproj')
+  .withHttpsEndpoint();
+
+// YARP gateway proxying to the HTTPS backend
+const gateway = await builder
+  .addYarp('gateway')
+  .withHttpsEndpoint()
+  .withHttpsDeveloperCertificate();
+
+await gateway.withConfiguration(async (yarp) => {
+  await yarp.addRoute('/{**catch-all}', razorPages);
+});
+
+await builder.build().run();
 ```
 
+</TabItem>
+</Tabs>
+
 <Aside type="note">
-When using HTTPS with YARP, ensure that the developer certificate is trusted on your machine. Run `dotnet dev-certs https --trust` if you see certificate validation errors.
+  When using HTTPS with YARP, ensure that the developer certificate is trusted
+  on your machine. Run `dotnet dev-certs https --trust` if you see certificate
+  validation errors.
 </Aside>
 
 ## See also
