I am working on a nextJS/Strapi online store and I want to use the react-responsive-carousel I followed all the steps on [ https://www.npmjs.com/package/react-responsive-carousel ].
(I am working on localhost)
The Carousel works fine on the desktop using the dynamic images from Strapi API (Single type collection) but the images don't show on my phone when I try to access the localhost from there. All other images from Strapi work just fine except the ones inside the Carousel.
Carousel code:
import { imgToUrl } from "../../utils/urls";
import { Carousel } from "react-responsive-carousel";
const index = ({ data }) => {
const images = data.slider.map((slide) => imgToUrl(slide.image)); //imgToUrl is a function that takes the image URL and concatinate it with HTTP://localhost:1337/
return (
<>
<Carousel
autoPlay={true}
emulateTouch={true}
infiniteLoop={true}
showThumbs={false}
width="100%"
>
{images.map((image) => (
<div className="h-full w-full">
<img className="w-full h-full" src={image} />
{/* <p className="legend">Legend 1</p> */}
</div>
))}
</Carousel>
</>
);
};
export default index;
imgToUrl Code:
export const API_URL =
process.env.NEXT_PUBLIC_API_URL || "http://localhost:1337";
/**
*
* @param {any} image
*
*/
export const imgToUrl = (image) => {
if (!image) {
return "/Products/3.jpg"; //default image when there is not image uploaded
}
if (image.url.indexOf("/") === 0) {
return `${API_URL}${image.url}`; // Concatinates http://localhost:1337 with the image url
}
return image.url;
};
Output of imToUrl :
http://localhost:1337/uploads/banner_3_d93516ad90.jpg
I would appreciate any help. Thank you.
I am also using Strapi "headless" CMS as my backend and GraphQL API to retrieve data from frontend, and below is how I have currently implemented my "Strapi Media" Image component:
frontend/utils/media.js
export function getStrapiMedia(url) {
if (url == null) {
return null
}
// Return the full URL if the media is hosted on an external provider
if (url.startsWith("http") || url.startsWith("//")) {
return url
}
// Otherwise prepend the URL path with the Strapi URL
return `${
process.env.NEXT_PUBLIC_STRAPI_API_URL || "http://localhost:1337"
}${url}`
}
frontend/utils/types.js
import PropTypes from 'prop-types'
export const linkPropTypes = PropTypes.shape({
id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
url: PropTypes.string.isRequired,
text: PropTypes.string.isRequired,
newTab: PropTypes.bool,
})
export const mediaPropTypes = PropTypes.shape({
id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
alternativeText: PropTypes.string,
mime: PropTypes.string.isRequired,
url: PropTypes.string.isRequired,
})
export const buttonLinkPropTypes = PropTypes.shape({
theme: PropTypes.string,
text: PropTypes.string.isRequired,
newTab: PropTypes.bool,
})
frontend/components/elements/image.js
import { getStrapiMedia } from "utils/media"
import Image from "next/image"
import PropTypes from "prop-types"
import { mediaPropTypes } from "utils/types"
const NextImage = ({ media, ...props }) => {
const { url, alternativeText } = media
const loader = ({ src }) => {
return getStrapiMedia(src)
}
// The image has a fixed width and height
if (props.width && props.height) {
return (
<Image loader={loader} src={url} alt={alternativeText || ""} {...props} />
)
}
// The image is responsive
return (
<Image
loader={loader}
layout="responsive"
width={media.width}
height={media.height}
objectFit="contain"
src={url}
alt={alternativeText || ""}
/>
)
}
Image.propTypes = {
media: mediaPropTypes.isRequired,
className: PropTypes.string,
}
export default NextImage
And below is an example use case from another component's context:
...
import NextImage from "./image"
...
<div className="flex flex-row items-center">
<Link href="/">
<a className="h-8 w-32">
<NextImage layout="fill" className="image" media={navbar.logo} />
</a>
</Link>
</div>
...
I hope this helps - let me know if you could use further source share here.
I am just learning the Strapi Framework myself, opting to bootstrap my software engineering portfolio, profile, and blog site from Strapi Next Corporate Starter. Are you also using a Strapi bootstrapped project, or custom using their SDK?
While working on my own custom Carousel I also discovered that if you are implementing your custom component as a section component, you will need to add the import statement and array member to the Strapi defaults in:
frontend/components/sections.js
Example from my use case:
...
import CardCarouselGroup from "@/components/sections/card-carousel-group";
...
// Map Strapi sections to section components
const sectionComponents = {
"sections.hero": Hero,
"sections.large-video": LargeVideo,
"sections.feature-columns-group": FeatureColumnsGroup,
...
"sections.card-carousel-group": CardCarouselGroup
}
...