Files
coder/docs/tutorials
Nick Vigilante d43dd98baf docs: rewrite gerund-leading headings and page titles (#30049)
Rewrites the headings and page titles that `Coder.GerundHeading` flags
as gerund-leading, using the imperative for tasks and the noun form for
concepts.
This PR covers only changes that don't rename a page slug.

## Changes

- Rewrites 121 in-page headings, bringing `Coder.GerundHeading` findings
in `docs/` to zero.
- Adds an empty `<a id="old-slug"></a>` above each renamed heading, so
existing bookmarks and inbound deep links still land on the section.
The legacy IDs were computed with the same slugger the classic renderer
uses (`rehype-slug`), and all 115 that exist on production today match
the live `id` attributes; the other 6 are on pages not published yet.
- Updates the 18 in-docs links that targeted old anchors to use the new
slugs, and the link text that quoted the old heading.
- De-gerunds seven page titles (frontmatter and `manifest.json`) whose
slugs don't change, for example `Upgrading Best Practices` to `Upgrade
best practices`.
- Scopes a Vale exception around the glossary term `Coding agent`, where
"Coding" is an adjective.

## Not in this PR

- **Pages with gerund slugs** (`creating-templates`, `getting-started`,
`working-with-dev-containers`, `cloning-git-repositories`,
`configuring-okta`, and others) keep their current titles, so the title
and slug change together in the slug-rename PR.
  The redirects for those renames come in a third PR.
- **Links outside `docs/`** to old anchors (Go notification strings, an
applied SQL migration, golden files, and the generated `prometheus.md`)
still target old slugs.
They keep working through the legacy anchors, and updating them would
need code changes.

## Known limitation

`coder/docs-engine` prefixes raw-HTML `id` attributes with
`user-content-` (DOM-clobbering protection), and inbound deep links
aren't rewritten.
Once the docs move to docs-engine, these legacy anchors resolve only as
`#user-content-<old-slug>` unless docs-engine adds a fragment fallback.
They work on the current coder.com renderer and on GitHub.

## Testing

- `vale --filter='.Name=="Coder.GerundHeading"' docs`: zero findings,
down from 122.
- `make lint/markdown`, `make lint/docs-html`, `make lint/emdash`, and
the pre-commit hook: all pass.
- Scripted check that every relative `#fragment` link into a changed
file resolves to a heading slug or a legacy anchor (177 links).
- Scripted check that no legacy ID collides with a heading slug on the
same page, and that no untouched heading's duplicate-suffix slug
shifted.

<details>
<summary>Heading renames and legacy anchors (121)</summary>

| File | Old heading | New heading | Legacy anchor |
| --- | --- | --- | --- |
| `admin/integrations/opentofu.md` | Using a custom Terraform binary |
Use a custom Terraform binary | `#using-a-custom-terraform-binary` |
| `admin/monitoring/connection-logs.md` | Capturing/Exporting Connection
Logs | Capture and export connection logs |
`#capturingexporting-connection-logs` |
| `admin/monitoring/metrics.md` | Setting up metrics | Set up metrics |
`#setting-up-metrics` |
| `admin/networking/port-forwarding.md` | Accessing workspace ports |
Access workspace ports | `#accessing-workspace-ports` |
| `admin/networking/port-forwarding.md` | Sharing ports | Share ports |
`#sharing-ports` |
| `admin/networking/port-forwarding.md` | Configuring port protocol |
Configure port protocol | `#configuring-port-protocol` |
| `admin/networking/workspace-proxies.md` | Running on Kubernetes | Run
on Kubernetes | `#running-on-kubernetes` |
| `admin/networking/workspace-proxies.md` | Running on a VM | Run on a
VM | `#running-on-a-vm` |
| `admin/networking/workspace-proxies.md` | Running as a system service
| Run as a system service | `#running-as-a-system-service` |
| `admin/networking/workspace-proxies.md` | Running in Docker | Run in
Docker | `#running-in-docker` |
| `admin/networking/workspace-proxies.md` | Selecting a proxy | Select a
proxy | `#selecting-a-proxy` |
| `admin/security/audit-logs.md` | Capturing/Exporting Audit Logs |
Capture and export audit logs | `#capturingexporting-audit-logs` |
| `admin/security/audit-logs.md` | Purging Old Audit Logs | Purge old
audit logs | `#purging-old-audit-logs` |
| `admin/security/database-encryption.md` | Enabling encryption | Turn
on encryption | `#enabling-encryption` |
| `admin/security/database-encryption.md` | Rotating keys | Rotate keys
| `#rotating-keys` |
| `admin/security/database-encryption.md` | Disabling encryption | Turn
off encryption | `#disabling-encryption` |
| `admin/security/database-encryption.md` | Deleting Encrypted Data |
Delete encrypted data | `#deleting-encrypted-data` |
| `admin/security/secrets.md` | Displaying Secrets | Display secrets |
`#displaying-secrets` |
| `admin/setup/data-retention.md` | Keeping Data Indefinitely | Keep
data indefinitely | `#keeping-data-indefinitely` |
| `admin/setup/index.md` | Migrating from the built-in database to an
external database | Migrate from the built-in database to an external
database |
`#migrating-from-the-built-in-database-to-an-external-database` |
| `admin/setup/index.md` | Configuring Coder behind a proxy | Configure
Coder behind a proxy | `#configuring-coder-behind-a-proxy` |
| `admin/setup/telemetry.md` | Toggling | Turn telemetry on or off |
`#toggling` |
| `admin/templates/creating-templates.md` | Disabling the template
builder | Turn off the template builder |
`#disabling-the-template-builder` |
| `admin/templates/extending-templates/agent-metadata.md` | Managing the
database load | Manage the database load | `#managing-the-database-load`
|
| `admin/templates/extending-templates/docker-in-workspaces.md` |
Authenticating with a Private Registry | Authenticate with a private
registry | `#authenticating-with-a-private-registry` |
| `admin/templates/extending-templates/index.md` | Running scripts on
workspace lifecycle | Run scripts on workspace lifecycle events |
`#running-scripts-on-workspace-lifecycle` |
| `admin/templates/extending-templates/parameters.md` | Validating
parameters | Validate parameters | `#validating-parameters` |
| `admin/templates/extending-templates/prebuilt-workspaces.md` |
Invalidating prebuilds | Invalidate prebuilds |
`#invalidating-prebuilds` |
| `admin/templates/extending-templates/prebuilt-workspaces.md` |
Managing resource quotas | Manage resource quotas |
`#managing-resource-quotas` |
| `admin/templates/extending-templates/prebuilt-workspaces.md` |
Managing prebuild provisioning queues | Manage prebuild provisioning
queues | `#managing-prebuild-provisioning-queues` |
| `admin/templates/extending-templates/prebuilt-workspaces.md` |
Preventing resource replacement | Prevent resource replacement |
`#preventing-resource-replacement` |
| `admin/templates/extending-templates/prebuilt-workspaces.md` |
Preventing prebuild queue contention (recommended) | Prevent prebuild
queue contention (recommended) |
`#preventing-prebuild-queue-contention-recommended` |
| `admin/templates/extending-templates/process-logging.md` | Configuring
custom templates to use workspace process logging | Configure custom
templates to use workspace process logging |
`#configuring-custom-templates-to-use-workspace-process-logging` |
| `admin/templates/extending-templates/process-logging.md` | Viewing
workspace process logs | View workspace process logs |
`#viewing-workspace-process-logs` |
| `admin/templates/extending-templates/process-priority.md` | Verifying
the feature is enabled | Verify the feature is enabled |
`#verifying-the-feature-is-enabled` |
| `admin/templates/extending-templates/resource-metadata.md` | Hiding
resources in the dashboard | Hide resources in the dashboard |
`#hiding-resources-in-the-dashboard` |
| `admin/templates/extending-templates/resource-metadata.md` | Using a
custom resource icon | Use a custom resource icon |
`#using-a-custom-resource-icon` |
| `admin/templates/extending-templates/resource-ordering.md` | Using
"order" property | Use the "order" property | `#using-order-property` |
| `admin/templates/extending-templates/resource-persistence.md` |
Disabling persistence | Turn off persistence | `#disabling-persistence`
|
| `admin/templates/index.md` | Extending templates | Extend templates |
`#extending-templates` |
| `admin/templates/managing-templates/change-management.md` | Testing
and Publishing Coder Templates in CI/CD | Test and publish Coder
templates in CI/CD | `#testing-and-publishing-coder-templates-in-cicd` |
| `admin/templates/managing-templates/index.md` | Creating templates |
Create templates | `#creating-templates` |
| `admin/templates/managing-templates/index.md` | Editing templates |
Edit templates | `#editing-templates` |
| `admin/templates/managing-templates/index.md` | Updating templates |
Update templates | `#updating-templates` |
| `admin/templates/troubleshooting.md` | Debugging the startup script |
Debug the startup script | `#debugging-the-startup-script` |
| `admin/users/groups-roles.md` | Creating custom roles | Create custom
roles | `#creating-custom-roles` |
| `admin/users/index.md` | Configuring SSO | Configure SSO |
`#configuring-sso` |
| `admin/users/index.md` | Resetting a password on Kubernetes | Reset a
password on Kubernetes | `#resetting-a-password-on-kubernetes` |
| `admin/users/quotas.md` | Establishing Costs | Establish costs |
`#establishing-costs` |
| `admin/users/quotas.md` | Establishing Budgets | Establish budgets |
`#establishing-budgets` |
| `admin/users/sessions-tokens.md` | Creating tokens with scopes |
Create tokens with scopes | `#creating-tokens-with-scopes` |
| `ai-coder/agent-firewall/index.md` | Getting Started with Agent
Firewall | Get started with Agent Firewall |
`#getting-started-with-agent-firewall` |
| `ai-coder/agent-firewall/index.md` | Viewing Audit Logs | View audit
logs | `#viewing-audit-logs` |
| `ai-coder/agent-firewall/nsjail/k8s.md` | Running without user
namespaces | Run without user namespaces |
`#running-without-user-namespaces` |
| `ai-coder/agent-firewall/version.md` | Using Coder Before v2.30.0 with
Claude Code Module v4.7.0+ | Coder before v2.30.0 with Claude Code
module v4.7.0+ |
`#using-coder-before-v2300-with-claude-code-module-v470` |
| `ai-coder/agent-firewall/version.md` | Using Claude Code Module Before
v4.7.0 | Claude Code module before v4.7.0 |
`#using-claude-code-module-before-v470` |
| `ai-coder/agents/getting-started.md` | Providing feedback | Provide
feedback | `#providing-feedback` |
| `ai-coder/agents/models.md` | Managing personal API keys | Manage
personal API keys | `#managing-personal-api-keys` |
| `ai-coder/agents/models.md` | Removing a personal key | Remove a
personal key | `#removing-a-personal-key` |
| `ai-coder/agents/models.md` | Using an LLM proxy | Use an LLM proxy |
`#using-an-llm-proxy` |
| `ai-coder/agents/platform-controls/git-providers.md` | Checking logs |
Check logs | `#checking-logs` |
| `ai-coder/ai-gateway/audit.md` | Navigating the UI | Navigate the UI |
`#navigating-the-ui` |
| `ai-coder/ai-gateway/audit.md` | Conducting a forensic audit | Conduct
a forensic audit | `#conducting-a-forensic-audit` |
| `ai-coder/ai-gateway/clients/jetbrains.md` | Using the AI Assistant |
Use the AI Assistant | `#using-the-ai-assistant` |
| `install/operate/upgrade/best-practices.md` | Diagnosing liveness
probe issues | Diagnose liveness probe issues |
`#diagnosing-liveness-probe-issues` |
| `install/operate/upgrade/best-practices.md` | Recovering from failed
database migrations | Recover from failed database migrations |
`#recovering-from-failed-database-migrations` |
| `install/operate/upgrade/esr-2.24-2.29-upgrade.md` | Upgrading |
Upgrade recommendations | `#upgrading` |
| `install/operate/upgrade/esr-2.29-2.34-upgrade.md` | Upgrading |
Upgrade recommendations | `#upgrading` |
| `install/prepare/licensing.md` | Adding your license key | Add your
license key | `#adding-your-license-key` |
| `install/server/cloud/azure-vm.md` | Creating and Uploading Your First
Template | Create and upload your first template |
`#creating-and-uploading-your-first-template` |
| `install/server/cloud/compute-engine.md` | Configuring the control
plane | Configure the control plane | `#configuring-the-control-plane` |
| `reference/releases.md` | Installing stable | Install stable |
`#installing-stable` |
| `start/first-workspace.md` | Creating your first coder workspace |
Create your first Coder workspace |
`#creating-your-first-coder-workspace` |
| `start/local-deploy.md` | Setting up a Coder deployment | Set up a
Coder deployment | `#setting-up-a-coder-deployment` |
| `tutorials/best-practices/organizations.md` | Managing Organizations
at Scale | Manage organizations at scale |
`#managing-organizations-at-scale` |
| `tutorials/example-guide.md` | Adding Photos | Add photos |
`#adding-photos` |
| `tutorials/example-guide.md` | Setting the author data | Set the
author data | `#setting-the-author-data` |
| `tutorials/example-guide.md` | Setting up the routes | Set up the
routes | `#setting-up-the-routes` |
| `tutorials/persistent-shared-workspaces.md` | Finding shared
workspaces | Find shared workspaces | `#finding-shared-workspaces` |
| `tutorials/reverse-proxy-caddy.md` | Getting started | Get started |
`#getting-started` |
| `tutorials/reverse-proxy-caddy.md` | Generating wildcard certificates
| Generate wildcard certificates | `#generating-wildcard-certificates` |
| `tutorials/reverse-proxy-nginx.md` | Adding Coder deployment subdomain
| Add the Coder deployment subdomain |
`#adding-coder-deployment-subdomain` |
| `tutorials/testing-templates.md` | Creating the headless user | Create
the headless user | `#creating-the-headless-user` |
| `user-guides/desktop/desktop-connect-sync.md` | Accessing web apps in
a secure browser context | Access web apps in a secure browser context |
`#accessing-web-apps-in-a-secure-browser-context` |
| `user-guides/desktop/index.md` | Testing Your Connection | Test your
connection | `#testing-your-connection` |
| `user-guides/desktop/index.md` | Getting Help | Get help |
`#getting-help` |
| `user-guides/desktop/index.md` | Uninstalling | Uninstall Coder
Desktop | `#uninstalling` |
| `user-guides/devcontainers/index.md` | Getting started | Get started |
`#getting-started` |
| `user-guides/devcontainers/troubleshooting-dev-containers.md` |
Finding your dev container agent | Find your dev container agent |
`#finding-your-dev-container-agent` |
| `user-guides/devcontainers/troubleshooting-dev-containers.md` |
Getting more help | Get more help | `#getting-more-help` |
| `user-guides/devcontainers/working-with-dev-containers.md` | Using the
Coder CLI | Use the Coder CLI | `#using-the-coder-cli` |
| `user-guides/devcontainers/working-with-dev-containers.md` | Using
OpenSSH (config-ssh) | Use OpenSSH (config-ssh) |
`#using-openssh-config-ssh` |
| `user-guides/devcontainers/working-with-dev-containers.md` | Exposing
ports on the parent workspace | Expose ports on the parent workspace |
`#exposing-ports-on-the-parent-workspace` |
| `user-guides/devcontainers/working-with-dev-containers.md` |
Rebuilding dev containers | Rebuild dev containers |
`#rebuilding-dev-containers` |
| `user-guides/shared-workspaces.md` | Getting Started | Get started |
`#getting-started` |
| `user-guides/shared-workspaces.md` | Sharing your Workspace | Share
your workspace | `#sharing-your-workspace` |
| `user-guides/shared-workspaces.md` | Using a shared workspace | Use a
shared workspace | `#using-a-shared-workspace` |
| `user-guides/shared-workspaces.md` | Accessing workspace apps in
shared workspaces | Access workspace apps in shared workspaces |
`#accessing-workspace-apps-in-shared-workspaces` |
| `user-guides/workspace-access/emacs-tramp.md` | Connecting To A
Workspace | Connect to a workspace | `#connecting-to-a-workspace` |
| `user-guides/workspace-access/emacs-tramp.md` | Using SSH | Use SSH |
`#using-ssh` |
| `user-guides/workspace-access/index.md` | Running remote commands with
quoting | Run remote commands with quoting |
`#running-remote-commands-with-quoting` |
| `user-guides/workspace-access/jetbrains/gateway.md` | Configuring the
Gateway plugin to use internal certificates | Configure the Gateway
plugin to use internal certificates |
`#configuring-the-gateway-plugin-to-use-internal-certificates` |
| `user-guides/workspace-access/jetbrains/gateway.md` | Using an
existing JetBrains installation in the workspace | Use an existing
JetBrains installation in the workspace |
`#using-an-existing-jetbrains-installation-in-the-workspace` |
| `user-guides/workspace-access/port-forwarding.md` | Accessing
workspace ports | Access workspace ports | `#accessing-workspace-ports`
|
| `user-guides/workspace-access/port-forwarding.md` | Sharing ports |
Share ports | `#sharing-ports` |
| `user-guides/workspace-access/port-forwarding.md` | Configuring port
protocol | Configure port protocol | `#configuring-port-protocol` |
| `user-guides/workspace-access/vscode.md` | Using the public extensions
marketplaces | Use the public extensions marketplaces |
`#using-the-public-extensions-marketplaces` |
| `user-guides/workspace-access/vscode.md` | Adding extensions to custom
images | Add extensions to custom images |
`#adding-extensions-to-custom-images` |
| `user-guides/workspace-access/vscode.md` | Installing extensions using
its `vsix` file at the command line | Install extensions using a `vsix`
file at the command line |
`#installing-extensions-using-its-vsix-file-at-the-command-line` |
| `user-guides/workspace-access/vscode.md` | Installing from a
marketplace at the command line | Install from a marketplace at the
command line | `#installing-from-a-marketplace-at-the-command-line` |
| `user-guides/workspace-access/vscode.md` | Using VS Code Desktop | Use
VS Code Desktop | `#using-vs-code-desktop` |
| `user-guides/workspace-access/web-terminal.md` | Accessing the
Terminal | Access the terminal | `#accessing-the-terminal` |
| `user-guides/workspace-lifecycle.md` | Stopping workspaces | Stop
workspaces | `#stopping-workspaces` |
| `user-guides/workspace-lifecycle.md` | Deleting workspaces | Delete
workspaces | `#deleting-workspaces` |
| `user-guides/workspace-management.md` | Creating workspaces | Create
workspaces | `#creating-workspaces` |
| `user-guides/workspace-management.md` | Updating workspaces | Update
workspaces | `#updating-workspaces` |
| `user-guides/workspace-management.md` | Updating via the CLI | Update
with the CLI | `#updating-via-the-cli` |
| `user-guides/workspace-management.md` | Starting and stopping
workspaces | Start and stop workspaces |
`#starting-and-stopping-workspaces` |
| `user-guides/workspace-management.md` | Repairing workspaces | Repair
workspaces | `#repairing-workspaces` |
| `user-guides/workspace-scheduling.md` | Working hours | Work schedule
| `#working-hours` |
| `user-guides/workspace-scheduling.md` | Basing solely on activity
detection | Rely solely on activity detection |
`#basing-solely-on-activity-detection` |

</details>

<details>
<summary>Plan</summary>

The de-gerund work ships as three PRs:

1. This PR: in-page headings and page titles that do not require a page
slug rename.
1. Page slug renames for pages whose filenames are gerunds.
1. Redirects for the renamed slugs.

Heading rewrites follow the style guide section "No gerund-leading
headings": imperative for task headings, noun form for concept headings,
sentence case, and "turn on"/"turn off" instead of "enable"/"disable"
per word-choice guidance.
The legacy anchor sits on its own line above the heading (with a blank
line between) rather than inside the heading, so it does not leak into
heading text, TOC entries, or Fumadocs slugs.

</details>

---

_Generated by Coder Agents on behalf of @nickvigilante._
2026-09-28 13:40:07 -04:00
..