Image dimensions
Opt-inAuto-detect and inject width/height attributes on local img elements to eliminate Cumulative Layout Shift.
The imageDimensions feature reads image file headers at build time and injects width and height attributes on <img> elements that reference local files. Providing these attributes lets browsers allocate the correct space before the image loads, eliminating Cumulative Layout Shift (CLS).
Reference: <code>rehype-img-size</code>.
Enable
// zfb.config.ts
export default defineConfig({
markdown: {
features: {
imageDimensions: {},
},
},
});
Behaviour
For each <img> element, the plugin:
- Skips elements that already carry
widthorheightattributes. - Skips remote URLs (
http:,/ / https:,/ / /) and/ data:URLs. - Resolves the
srcto an absolute path (see Source resolution below). - Reads only the image file header — no full decode occurs — and injects
width="W" height="H". - If the file cannot be found or is not a recognised image format, emits a build warning and leaves the element unchanged.
Supported formats: PNG, JPEG, GIF, WebP, AVIF.
Source resolution
The plugin resolves src values against the file system using BuildContext:
- Absolute paths (e.g.
/) are resolved against the project’simg/ hero. png publicdirectory. - Relative paths (e.g.
.,/ assets/ hero. png assets/) are resolved relative to the markdown source file’s directory.hero. png - Remote and
data:URLs are skipped silently.
Options
skipRemote(defaulttrue) — whentrue,http:and/ / https:image sources are skipped. Set to/ / falseonly for unusual setups; probing remote images requires network access at build time.
imageDimensions: { skipRemote: false },
Example
Given a 400×300 PNG at public/ and this markdown:

The plugin produces:
<img src="/images/hero.png" alt="Hero image" width="400" height="300">
An <img> with explicit dimensions is left unchanged:
<img src="/images/hero.png" width="200" height="150" />
Caching
The plugin caches (path, mtime) → (width, height) in memory. A second <img> reference to the same file within the same build hits the cache rather than re-reading the file header.
Ordering
ImageDimensionsPlugin runs in the hast phase, before SyntectPlugin. It injects width and height on <img> elements found in the document.
Requirements
This feature uses the wave-6 BuildContext seam. The pipeline must be invoked via Pipeline::run_with_context (or Pipeline::apply_hast_visitors_with_context) for dimensions to be injected. When the feature is wired but run (without context) is called, the plugin is a no-op.