No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Image API: configurando nuestro propio loader avanzado

7/19
Recursos

Comando: git checkout -b dev 3-image-loader

Aportes 4

Preguntas 2

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

o inicia sesión.

Tener en cuenta que la API de contentful sólo soporta tamaños menores a 4000. Si el height o el width superan ese valor salta un error y no se renderiza la imágen.

No tengo ni puta idea de como integrar el API de contentfull a NextJs

En calcAspectRatio estamos diciendo a aspectRatio que puede ser una de las siguientes opciones: ‘1:1’ | ‘4:3’ | ‘16:9’ y a width que sea number, esto esta bien sin embargo si aspectRatio cambia de ImageProps tendriamos que tambien cambiar el de la funcion una forma de que siempre se mantenga actualizado los tipos

type ImageProps = {
  layout: 'responsive' | 'intrinsic'
  src: string
  width: number
  height?: never
  aspectRatio: '1:1' | '4:3' | '16:9'
  fit?: 'pad' | 'fill' | 'cropt'
}

const calcAspectRatio = (
  aspectRatio: ImageProps['aspectRatio'],
  width: ImageProps['width']
) => {}

Este es mi componente Image con algunas mejoras en el tipado

// components/Image.tsx

import { FC } from 'react'
import NextImage, { ImageLoader } from 'next/image'

type AspectRatio = '1:1' | '4:3' | '16:9'

const aspectRatioToRatio: { [key in AspectRatio]: number } = {
  '1:1': 1,
  '4:3': 3 / 4,
  '16:9': 9 / 16,
}

function calcAspectRatio(aspectRatio: AspectRatio, width: number): number {
  const ratio = aspectRatioToRatio[aspectRatio]
  return Math.floor(width * ratio)
}

type ImageProps = {
  layout: 'fill' | 'fixed' | 'intrinsic' | 'responsive' | undefined
  src: string
  width: number
  height?: never
  aspectRatio: AspectRatio
  fit?: 'pad' | 'fill' | 'crop' | 'scale'
}

const Image: FC<ImageProps> = ({
  layout,
  src,
  width,
  aspectRatio,
  fit = 'scale',
}) => {
  const height = calcAspectRatio(aspectRatio, width)

  const loader: ImageLoader = (args) => {
    const loaderHeight = calcAspectRatio(aspectRatio, args.width)
    return `${args.src}?w=${width}&h=${loaderHeight}&fit=${fit}`
  }

  return <NextImage {...{ layout, src, width, height, loader }} unoptimized />
}

export default Image