Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
2b4da06
feat: Refactor AppHost language pivot component and update documentation
IEvangelist Apr 1, 2026
490361a
fix: Correct markdown syntax for code blocks in contributor guide
IEvangelist Apr 1, 2026
9847eda
feat(tour): implement site tour functionality with step definitions a…
IEvangelist Apr 2, 2026
e30905d
Refactor code structure for improved readability and maintainability
IEvangelist Apr 2, 2026
b790caf
fix: Update references from dotnet to microsoft for aspire-samples re…
IEvangelist Apr 2, 2026
84857aa
Add analytics tracking scripts for event capturing
IEvangelist Apr 2, 2026
b438620
style: Enhance sidebar and integration grid styles for improved layou…
IEvangelist Apr 2, 2026
0a53636
fix: Update route data handling and normalize path function for bread…
IEvangelist Apr 2, 2026
52246e6
Add site tour translations for multiple languages
IEvangelist Apr 2, 2026
4b1151c
chore: rewrite add existing app for scenarios, avoiding bias.
IEvangelist Apr 2, 2026
1a953f2
chore: add `tmp/` to .gitignore and delete patches.
IEvangelist Apr 6, 2026
a199556
feat: enhance sidebar functionality and improve breadcrumb utility
IEvangelist Apr 6, 2026
32cb3d1
Add end-to-end and unit tests for site tour functionality
IEvangelist Apr 6, 2026
436774e
fix: update footer preferences heading to use paragraph tag for consi…
IEvangelist Apr 6, 2026
e6dd9a0
fix: rename variables for site tour props to avoid conflicts
IEvangelist Apr 6, 2026
5f9a07a
fix: update documentation and styles for improved clarity and consist…
IEvangelist Apr 6, 2026
55fb557
fix: improve inline code handling in markdown content for better read…
IEvangelist Apr 6, 2026
5511bba
fix: remove unnecessary 'prev' field from documentation for clarity
IEvangelist Apr 6, 2026
ccbbd69
fix: refactor Playwright configuration and enhance E2E test support w…
IEvangelist Apr 6, 2026
c4f26ec
fix: refactor prerequisites documentation to streamline language sele…
IEvangelist Apr 6, 2026
6d4194c
fix: refactor TypeScript API routes and enhance slug generation for b…
IEvangelist Apr 6, 2026
a1633d0
fix: update links in documentation for consistency and clarity
IEvangelist Apr 6, 2026
7bab4cf
fix: remove inline-block display from code elements for better wrappi…
IEvangelist Apr 6, 2026
0bd6399
fix: enhance header actions for better accessibility and responsivene…
IEvangelist Apr 6, 2026
34fdd27
fix: refactor site tour feature to enable/disable based on environmen…
IEvangelist Apr 7, 2026
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
107 changes: 66 additions & 41 deletions .github/skills/doc-writer/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ Optional frontmatter fields:
Import Starlight components at the top of your MDX file:

```tsx
import { Aside, CardGrid, LinkCard, Steps, Tabs, TabItem, Icon, FileTree } from '@astrojs/starlight/components';
import { CardGrid, LinkCard, Steps, Tabs, TabItem, Icon, FileTree } from '@astrojs/starlight/components';
```

Additional commonly used imports:
Expand Down Expand Up @@ -104,24 +104,24 @@ When you introduce or change a custom component that is used by docs pages:

#### Aside (Callouts)

Use for tips, notes, cautions, and warnings:
Prefer fenced `:::` callouts for tips, notes, cautions, and warnings. Use the `Aside` component only when a JSX-only composition pattern is required.

```mdx
<Aside type="tip" title="Pro Tip">
:::tip[Pro Tip]
This is a helpful tip for users.
</Aside>
:::

<Aside type="note">
:::note
Important information users should be aware of.
</Aside>
:::

<Aside type="caution">
:::caution
Proceed with care - this may have unexpected consequences.
</Aside>
:::

<Aside type="danger">
:::danger
Critical warning - this could cause data loss or security issues.
</Aside>
:::
```

#### Steps
Expand Down Expand Up @@ -165,6 +165,8 @@ Press F5 to start debugging.
</Tabs>
```

If a heading should appear in the **On this page** table of contents, keep that heading outside the `Tabs` component. Headings placed inside `TabItem` content may be skipped by the generated TOC.

#### Pivot/PivotSelector

Use for programming language selection that persists across page:
Expand All @@ -188,6 +190,22 @@ Python specific content here.
</Pivot>
```

If a heading needs to appear in the **On this page** table of contents, keep the heading outside the `Pivot` content and put only the variant-specific body content inside each `Pivot`.

