Media

View as Markdown

Theme images live outside the media library, so WordPress knows nothing about their dimensions and every unstyled image shifts layout while it loads. Blockstudio closes that gap with a generated metadata manifest, a template helper that always emits real dimensions, and an optional lazy loader.

Rendering images

bs_media_image() renders theme assets with real width, height, and a reserved aspect ratio:

PHP
<?php
echo bs_media_image([
    'src' => 'assets/images/hero.webp',
    'alt' => 'Hero',
    'class' => 'hero-media',
    'sources' => [
        ['srcset' => '/hero-small.webp', 'media' => '(max-width: 640px)'],
    ],
]);
?>

The output is a figure.blockstudio-media with an inline aspect-ratio around an img carrying real width, height, loading, and decoding values.

src takes a theme-relative path, an absolute path, or a full URL, and attachmentId covers media library images. eager opts out of lazy loading above the fold, and sources emits a <picture> element with the given alternates.

The helper always emits known width, height, and aspect ratio values when metadata exists. Lazy mode uses only blockstudio-* classes, attributes, handles, and globals.

The metadata manifest

Dimensions come from assets/media.json, written by Blockstudio\Media_Metadata_Builder in a build step or by hand:

PHP
use Blockstudio\Media_Metadata_Builder;

(new Media_Metadata_Builder())->write(
    get_stylesheet_directory(),
    true
);

This writes deterministic metadata for the theme’s assets and, with the second argument, optional WordPress attachments. Regenerate it whenever files under assets/ change.

Media_Metadata_Builder::build( string $root ) returns the manifest without writing it; write() is the variant that persists. Blockstudio\Media_Metadata::reset() clears the in-process cache after a rebuild, which long-lived build processes need before rendering against fresh metadata.

Lazy loading

The performance.media settings drive the frontend loader:

JSON
{
  "performance": {
    "media": {
      "lazy": true,
      "skeleton": true,
      "metadata": true,
      "rootMargin": "300px"
    }
  }
}

With lazy on, the real URL moves to data-src behind a correctly sized placeholder and Blockstudio’s intersection-based loader swaps it in as the image approaches the viewport, rootMargin ahead of time. skeleton shows the built-in loading placeholder, and metadata declares that assets/media.json is in use.

The speed and strict performance profiles enable the loader by default; compat leaves it off. Every child value can override its profile default.

Settings

The full performance.media option table.

Static Prerendering

Media metadata is step two of the production adoption order.