Skip to content

Instantly share code, notes, and snippets.

@treckstar
Last active April 6, 2023 18:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save treckstar/6005fc23a77e2e0f3f22bdf9e6ab75ef to your computer and use it in GitHub Desktop.
Save treckstar/6005fc23a77e2e0f3f22bdf9e6ab75ef to your computer and use it in GitHub Desktop.
Class based next/image loader for Contentful
import React from "react";
import { Image, ImageProps } from "next/image";
import { createClient } from "contentful";
type ContentfulImage = {
fields: {
file: {
url: string;
details: {
image: {
width: number;
height: number;
};
};
};
};
};
type ImageLoaderProps = Omit<ImageProps, "src"> & {
src: string;
};
class ContentfulImageLoader extends React.Component<ImageLoaderProps> {
private client = createClient({
space: process.env.CONTENTFUL_SPACE_ID || "",
accessToken: process.env.CONTENTFUL_ACCESS_TOKEN || "",
});
private async getContentfulImage(): Promise<ContentfulImage | null> {
const { src } = this.props;
try {
const [entry] = await this.client.getEntries({
content_type: "image",
"fields.file.url": src,
});
return entry?.fields as ContentfulImage;
} catch (error) {
console.error(`Error fetching Contentful image: ${error.message}`);
return null;
}
}
public async loader({ src, width, quality }: ImageLoaderProps): Promise<string> {
const contentfulImage = await this.getContentfulImage();
if (!contentfulImage) {
throw new Error(`Contentful image not found: ${src}`);
}
const imageURL = `${contentfulImage.fields.file.url}?w=${width}&q=${quality || 75}`;
return imageURL;
}
public render(): JSX.Element {
const { src, ...props } = this.props;
return <Image loader={this.loader} src={src} {...props} />;
}
}
export default ContentfulImageLoader;
import ContentfulImageLoader from "./ContentfulImageLoader";
const MyComponent = () => {
return (
<div>
<h1>My Contentful Images</h1>
<ContentfulImageLoader src="https://images.ctfassets.net/123abc456def/my-image.jpg" alt="My Image" width={800} height={600} />
</div>
);
};
export default MyComponent;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment