docs: normalize code-fence languages for Shiki compatibility (#27161)

Normalizes non-standard code-fence language tags across `docs/**` so a
strict highlighter (Shiki, used by Fumadocs) won't fail the build on an
unrecognized language, and unifies redundant synonym tags onto one
canonical form per language. The current renderer (Speed-Highlight)
detects the language from the code content, not the fence label, so this
drift wasn't visible until now.

## Changes

- `hcl` -> `tf` (199 fences, including indented ones nested in
numbered/bulleted lists). Shiki ships `hcl` and `terraform` as two
distinct grammars (not aliases); every `hcl`-tagged fence in `docs/**`
is actually Terraform resource/data/provider syntax, so the more
specific `terraform` grammar is correct for all of them. `tf` is Shiki's
own alias for that grammar, and it's also what GitHub's own markdown
renderer resolves to the same HCL/Terraform highlighting.
- `pwsh`/`powershell` -> `ps1`. Both `ps` and `ps1` are registered
PowerShell aliases in Shiki, but on GitHub's renderer only `.ps1` is a
registered file extension (`.ps` isn't), so `ps1` renders identically to
`powershell` there today while bare `ps` would silently lose
highlighting.
- `env` -> `dotenv` (a dedicated Shiki grammar for `KEY=VALUE` files)
- `text`/`output`/`none`/`url` -> `txt`. Same built-in plain-text
fallback either way, just shorter.
- `Dockerfile` -> `dockerfile` (lowercase)
- `bash`/`shell` -> `sh` (732 fences). Shiki and GitHub both alias all
three to a single shell grammar; this was already the style guide's
stated preference, just not enforced across the existing corpus until
now.
- `markdown` -> `md` (4 fences). Alias of the same grammar in both Shiki
and GitHub.
- `jsonc` -> `json` (1 fence). The block has no comments or trailing
commas, so it doesn't need the comments-capable grammar.
- `ts` -> `tsx` (2 fences, `docs/about/contributing/frontend.md`).
Verified the actual content tokenizes identically under both grammars,
and a sibling block in the same file already needs `tsx` for real JSX,
so unifying to one tag is safe for this file. Documented a caveat: `tsx`
mis-tokenizes the legacy angle-bracket type-assertion syntax
(`<Type>value`), which is invalid in real `.tsx` files anyway, so use
`value as Type` instead.
- `yml` -> `yaml` (1 fence)
- Updated `docs/.style/style-guide/formatting.md` to document all
canonical tags

`promql` (2 fences) and `caddyfile` (2 fences) are left as-is. Shiki
doesn't bundle a grammar for either, so they need a custom grammar
registration when the site adopts Shiki, rather than degrading to `txt`.
Tracked as follow-up work under DOCS-118 and
[DOCS-544](https://linear.app/codercom/issue/DOCS-544/vendor-a-local-promql-grammar-for-shiki-syntax-highlighting)
(promql).

Does not touch `offlinedocs/`.

Linear:
[DOCS-476](https://linear.app/codercom/issue/DOCS-476/normalize-docs-code-fence-languages-de-risk-shikifumadocs)

<details>
<summary>How the fence tags were verified</summary>

Each tag was tested against a real `shiki@latest` highlighter instance
(`codeToHtml`/`codeToTokens`) and cross-checked against GitHub's
`@wooorm/starry-night` grammar sources (the renderer that actually
displays these `.md` files today, in repo browsing and PR diffs), since
that's what determines whether brevity is safe before Shiki adoption:

```text
FAIL  env        -- Language `env` is not included in this bundle.
FAIL  Dockerfile -- Language `Dockerfile` is not included in this bundle.
FAIL  promql     -- Language `promql` is not included in this bundle.
FAIL  caddyfile  -- Language `caddyfile` is not included in this bundle.
FAIL  pwsh       -- Language `pwsh` is not included in this bundle.
FAIL  output     -- Language `output` is not included in this bundle.
```

`hcl` doesn't error in Shiki, since it's a real grammar, but that's
exactly the trap: it was silently rendering every fence with the generic
HCL grammar instead of the Terraform-specific one. Every `hcl`-tagged
fence in `docs/**` was manually checked against `origin/main` and is
genuinely Terraform content.

For `ts`/`tsx`, tokenizing the actual doc content confirmed identical
output under both grammars; a synthetic test with the legacy
angle-bracket cast syntax confirmed `tsx` degrades on that specific
construct, which the style guide now calls out.

The first normalization pass only matched fence tags at column 0
(`^```tag$`), missing tags indented inside numbered/bulleted lists. A
follow-up pass caught the remaining occurrences at any indentation
level.

</details>


---

*This PR description and the underlying changes were prepared with Coder
Agents assistance.*
This commit is contained in:
Nick Vigilante
2026-07-15 14:07:09 -04:00
committed by GitHub
parent d0982e3cc7
commit c84aa564ba
181 changed files with 997 additions and 980 deletions
@@ -78,7 +78,7 @@ A malicious workspace could reuse Coder cookies to call the API or interact with
1. Disable path-based apps:
```shell
```sh
coderd server --disable-path-apps
# or
export CODER_DISABLE_PATH_APPS=true
@@ -23,7 +23,7 @@ potentially optimize within the template.
You can also retrieve this detail programmatically from the API:
```shell
```sh
curl -X GET https://coder.example.com/api/v2/workspacebuilds/{workspacebuild}/timings \
-H 'Accept: application/json' \
-H 'Coder-Session-Token: API_KEY'
@@ -137,19 +137,19 @@ To use `terraform init` to build the static provider version list:
1. Pull your template to your local device:
```shell
```sh
coder templates pull <template>
```
1. Run `terraform init` inside the template directory to build the lock file:
```shell
```sh
terraform init
```
1. Push the templates back to your Coder deployment:
```shell
```sh
coder templates push <template>
```
+4 -4
View File
@@ -46,7 +46,7 @@ Configure Coder to use these claims for group sync.
These claims are present in the `id_token`.
For more group sync configuration options, consult the [IDP sync documentation](../admin/users/idp-sync.md#group-sync).
```bash
```sh
# Add the 'groups' scope and include the 'offline_access' scope for refresh tokens
CODER_OIDC_SCOPES=openid,profile,email,offline_access,groups
# This name needs to match the "Claim name" in the configuration above.
@@ -59,7 +59,7 @@ CODER_OIDC_GROUP_FIELD=groups
These groups can also be used to configure role syncing based on group
membership:
```bash
```sh
CODER_OIDC_SCOPES=openid,profile,email,offline_access,groups
# This name needs to match the "Claim name" in the configuration above.
CODER_OIDC_USER_ROLE_FIELD=groups
@@ -91,7 +91,7 @@ attribute you have configured to the application:
Configure using these new attributes in Coder:
```bash
```sh
# This must be set to false. Coder uses this endpoint to grab the attributes.
CODER_OIDC_IGNORE_USERINFO=false
# Include offline_access for refresh tokens
@@ -142,7 +142,7 @@ This is so if other applications exist, we do not send them information they do
Now we have a custom scope and claim configured under an authorization server.
Configure Coder to use this:
```bash
```sh
# Grab this value from the Authorization Server > Settings > Issuer
# DO NOT USE the application issuer URL. Make sure to use the newly configured
# authorization server.
+4 -4
View File
@@ -26,7 +26,7 @@ Coder configuration is defined via
[environment variables](../admin/setup/index.md). The database client requires
the connection string provided via the `CODER_PG_CONNECTION_URL` variable.
```shell
```sh
export CODER_PG_CONNECTION_URL="postgres://coder:secret42@localhost/coder?sslmode=disable"
```
@@ -44,7 +44,7 @@ CREATE SCHEMA myschema;
Once the schema is created, you can list all schemas with `\dn`:
```text
```txt
List of schemas
Name | Owner
-----------+----------
@@ -55,7 +55,7 @@ List of schemas
In this case the database client requires the modified connection string:
```shell
```sh
export CODER_PG_CONNECTION_URL="postgres://coder:secret42@localhost/coder?sslmode=disable&search_path=myschema"
```
@@ -87,6 +87,6 @@ Please make sure that the schema selected in the connection string
`...&search_path=myschema` exists and the role has granted permissions to access
it. The schema should be present on this listing:
```shell
```sh
psql -U coder -c '\dn'
```
+4 -4
View File
@@ -42,7 +42,7 @@ Visit <https://coder.com/trial> or contact
1. Open a terminal.
1. Log in to your Coder deployment:
```shell
```sh
coder login <access url>
```
@@ -50,7 +50,7 @@ Visit <https://coder.com/trial> or contact
- For a `.jwt` license file:
```shell
```sh
coder licenses add -f <path to your license key>
```
@@ -241,7 +241,7 @@ can start Caddy as a `systemd` service.
The Caddyfile configuration will appear like this where `127.0.0.1:3000` is your
`CODER_ACCESS_URL`:
```text
```txt
coder.example.com {
reverse_proxy 127.0.0.1:3000
@@ -269,7 +269,7 @@ the existing Caddy binary in `usr/bin` and restart the Caddy service.
The updated Caddyfile configuration will look like this:
```text
```txt
*.coder.example.com, coder.example.com {
reverse_proxy 127.0.0.1:3000
+12 -12
View File
@@ -54,7 +54,7 @@ Because no individual user owns the workspace, there are no personal
credentials to expose and the shared environment is not affected when any user
leaves the team or the organization.
```shell
```sh
# On-call example — substitute a name that fits your use case
coder users create \
--username oncall-sre \
@@ -66,7 +66,7 @@ coder users create \
Generate a long-lived API token so you can create and manage workspaces on
behalf of the service account:
```shell
```sh
coder tokens create \
--user oncall-sre \
--name oncall-automation \
@@ -85,7 +85,7 @@ Manager).
Authenticate as the service account and create the workspace:
```shell
```sh
export CODER_SESSION_TOKEN="<token-from-step-2>"
coder create oncall-sre/oncall-workspace \
@@ -105,7 +105,7 @@ coder create oncall-sre/oncall-workspace \
Use `coder sharing share` to grant access to users who need the workspace:
```shell
```sh
coder sharing share oncall-sre/oncall-workspace --user alice
```
@@ -115,19 +115,19 @@ workspace apps, starting and stopping the workspace, and viewing logs and stats.
To grant `admin` permissions (which includes all `use` permissions as well as renaming, updating, and inviting
others to join with the `use` role):
```shell
```sh
coder sharing share oncall-sre/oncall-workspace --user alice:admin
```
To share with multiple users at once:
```shell
```sh
coder sharing share oncall-sre/oncall-workspace --user alice:admin,bob
```
To share with an entire Coder group:
```shell
```sh
coder sharing share oncall-sre/oncall-workspace --group sre-oncall
```
@@ -140,7 +140,7 @@ coder sharing share oncall-sre/oncall-workspace --group sre-oncall
When team membership changes, remove outgoing users and add incoming ones:
```shell
```sh
# Remove outgoing user
coder sharing remove oncall-sre/oncall-workspace --user alice
@@ -153,7 +153,7 @@ coder sharing share oncall-sre/oncall-workspace --user carol
Verify current sharing status at any time:
```shell
```sh
coder sharing status oncall-sre/oncall-workspace
```
@@ -165,7 +165,7 @@ cron job.
### Rotation script
```shell
```sh
#!/bin/bash
# rotate-access.sh
# Usage: ./rotate-access.sh <outgoing-user> <incoming-user>
@@ -199,7 +199,7 @@ in Okta or Azure AD), you can skip manual share/remove commands entirely:
1. Share the workspace with the group once:
```shell
```sh
coder sharing share oncall-sre/oncall-workspace --group sre-oncall
```
@@ -211,7 +211,7 @@ in Okta or Azure AD), you can skip manual share/remove commands entirely:
Shared users can find workspaces shared with them:
```shell
```sh
# List all shared workspaces you can access, including your own
coder list --search shared:true
+4 -4
View File
@@ -18,7 +18,7 @@ follow the steps below:
1. Create the certificate as a secret in your Kubernetes cluster, if not already
present:
```shell
```sh
kubectl create secret tls postgres-certs -n coder --key="postgres.key" --cert="postgres.crt"
```
@@ -38,7 +38,7 @@ coder:
1. Lastly, your PG connection URL will look like:
```shell
```sh
postgres://<user>:<password>@databasehost:<port>/<db-name>?sslmode=require&sslcert="$HOME/.postgresql/postgres.crt&sslkey=$HOME/.postgresql/postgres.key"
```
@@ -47,7 +47,7 @@ postgres://<user>:<password>@databasehost:<port>/<db-name>?sslmode=require&sslce
1. Download the CA certificate chain for your database instance, and create it
as a secret in your Kubernetes cluster, if not already present:
```shell
```sh
kubectl create secret tls postgres-certs -n coder --key="postgres-root.key" --cert="postgres-root.crt"
```
@@ -67,7 +67,7 @@ coder:
1. Lastly, your PG connection URL will look like:
```shell
```sh
postgres://<user>:<password>@databasehost:<port>/<db-name>?sslmode=verify-full&sslrootcert="/home/coder/.postgresql/postgres-root.crt"
```
+13 -13
View File
@@ -5,7 +5,7 @@
1. Start a Coder deployment and be sure to set the following
[configuration values](../admin/setup/index.md):
```env
```dotenv
CODER_HTTP_ADDRESS=127.0.0.1:3000
CODER_ACCESS_URL=https://coder.example.com
CODER_WILDCARD_ACCESS_URL=*coder.example.com
@@ -24,13 +24,13 @@
3. Install Apache (assuming you're on Debian/Ubuntu):
```shell
```sh
sudo apt install apache2
```
4. Enable the following Apache modules:
```shell
```sh
sudo a2enmod proxy
sudo a2enmod proxy_http
sudo a2enmod ssl
@@ -39,7 +39,7 @@
5. Stop Apache service and disable default site:
```shell
```sh
sudo a2dissite 000-default.conf
sudo systemctl stop apache2
```
@@ -70,7 +70,7 @@ providers, refer to the
dns_cloudflare_api_token = YOUR_API_TOKEN
```
```shell
```sh
mkdir -p ~/.secrets/certbot
touch ~/.secrets/certbot/cloudflare.ini
nano ~/.secrets/certbot/cloudflare.ini
@@ -78,7 +78,7 @@ providers, refer to the
3. Set the correct permissions:
```shell
```sh
sudo chmod 600 ~/.secrets/certbot/cloudflare.ini
```
@@ -86,7 +86,7 @@ providers, refer to the
1. Create the wildcard certificate:
```shell
```sh
sudo certbot certonly --dns-cloudflare --dns-cloudflare-credentials ~/.secrets/certbot/cloudflare.ini -d coder.example.com -d *.coder.example.com
```
@@ -97,7 +97,7 @@ you're using `coder.example.com` as your subdomain.
1. Create Apache configuration for Coder:
```shell
```sh
sudo nano /etc/apache2/sites-available/coder.conf
```
@@ -137,13 +137,13 @@ you're using `coder.example.com` as your subdomain.
3. Enable the site:
```shell
```sh
sudo a2ensite coder.conf
```
4. Restart Apache:
```shell
```sh
sudo systemctl restart apache2
```
@@ -151,19 +151,19 @@ you're using `coder.example.com` as your subdomain.
1. Create a new file in `/etc/cron.weekly`:
```shell
```sh
sudo touch /etc/cron.weekly/certbot
```
2. Make it executable:
```shell
```sh
sudo chmod +x /etc/cron.weekly/certbot
```
3. And add this code:
```shell
```sh
#!/bin/sh
sudo certbot renew -q
```
+4 -4
View File
@@ -108,7 +108,7 @@ certificates, you'll need a domain name that resolves to your Caddy server.
4. Start Coder. Set `CODER_ACCESS_URL` and `CODER_WILDCARD_ACCESS_URL` to the
domain you're using in your Caddyfile.
```shell
```sh
export CODER_ACCESS_URL=https://coder.example.com
export CODER_WILDCARD_ACCESS_URL=*.coder.example.com
docker compose up -d # Run on startup
@@ -158,20 +158,20 @@ certificates, you'll need a domain name that resolves to your Caddy server.
If you're [keeping Caddy running](https://caddyserver.com/docs/running) via a
system service:
```shell
```sh
sudo systemctl restart caddy
```
Or run a standalone server:
```shell
```sh
caddy run
```
6. Optionally, use [ufw](https://wiki.ubuntu.com/UncomplicatedFirewall) or
another firewall to disable external traffic outside of Caddy.
```shell
```sh
# Check status of UncomplicatedFirewall
sudo ufw status
+14 -14
View File
@@ -5,7 +5,7 @@
1. Start a Coder deployment and be sure to set the following
[configuration values](../admin/setup/index.md):
```env
```dotenv
CODER_HTTP_ADDRESS=127.0.0.1:3000
CODER_ACCESS_URL=https://coder.example.com
CODER_WILDCARD_ACCESS_URL=*.coder.example.com
@@ -24,13 +24,13 @@
3. Install NGINX (assuming you're on Debian/Ubuntu):
```shell
```sh
sudo apt install nginx
```
4. Stop NGINX service:
```shell
```sh
sudo systemctl stop nginx
```
@@ -41,13 +41,13 @@ you're using `coder.example.com` as your subdomain.
1. Create NGINX configuration for this app:
```shell
```sh
sudo touch /etc/nginx/sites-available/coder.example.com
```
2. Activate this file:
```shell
```sh
sudo ln -s /etc/nginx/sites-available/coder.example.com /etc/nginx/sites-enabled/coder.example.com
```
@@ -77,7 +77,7 @@ providers, refer to the
dns_cloudflare_api_token = YOUR_API_TOKEN
```
```shell
```sh
mkdir -p ~/.secrets/certbot
touch ~/.secrets/certbot/cloudflare.ini
nano ~/.secrets/certbot/cloudflare.ini
@@ -85,7 +85,7 @@ providers, refer to the
3. Set the correct permissions:
```shell
```sh
sudo chmod 600 ~/.secrets/certbot/cloudflare.ini
```
@@ -93,7 +93,7 @@ providers, refer to the
1. Create the wildcard certificate:
```shell
```sh
sudo certbot certonly --dns-cloudflare --dns-cloudflare-credentials ~/.secrets/certbot/cloudflare.ini -d coder.example.com -d *.coder.example.com
```
@@ -101,7 +101,7 @@ providers, refer to the
1. Edit the file with:
```shell
```sh
sudo nano /etc/nginx/sites-available/coder.example.com
```
@@ -144,7 +144,7 @@ providers, refer to the
3. Test the configuration:
```shell
```sh
sudo nginx -t
```
@@ -152,26 +152,26 @@ providers, refer to the
1. Create a new file in `/etc/cron.weekly`:
```shell
```sh
sudo touch /etc/cron.weekly/certbot
```
2. Make it executable:
```shell
```sh
sudo chmod +x /etc/cron.weekly/certbot
```
3. And add this code:
```shell
```sh
#!/bin/sh
sudo certbot renew -q
```
## Restart NGINX
```shell
```sh
sudo systemctl restart nginx
```
+2 -2
View File
@@ -365,7 +365,7 @@ use the Coder CLI.
1. Paste it into the CLI:
```output
```txt
> Welcome to Coder, marc! You're authenticated.
$
```
@@ -414,7 +414,7 @@ through the CLI, or through the Coder dashboard:
- To zip the files through the command line:
```shell
```sh
zip templates.zip Dockerfile main.tf
```
+2 -2
View File
@@ -35,7 +35,7 @@ ensures your templates are validated, tested, and promoted seamlessly.
For Premium deployments, create a service account:
```shell
```sh
coder users create \
--username machine-user \
--service-account
@@ -46,7 +46,7 @@ coder tokens create --user machine-user --lifetime 8760h
For OSS deployments, create a regular user:
```shell
```sh
coder users create \
--username machine-user \
--email machine-user@example.com \