For Aspire AppHost docs, use a single page-level `PivotSelector` with `key="aspire-lang"` when the surrounding section flow should switch as one unit. If a page would otherwise need multiple `aspire-lang` selectors, keep the page-level selector for the main flow and use synced `Tabs`/`TabItem` with `syncKey='aspire-lang'` for repeated language-specific examples later on the page.

```mdx
<Tabs syncKey='aspire-lang'>
<TabItem id='csharp' label='C#'>
C# example content here.
</TabItem>

<TabItem id='typescript' label='TypeScript'>
TypeScript example content here.
</TabItem>
</Tabs>
```

#### CardGrid and LinkCard

Use for navigation and feature highlights:
Expand Down Expand Up @@ -246,10 +264,10 @@ For more information, see [Service Defaults](/fundamentals/service-defaults/).
</LearnMore>
```

The component renders an open-book icon alongside the provided content. Place it after a section or code example to point readers to deeper documentation. It works well inside `<Aside>` blocks or after `<Steps>`:
The component renders an open-book icon alongside the provided content. Place it after a section or code example to point readers to deeper documentation. It works well inside fenced `:::` callouts or after `<Steps>`:

````mdx
<Aside type="tip" title="Feature flag">
:::tip[Feature flag]
Enable polyglot support by running:

```bash
Expand All @@ -259,7 +277,7 @@ aspire config set features:polyglotSupportEnabled true --global
<LearnMore>
For more information, see [aspire config command reference](/reference/cli/commands/aspire-config-set/)
</LearnMore>
</Aside>
:::
````

#### Aspire Custom Components
Expand Down Expand Up @@ -333,20 +351,20 @@ Aspire supports both **C# AppHosts** (`AppHost.cs`) and **TypeScript AppHosts**

### Core Principles

1. **Always show both languages**: Every AppHost code example must include both C# and TypeScript variants unless the feature is genuinely language-specific.
1. **Always show both languages**: Every AppHost-focused example or walkthrough must include both C# and TypeScript variants unless the feature is genuinely language-specific.
2. **Use neutral framing**: Write prose that applies to both languages. Say "In your AppHost" not "In your C# project". Say "Add a Redis resource" not "Call `builder.AddRedis()`".
3. **Neither language is the default**: Don't present C# first as the "real" example and TypeScript as an afterthought. Both tabs are equal peers.
4. **Verify TypeScript APIs exist**: Before writing a TypeScript example, confirm the API exists in the TypeScript AppHost SDK. Do not invent TypeScript samples — if you are unsure whether an API is available, flag it for review.

### Tab Pattern for AppHost Code
### AppHostLangPivot Pattern for AppHost Content

Use `<Tabs syncKey="apphost-lang">` so the reader's language choice persists across the page and across pages:
Use `AppHostLangPivot` for AppHost-specific content that changes between C# and TypeScript. The component is controlled by the site-wide AppHost selector in the sidebar, so it should be the default choice for AppHost walkthroughs, code samples, and prose that should switch together.

````mdx
import { Tabs, TabItem } from '@astrojs/starlight/components';
import AppHostLangPivot from '@components/AppHostLangPivot.astro';

<Tabs syncKey="apphost-lang">
<TabItem label="C#">
<AppHostLangPivot>
<div slot="csharp">

```csharp title="AppHost.cs"
var builder = DistributedApplication.CreateBuilder(args);
Expand All @@ -359,8 +377,8 @@ builder.AddProject<Projects.Api>("api")
builder.Build().Run();
```

</TabItem>
<TabItem label="TypeScript">
</div>
<div slot="typescript">

```typescript title="apphost.ts"
import { createBuilder } from './.modules/aspire.js';
Expand All @@ -375,17 +393,23 @@ await api.withReference(cache);
await builder.build().run();
```

</TabItem>
</Tabs>
</div>
</AppHostLangPivot>
````

Use `AppHostLangPivot` for more than code blocks when needed. Entire paragraphs, lists, asides, or multi-step sections can live inside the `csharp` and `typescript` slots when the workflows differ. The pivot itself is the shared wrapper; the slot names are the language discriminator.

Use `Tabs` for other concerns such as CLI vs IDE, deployment targets, or platform choices. Do not use `Tabs syncKey="apphost-lang"` for new AppHost content.

If a section heading should appear in the **On this page** table of contents, keep that heading outside `AppHostLangPivot`. Headings inside the `csharp` and `typescript` slots can be missed by the TOC generator, so the recommended pattern is a shared heading followed by an `AppHostLangPivot` containing only the language-specific body content.

### Conventions

