Fix Dev Tunnels "Configure dev tunnel options" examples and document Region - #1468
Conversation
The C# sample referenced a non-existent `TunnelId` member, assigned a `string[]` to the `List<string>?` `Labels` property, and passed `DevTunnelOptions` into the `string? tunnelId` positional parameter, so it did not compile. Fix it to set `tunnelId`/`options` as named arguments on `AddDevTunnel` and use a collection expression for `Labels`. The TypeScript sample passed an options object, but the polyglot `addDevTunnel(name, tunnelId?, allowAnonymous?, description?, labels?)` export takes positional parameters. Update it to match the exported signature. Document the C#-only `Region` (`DevTunnelOptions`) property, which the options table previously omitted. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Updates the Dev Tunnels integration documentation to align the “Configure dev tunnel options” examples and configuration table with the current Aspire Dev Tunnels APIs, addressing issue #1465.
Changes:
- Fixes the C# sample to pass
tunnelId/optionscorrectly toAddDevTunneland removes the invalidTunnelIdoption member. - Updates the TypeScript sample to use the positional
addDevTunnel(name, tunnelId?, allowAnonymous?, description?, labels?)signature. - Documents the missing
Regionoption in theDevTunnelOptionstable, with a note about its C#-only availability.
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| allowAnonymous: false, | ||
| }).withReference(web); | ||
| const tunnel = await builder.addDevTunnel("qa", "my-tunnel-id", false, "QA environment tunnel", ["qa", "testing"]) | ||
| .withReference(web); |
Frontend HTML artifact readyThe latest frontend build uploaded the This comment updates automatically when a new frontend build artifact is uploaded. |
David Pine (IEvangelist)
left a comment
There was a problem hiding this comment.
📋 Docs-accuracy review — automated (doc-pr-reviewer)
Sources of truth
| Repo | Branch | SHA | Files read |
|---|---|---|---|
microsoft/aspire |
release/13.5 |
1d92281 |
src/Aspire.Hosting.DevTunnels/DevTunnelOptions.cs, src/Aspire.Hosting.DevTunnels/DevTunnelResourceBuilderExtensions.cs |
microsoft/aspire.dev (this PR) |
head | 375b694 |
generated src/frontend/src/data/ts-modules/Aspire.Hosting.DevTunnels.13.4.0.json, src/frontend/src/data/twoslash/aspire.d.ts |
Phase A — claims: 10 non-narrative claims extracted → 9 verified, 1 verified-with-nuance, 0 unverifiable, 0 contradicted.
Phase B — doc-tester: exercised /integrations/devtools/dev-tunnels/ (Configure dev tunnel options + Configuration → Dev tunnel options) on a local pnpm dev server serving this PR's content → 0 critical, 2 warnings (1 dev-only console artifact, 1 completeness gap).
Verdict: COMMENT. Every factual claim this PR makes checks out against microsoft/aspire release/13.5, and the page renders correctly. The two notes below are non-blocking. Nice, well-scoped fix. ✅
Phase A — Claim verification
No contradicted or unverifiable claims, so there are no blocking inline comments. One nuance worth surfacing (which the PR description already calls out):
verified-with-nuance— the corrected TypeScript sample still chains.withReference(web)
TheaddDevTunnel(...)call is now correct, but.withReference(web)is not an exported polyglot method. InDevTunnelResourceBuilderExtensions.cs(release/13.5) the resource/endpoint reference methods are exported aswithTunnelReferenceAll([AspireExport("withReferenceResourceAnonymous", MethodName = "withTunnelReferenceAll")]),withTunnelReference(MethodName = "withTunnelReference") andwithTunnelReferenceAnonymous; theWithReferenceoverloads that would map to a bare.withReferenceare[AspireExportIgnore]. So the TS snippet, if executed, would still fail on.withReference. This is pre-existing and page-wide (every TS sample on the page uses.withReference), it lives in a display-only```typescriptblock (nottwoslash, so CI doesn't type-check it), and the author explicitly deferred it as out of scope for #1465. Flagging only so the follow-up isn't lost. Not blocking.
✅ verified / verified-with-nuance claims (9 verified + 1 nuance) — evidence
Evidence paths are in microsoft/aspire@release/13.5 unless noted.
| # | Claim (from the diff) | Verdict | Evidence |
|---|---|---|---|
| 1 | DevTunnelOptions.Description exists (string?) |
verified | DevTunnelOptions.cs — public string? Description { get; set; } |
| 2 | Labels is List<string>?, so the collection expression ["qa", "testing"] is assignable (old new[] { ... } string[] was not) |
verified | DevTunnelOptions.cs — public List<string>? Labels { get; set; } |
| 3 | DevTunnelOptions.AllowAnonymous exists (bool) |
verified | DevTunnelOptions.cs — public bool AllowAnonymous { get; set; } |
| 4 | TunnelId is not a DevTunnelOptions member (removed from the sample) |
verified | DevTunnelOptions.cs — members are Description, AllowAnonymous, Labels, Region only; no TunnelId |
| 5 | AddDevTunnel("qa", tunnelId: "my-tunnel-id", options: options) matches the signature AddDevTunnel(this IDistributedApplicationBuilder, string name, string? tunnelId = null, DevTunnelOptions? options = null) |
verified | DevTunnelResourceBuilderExtensions.cs L49–53 |
| 6 | C# .WithReference(web) compiles |
verified | DevTunnelResourceBuilderExtensions.cs L286–290 — WithReference<TResource>(this IResourceBuilder<DevTunnelResource>, IResourceBuilder<TResource>, DevTunnelPortOptions? = null) where TResource : IResourceWithEndpoints |
| 7 | TS addDevTunnel("qa", "my-tunnel-id", false, "QA environment tunnel", ["qa", "testing"]) matches the polyglot export addDevTunnel(name, tunnelId?, allowAnonymous?, description?, labels?) |
verified | AddDevTunnelForPolyglot [AspireExport("addDevTunnel")] L239–252 (name, tunnelId, allowAnonymous, description, labels[]); confirmed in this repo's generated Aspire.Hosting.DevTunnels.13.4.0.json → functions[0].signature |
| 8 | Options table adds Region — "The DevTunnelRegion to create the tunnel in; automatic when unset" |
verified | DevTunnelOptions.cs — public DevTunnelRegion? Region { get; set; }, XML doc: "If not specified, the region will be selected automatically based on the ping." DevTunnelRegion enum defined (13 members) |
| 9 | Aside — "Region is only configurable in C# via DevTunnelOptions; the polyglot TypeScript addDevTunnel export doesn't surface a region parameter" |
verified | AddDevTunnelForPolyglot params are (name, tunnelId, allowAnonymous, description, labels) — no region; Region exists only on the C# DevTunnelOptions |
| 10 | TS sample chains .withReference(web) |
verified-with-nuance | See note above — exported polyglot names are withTunnelReference*, not withReference (pre-existing, author-acknowledged, out of scope) |
FYI (unchanged file, not part of this PR): this repo's twoslash aspire.d.ts declares two addDevTunnel overloads — a stale options-object form (addDevTunnel(name, options?: { tunnelId?, allowAnonymous?, description?, labels? }), L12314) alongside the correct positional form (L12319). The options-object overload doesn't exist in the real exported API, which is why the previous broken example passed twoslash. This PR's blocks are plain ```typescript/```csharp (display-only), so twoslash doesn't gate them either way — noting it only as a possible generator cleanup for a separate change.
Phase B — Doc-tester report (rendered site, blind to source)
Documentation Test Report
Focus Area: Dev Tunnels integration → "Configure dev tunnel options" and "Configuration → Dev tunnel options"
Date: 2026-08-11
Tester: doc-tester (served PR head 375b694 locally via pnpm dev, browsed with Playwright)
Summary
| Category | Passed | Failed | Warnings |
|---|---|---|---|
| Content Accuracy | 4 | 0 | 1 |
| Code Examples (rendering) | 2 | 0 | 0 |
| Links / anchors | 1 | 0 | 0 |
| Page load / console | 0 | 0 | 1 |
Critical Issues
None.
Warnings
Warning 1: Dev-only console error on page load
Location: /integrations/devtools/dev-tunnels/
Issue: The page logs one console error — 504 (Outdated Optimize Dep) @ /@id/astro/runtime/client/dev-toolbar/entrypoint.js.
Suggestion: This is a Vite dev-server dependency-optimizer artifact for the Astro dev toolbar, not a content or PR defect (it wouldn't appear in a production build). No action needed for this PR; noted for completeness.
Warning 2 (completeness / knowledge gap): Region valid values aren't shown
Location: "Configuration → Dev tunnel options" table + Region note
Issue: The new row documents Region as a DevTunnelRegion, and the note says it's C#-only, but a reader is never shown the valid region values or an example of setting one (e.g. Region = DevTunnelRegion.NorthEurope). As a new user I can't tell from this page which regions are accepted or how to reference the enum.
Suggestion (optional, non-blocking): Add a short C# snippet setting Region, and/or list/link the DevTunnelRegion members. Reasonable to defer, since #1465 only asked to add the row.
Passed Checks
- Page loads; title
Dev Tunnels integration | Aspire. - C# sample renders with correct syntax highlighting and a working copy button; content matches the PR (
Labels = ["qa", "testing"],AddDevTunnel("qa", tunnelId: "my-tunnel-id", options: options), noTunnelId). - TypeScript sample renders correctly; the C#/TypeScript tab toggle works and syncs the URL (
?aspire-lang=typescript); positional args display as authored. - "Dev tunnel options" table renders all four rows —
Description,Labels,AllowAnonymous,Region— withDevTunnelRegionformatted as inline code. - The
Region"Note" Aside renders correctly. - No new internal links introduced by the diff; the
#configure-dev-tunnel-optionsheading anchor resolves from the on-page table of contents. No 404s.
Recommendations
- Priority fixes: none — merge-ready on accuracy and rendering.
- Documentation gaps: optionally show
DevTunnelRegionvalues / aRegion = ...example (Warning 2). - Product/generator issues: the stale options-object
addDevTunneloverload in twoslashaspire.d.ts, and the page-wide.withReference→withTunnelReference*naming mismatch in TypeScript samples — both out of scope here and already noted by the author for follow-up.
🤖 Generated by the doc-pr-reviewer skill (Phase A: claim verification vs microsoft/aspire release/13.5; Phase B: doc-tester on a local render of this PR).
Fixes #1465
The Configure dev tunnel options section of the Dev Tunnels integration doc contained examples that don't compile/match the API, and the options table omitted
Region. All corrections were verified againstmicrosoft/aspirerelease/13.5(DevTunnelOptions.cs,DevTunnelResourceBuilderExtensions.cs) and the generated TypeScript module data in this repo.Changes
C# example — the previous sample didn't compile:
TunnelId, which isn't aDevTunnelOptionsmember (it's a parameter ofAddDevTunnel/ a property ofDevTunnelResource).Labels = new[] { "qa", "testing" }(astring[]) to the collection expression["qa", "testing"], which is assignable to theList<string>?property.tunnelId:andoptions:as named arguments toAddDevTunnel(string name, string? tunnelId = null, DevTunnelOptions? options = null)instead of bindingoptionsto thestring? tunnelIdpositional parameter.TypeScript example — the previous sample passed an options object that the export doesn't accept. The polyglot export is
addDevTunnel(name: string, tunnelId?: string, allowAnonymous?: boolean, description?: string, labels?: string[]), so the call now uses positional arguments.Options table — added the previously missing
Region(DevTunnelRegion?) property, with anAsidenoting it's C#-only (the polyglotaddDevTunnelexport doesn't surface a region parameter).Note (out of scope)
While verifying, I noticed the TypeScript examples throughout this page use
.withReference(...), but the generated polyglot method names arewithTunnelReference/withTunnelReferenceAll/withTunnelReferenceAnonymous. That's a separate, page-wide discrepancy not raised in #1465, so I left those calls unchanged here to keep this fix focused and consistent with the rest of the doc.