Skip to content

Media images

Media and Images

When to Use

Handle Drupal media entities, image fields, and inline images in body fields using Next.js Image component for optimization.

Decision

Approach Use Case Implementation
Media entity fields Structured image fields Include relationship, use field_media_image
Inline images in body WYSIWYG editor images Parse HTML, replace with Image component
File fields (deprecated) Legacy implementations Use media entities instead

Pattern

Media entity field:

const article = await drupal.getResource("node--article", uuid, {
  params: {
    include: "field_image.field_media_image",
  },
})

// In component
import Image from "next/image"

<Image
  src={`${process.env.NEXT_PUBLIC_DRUPAL_BASE_URL}${article.field_image.field_media_image.uri.url}`}
  alt={article.field_image.field_media_image.resourceIdObjMeta.alt || ""}
  width={article.field_image.field_media_image.resourceIdObjMeta.width}
  height={article.field_image.field_media_image.resourceIdObjMeta.height}
/>

Inline images in body:

// components/body.tsx
import parse, { HTMLReactParserOptions, Element } from "html-react-parser"
import Image from "next/image"

const options: HTMLReactParserOptions = {
  replace: (domNode) => {
    if (domNode instanceof Element && domNode.name === "img") {
      const { src, alt, width, height } = domNode.attribs
      return (
        <Image
          src={`${process.env.NEXT_PUBLIC_DRUPAL_BASE_URL}${src}`}
          width={parseInt(width)}
          height={parseInt(height)}
          alt={alt}
        />
      )
    }
  },
}

export function Body({ value }: { value: string }) {
  return <>{parse(value, options)}</>
}

Image derivatives (responsive images):

// Drupal image styles are accessible via JSON:API
const article = await drupal.getResource("node--article", uuid, {
  params: {
    include: "field_image.field_media_image",
  },
})

// Access image styles
const imageUrl = article.field_image.field_media_image.image_style_uri?.large

Common Mistakes

  • Not including media relationships — Image data missing. WHY: Media is a relationship, requires explicit include.
  • Missing alt text — Accessibility violation. WHY: Always provide alt from resourceIdObjMeta.alt or fallback.
  • Not configuring NEXT_IMAGE_DOMAIN — Image optimization fails. WHY: Next.js requires domain allowlist.
  • Inline images without width/height — Layout shift. WHY: Next.js Image requires dimensions for optimization.

See Also

  • Fetching Content
  • drupal-jsonapi.md (for includes syntax)
  • Performance Optimization