Fix cms-kontent example Next/Image domain error (#37188)

* Fixes the following error in the `cms-kontent` example by implementing
  an `Image` component to wrap `Next/Image` with a custom loader.

```
Invalid src prop ... hostname "assets-eu-01.kc-usercontent.com" is not configured under images in your `next.config.js`
```

* This error is affecting both the `pages/index.js` and
  `pages/posts/[slug].js` routes.
* Uses a custom loader rather than adding the Kontent asset domains to
  `next.config.js` as we can transform the images using the Kontent
  Delivery API directly rather than delegating this to the Next app web
  server.

Ref:
* https://nextjs.org/docs/messages/next-image-unconfigured-host
* https://nextjs.org/docs/basic-features/image-optimization
* https://meeg.dev/blog/using-the-next-image-component-with-kentico-kontent-assets
* b7c9ef588c/components/Image.js
* https://kontent.ai/learn/reference/image-transformation/
This commit is contained in:
Tom Marshall 2022-05-25 16:40:18 +01:00 committed by GitHub
parent d9b6d99625
commit 82a9d21809
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 34 additions and 2 deletions

View file

@ -1,4 +1,4 @@
import Image from 'next/image'
import Image from '../components/image'
export default function Avatar({ name, picture }) {
return (

View file

@ -1,5 +1,5 @@
import cn from 'classnames'
import Image from 'next/image'
import Image from '../components/image'
import Link from 'next/link'
export default function CoverImage({ title, src, slug }) {

View file

@ -0,0 +1,32 @@
import NextImage from 'next/image'
import { transformImageUrl } from '@kentico/kontent-delivery'
const KONTENT_ASSET_HOSTNAME_REGEX = /.kc-usercontent.com$/
const getLoader = (src) => {
return srcIsKontentAsset(src) ? kontentImageLoader : undefined
}
const srcIsKontentAsset = (src) => {
try {
const { hostname } = new URL(src)
return KONTENT_ASSET_HOSTNAME_REGEX.test(hostname)
} catch {
return false
}
}
const kontentImageLoader = ({ src, width, quality = 100 }) => {
return new transformImageUrl(src)
.withWidth(width)
.withQuality(quality)
.withCompression('lossless')
.withAutomaticFormat()
.getUrl()
}
export default function Image(props) {
const loader = getLoader(props.src)
return <NextImage {...props} loader={loader} />
}