| Aspect | C# | TypeScript |
|---|---|---|
| File title | `title="AppHost.cs"` | `title="apphost.ts"` |
| Tab label | `C#` | `TypeScript` |
| Sync key | `apphost-lang` | `apphost-lang` |
| Pivot wrapper | Shared `AppHostLangPivot` container | Shared `AppHostLangPivot` container |
| Language slot | `slot="csharp"` | `slot="typescript"` |
| Builder creation | `DistributedApplication.CreateBuilder(args)` | `import { createBuilder } from './.modules/aspire.js';` then newline for space followed by `await createBuilder();` |
| Method casing | PascalCase (`AddRedis`) | camelCase (`addRedis`) |
| Async pattern | Synchronous fluent calls | `await` each builder call |
Expand All @@ -400,19 +424,19 @@ When writing narrative text around AppHost examples:
- ❌ "Call `builder.AddRedis()` in your _Program.cs_" (C#-specific)
- ❌ "Add the following C# code to your AppHost" (when both languages should be shown)

When a concept differs between languages (e.g., configuration files, async patterns), explain both within the tabs or in language-neutral prose above the tabs.
When a concept differs between languages (e.g., configuration files, async patterns), explain both within the AppHostLangPivot slots or in language-neutral prose above the pivot.

### When TypeScript Is Not Yet Supported

If a hosting integration does not yet have TypeScript AppHost support, show only the C# example **without tabs** and add a note:
If a hosting integration does not yet have TypeScript AppHost support, show only the C# example without `AppHostLangPivot` and add a note:

```mdx
<Aside type="note">
TypeScript AppHost support for this integration is not yet available.
</Aside>
```

Do **not** wrap a single language in a `<Tabs>` component — that creates a misleading UI suggesting another option exists.
Do **not** wrap a single language in `AppHostLangPivot` or a single-language `<Tabs>` component — that creates a misleading UI suggesting another option exists.

## Integration Documentation

Expand Down Expand Up @@ -443,7 +467,8 @@ title: [Technology] integration
description: Learn how to use the [Technology] integration with Aspire.
---

import { Aside, Tabs, TabItem } from '@astrojs/starlight/components';
import { Aside } from '@astrojs/starlight/components';
import AppHostLangPivot from '@components/AppHostLangPivot.astro';
import InstallPackage from '@components/InstallPackage.astro';
import Image from 'astro:assets';

Expand All @@ -459,8 +484,8 @@ Brief description of the technology and what the integration enables.

### Add [Technology] resource

<Tabs syncKey="apphost-lang">
<TabItem label="C#">
<AppHostLangPivot>
<div slot="csharp">

```csharp title="AppHost.cs"
var builder = DistributedApplication.CreateBuilder(args);
Expand All @@ -471,8 +496,8 @@ var tech = builder.AddTechnology("tech");
builder.Build().Run();
```

</TabItem>
<TabItem label="TypeScript">
</div>
<div slot="typescript">

```typescript title="apphost.ts"
import { createBuilder } from './.modules/aspire.js';
Expand All @@ -484,8 +509,8 @@ const tech = await builder.addTechnology("tech");
await builder.build().run();
```

</TabItem>
</Tabs>
</div>
</AppHostLangPivot>

### Configuration options

Expand All @@ -508,8 +533,8 @@ Include both hosting and client sections:

### Add [Technology] resource

<Tabs syncKey="apphost-lang">
<TabItem label="C#">
<AppHostLangPivot>
<div slot="csharp">

```csharp title="AppHost.cs"
var builder = DistributedApplication.CreateBuilder(args);
Expand All @@ -522,8 +547,8 @@ builder.AddProject<Projects.Api>("api")
builder.Build().Run();
```

</TabItem>
<TabItem label="TypeScript">
</div>
<div slot="typescript">

```typescript title="apphost.ts"
import { createBuilder } from './.modules/aspire.js';
Expand All @@ -538,8 +563,8 @@ await api.withReference(tech);
await builder.build().run();
```

</TabItem>
</Tabs>
</div>
</AppHostLangPivot>

### Hosting integration health checks

Expand Down
12 changes: 6 additions & 6 deletions .github/skills/update-samples/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
---
name: update-samples
description: Update the samples data file by fetching sample metadata from the dotnet/aspire-samples GitHub repository. Use when adding new samples, refreshing sample data, or ensuring samples.json stays in sync with the upstream repo.
description: Update the samples data file by fetching sample metadata from the microsoft/aspire-samples GitHub repository. Use when adding new samples, refreshing sample data, or ensuring samples.json stays in sync with the upstream repo.
---

# Update Samples Data

This skill synchronizes the samples data file with the `dotnet/aspire-samples` GitHub repository. It enumerates all sample projects in the `samples/` directory, fetches each sample's README.md, and generates a structured JSON catalog.
This skill synchronizes the samples data file with the `microsoft/aspire-samples` GitHub repository. It enumerates all sample projects in the `samples/` directory, fetches each sample's README.md, and generates a structured JSON catalog.

## Overview

The aspire.dev site maintains a data file for samples:

- **`src/frontend/src/data/samples.json`** — Sample metadata including titles, descriptions, tags, deep links, and README content extracted from the upstream repo.

This skill keeps that file in sync with the `dotnet/aspire-samples` repository on GitHub.
This skill keeps that file in sync with the `microsoft/aspire-samples` repository on GitHub.

## Prerequisites

Expand All @@ -32,7 +32,7 @@ Fetch the latest sample data from the GitHub API:
cd src/frontend && node scripts/update-samples.js
```

This writes updated sample metadata to `src/frontend/src/data/samples.json`. The script queries the GitHub Contents API for directories in `dotnet/aspire-samples/samples/`, fetches each sample's README.md, and extracts structured metadata.
This writes updated sample metadata to `src/frontend/src/data/samples.json`. The script queries the GitHub Contents API for directories in `microsoft/aspire-samples/samples/`, fetches each sample's README.md, and extracts structured metadata.

### 2. What the script does

Expand All @@ -46,7 +46,7 @@ For each subdirectory in `samples/`:
- **`name`** — The directory name (e.g., `aspire-shop`)
- **`title`** — Extracted from the first `# heading` in the README
- **`description`** — The first paragraph of body text after the title (before any `##` heading)
- **`href`** — Deep link to the sample on GitHub: `https://github.com/dotnet/aspire-samples/tree/main/samples/{name}`
- **`href`** — Deep link to the sample on GitHub: `https://github.com/microsoft/aspire-samples/tree/main/samples/{name}`
- **`readme`** — The full Markdown content of the README.md, with image paths rewritten to local assets (see below)
- **`tags`** — Auto-detected tags based on technologies, languages, services, and features mentioned in the README and directory name
- **`thumbnail`** — Local asset path to the first image referenced in the README (if any), or `null`
Expand Down Expand Up @@ -119,7 +119,7 @@ The output `samples.json` is a JSON array with entries like:
"name": "aspire-shop",
"title": "Aspire Shop",
"description": "The app consists of four .NET services including a Blazor frontend, catalog API, catalog database manager, and basket service.",
"href": "https://github.com/dotnet/aspire-samples/tree/main/samples/aspire-shop",
"href": "https://github.com/microsoft/aspire-samples/tree/main/samples/aspire-shop",
"readme": "# Aspire Shop\n\n![Screenshot...](~/assets/samples/aspire-shop/aspireshop-frontend-complete.png)...",
"tags": ["csharp", "blazor", "postgresql", "redis", "grpc", "ef-core"],
"thumbnail": "~/assets/samples/aspire-shop/aspireshop-frontend-complete.png"
Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ test-results/
# generated types
.astro/
.cache/

.netlify/
tmp/

# Logs
npm-debug.log*
Expand Down
12 changes: 12 additions & 0 deletions src/frontend/config/redirects.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,18 @@ export const redirects = {
'/reference/cli/commands/aspire-mcp-start/': '/reference/cli/commands/aspire-agent-mcp/',
'/reference/cli/commands/aspire-exec/': '/reference/cli/commands/aspire-resource/',
'/get-started/configure-mcp/': '/get-started/ai-coding-agents/',
'/get-started/first-app-csharp-apphost/': '/get-started/first-app/',
'/get-started/first-app-typescript-apphost/': '/get-started/first-app/',
'/get-started/deploy-first-app-csharp/': '/get-started/deploy-first-app/',
'/get-started/deploy-first-app-typescript/': '/get-started/deploy-first-app/',
'/get-started/add-aspire-existing-app-csharp-apphost/': '/get-started/add-aspire-existing-app/',
'/get-started/add-aspire-existing-app-typescript-apphost/': '/get-started/add-aspire-existing-app/',
'/ja/get-started/first-app-csharp-apphost/': '/ja/get-started/first-app/',
'/ja/get-started/first-app-typescript-apphost/': '/ja/get-started/first-app/',
'/ja/get-started/deploy-first-app-csharp/': '/ja/get-started/deploy-first-app/',
'/ja/get-started/deploy-first-app-typescript/': '/ja/get-started/deploy-first-app/',
'/ja/get-started/add-aspire-existing-app-csharp-apphost/': '/ja/get-started/add-aspire-existing-app/',
'/ja/get-started/add-aspire-existing-app-typescript-apphost/': '/ja/get-started/add-aspire-existing-app/',
'/get-started/pipelines/': '/deployment/pipelines/',
'/ja/get-started/pipelines/': '/ja/deployment/pipelines/',
'/deployment/manifest-format/': '/deployment/azure/manifest-format/',
Expand Down
Loading
Loading