Skip to main content

Line Numbers

2 min readStableBeginner

Every fenced block ships with a numbered gutter. Writing showLineNumbers states that intent out loud, and showLineNumbers=N moves the first number so a snippet lines up with the file it came from.

Quick Start

No metastring at all. The numbers are already there.

TypeScript
TypeScript
const greeting: string = 'Hello, World!'
console.log(greeting)
app/features/code/line-numbers.mdx
MDX
```typescript
const greeting: string = 'Hello, World!'
console.log(greeting)
```

Adding Options

Write the flag when you want the fence to say what it's doing. The result is identical to leaving it off.

TypeScript
TypeScript
import { cache } from 'react'
 
const getCachedContent = cache(async (slug: string) => {
  return readFile(`./content/${slug}.mdx`, 'utf-8')
})
app/features/code/line-numbers.mdx
MDX
```typescript showLineNumbers
import { cache } from 'react'
 
const getCachedContent = cache(async (slug: string) => {
  return readFile(`./content/${slug}.mdx`, 'utf-8')
})
```

Advanced

Pair an offset with line highlighting and the two count differently on purpose. The gutter starts at 120, but {2} still means the second line of the block, which is why the tinted row reads 121.

lib/navigation-utils.ts
TypeScript
export function getRelatedPages(slugs: string[]) {
  const tree = buildNavigationTree()
  return slugs.map((slug) => findNode(tree, slug)).filter(Boolean)
}
app/features/code/line-numbers.mdx
MDX
```typescript showLineNumbers=120 {2} title="lib/navigation-utils.ts"
export function getRelatedPages(slugs: string[]) {
  const tree = buildNavigationTree()
  return slugs.map((slug) => findNode(tree, slug)).filter(Boolean)
}
```

Options

showLineNumbersbooleanDefault: true

Turns the numbered gutter on. Every fenced block already gets it, so this is a readability flag rather than a switch.

showLineNumbers=NnumberDefault: 1

Numbers the first line of the block N, then counts up from there. N must be written as digits — showLineNumbers=120. A value of 0 is accepted and starts the gutter at zero.

Behavior worth knowing

  • There is no off switch. showLineNumbers=false still turns numbering on, because the parser reads the flag and ignores anything after = that isn't a run of digits.
  • Line highlighting counts physical lines, always starting at 1. An offset moves the printed number, not the index you write inside {}.
  • The numbers come from a CSS counter, so they can't be selected and the copy button never picks them up.
  • The gutter is three characters wide and right-aligned. Past line 999 the numbers keep rendering, they just push into the two-character gap before the code.
  • Diff rows and highlighted rows keep their tint across the gutter, so a numbered line still reads as added, removed, or emphasized.
Was this page helpful?