Image Optimization of Remote Images from External CMS

Hi all,

How is everyone handling image optimization of images that are stored in an external headless CMS.

My project is in headless-api mode and it is deployed via webhooks to Netlify as a Next.js app. I am fetching a list of blog posts from the CMS via the GraphQL Data Fetcher component. Each blog post card contains a plasmic image component which takes the source url of the primary image of each post entry.

Currently the images end up being loaded directly from the external CMS instead of going through Plasmic’s image optimization pipeline. I am a developer but I would like it for designers I work with to be able to drive most of the frontend work from within Plasmic Studio using the headless-api mode instead of codegen.

Here are some solutions I can think of (not sure which is best):

  1. Override the Plasmic Image component with the Next.js’s <Image /> component from my codebase.
  2. Create a custom image code-component which wraps the Next.js <Image /> component and instruct my designers to use this component when authoring dynamic, repeated components like the Blog Card.
  3. Do the image optimization on the CMS side. (However, my current CMS setup doesn’t have the ability to build responsive images on-demand and at the ‘edge’ nor does it automatically convert images to webP format. Maybe I can proxy my CMS instance with Cloudflare or integrate it with another CDN service.

The ideal solution for me would be able to access Next.js’ built-in image optimization paired with hosting platforms like Vercel or Netlify like I usually do when I build sites purely from code while still giving my designer the power of building in Plasmic Studio.

Thoughts anyone?

1 Like

Hi @john_zambrano , external images are not optimized, so the best solution in this case is indeed to use your own image component.

Your component can wrap the next image component, and you can also optionally add custom UI controls for more easily picking images from your source CMS: Custom prop controls for code components | Learn Plasmic

Note that Next Image needs you to provide the width, but maybe this is available from your CMS - so that’s another thing your image wrapper can encapsulate.

Let me know if that helps.

2 Likes

Thanks @yang,

It worked like a charm. Super powerful feature. I like how the Plasmic Studio UI infers that the custom Next Image component is fundamentally a HTML <img/> element and shows the appropriate html attributes Image size, X-align and Y-align. The Fallback fields are a nice touch as well!

All I had to do in code was create the wrapper NextImage component:

import Image, { ImageProps } from "next/image";
import React from "react";

const NextImage = ({ src, alt, ...rest }: ImageProps) => {
	return <Image alt={alt} src={src} {...rest} />;
};

export default NextImage;

Then register the component (as described in the docs):

PLASMIC.registerComponent(NextImage, {
	name: "NextImage",
	props: {
		src: "imageUrl",
		alt: "string",
		width: "number",
		height: "number",
		sizes: "string",
		fill: "boolean",
		priority: "boolean",
	},
});

Which results in this nice UI in the Plasmic Studio:

Hats off to you and your team! :+1:

1 Like