skip to Main Content

I’m sure there is a quick fix, and I’m messing up somewhere, but how do I use custom elements instead of dots for pagination in Swiperjs for React?

The custom element returns an SVG from an icons array.

I originally had the code in TSX but converted it to js to make things easier, but no luck. It just keeps returning [object Object][object Object][object Object] where the pagination should be.

Here’s what I’ve got so far:

import React from "react";
// Import Swiper React components
import { Swiper, SwiperSlide } from "swiper/react";

// Import Swiper styles
import "swiper/css";
import "swiper/css/pagination";

import "./styles.css";

// import required modules
import { Pagination } from "swiper";

const icons = [
    {
        icon: (
            <svg
                width="86"
                height="87"
                viewBox="0 0 86 87"
                fill="none"
                xmlns="http://www.w3.org/2000/svg"
            >
                <rect x="0.5" y="1.125" width="75" height="75" stroke="#1A1918" />
                <rect x="10.5" y="11.125" width="75" height="75" stroke="#1A1918" />
            </svg>
        ),
    },
    {
        icon: (
            <svg
                width="91"
                height="84"
                viewBox="0 0 91 84"
                fill="none"
                xmlns="http://www.w3.org/2000/svg"
            >
                <rect x="0.5" y="1.125" width="75" height="75" stroke="#1A1918" />
                <path
                    d="M7.36379 83.25L48.5 12L89.6362 83.25H7.36379Z"
                    stroke="#1A1918"
                />
            </svg>
        ),
    },
    {
        icon: (
            <svg
                width="88"
                height="91"
                viewBox="0 0 88 91"
                fill="none"
                xmlns="http://www.w3.org/2000/svg"
            >
                <rect x="0.5" y="1.125" width="75" height="75" stroke="#1A1918" />
                <rect
                    x="8.5"
                    y="11.5"
                    width="79"
                    height="79"
                    rx="39.5"
                    stroke="#1A1918"
                />
            </svg>
        ),
    },
];

const Bullet = ({ bulletIcon, className }) => {
    return <div className={className}>{bulletIcon}</div>;
};

export default function App() {
    const pagination = {
        clickable: true,
        renderBullet: function (index, className) {
            return (
                <Bullet className={className} bulletIcon={icons[index].icon}></Bullet>
            );
        },
    };

    return (
        <>
            <Swiper
                pagination={pagination}
                modules={[Pagination]}
                className="mySwiper"
            >
                <SwiperSlide>Slide 1</SwiperSlide>
                <SwiperSlide>Slide 2</SwiperSlide>
                <SwiperSlide>Slide 3</SwiperSlide>
            </Swiper>
        </>
    );
}

Looking at the docs I can see they do this:

    renderBullet: function (index, className) {
      return '<span class="' + className + '">' + (index + 1) + "</span>";
    }

I’ve tried different variations of this but with no luck.

2

Answers


  1. This issue seem to be related to what Swiper is expecting vs what you are giving it. Instead of giving it a React Component you need to give it a string of plan HTML. You can do this with ReactDOMServers render to static HTML.

    Reference: https://github.com/nolimits4web/swiper/discussions/5295#discussioncomment-3354594

    import * as ReactDOMServer from "react-dom/server";
    
    return ReactDOMServer.renderToStaticMarkup(<Bullet className={className}>{icon}</Bullet>);```
    
    Login or Signup to reply.
  2. you are seeing [object Object] because this is what happens when you try to use toString on an object by default, the svg is a react object. I assume this is what the swipper module is doing.

    So you need it to be a html string.

    import React from "react";
    // Import Swiper React components
    import { Swiper, SwiperSlide } from "swiper/react";
    
    // Import Swiper styles
    import "swiper/css";
    import "swiper/css/pagination";
    
    import "./styles.css";
    
    // import required modules
    import { Pagination } from "swiper";
    
    const icons = [
        {
            icon: (
                `<svg
                    width="86"
                    height="87"
                    viewBox="0 0 86 87"
                    fill="none"
                    xmlns="http://www.w3.org/2000/svg"
                >
                    <rect x="0.5" y="1.125" width="75" height="75" stroke="#1A1918" />
                    <rect x="10.5" y="11.125" width="75" height="75" stroke="#1A1918" />
                </svg>`
            ),
        },
        {
            icon: (
                `<svg
                    width="91"
                    height="84"
                    viewBox="0 0 91 84"
                    fill="none"
                    xmlns="http://www.w3.org/2000/svg"
                >
                    <rect x="0.5" y="1.125" width="75" height="75" stroke="#1A1918" />
                    <path
                        d="M7.36379 83.25L48.5 12L89.6362 83.25H7.36379Z"
                        stroke="#1A1918"
                    />
                </svg>`
            ),
        },
        {
            icon: (
                `<svg
                    width="88"
                    height="91"
                    viewBox="0 0 88 91"
                    fill="none"
                    xmlns="http://www.w3.org/2000/svg"
                >
                    <rect x="0.5" y="1.125" width="75" height="75" stroke="#1A1918" />
                    <rect
                        x="8.5"
                        y="11.5"
                        width="79"
                        height="79"
                        rx="39.5"
                        stroke="#1A1918"
                    />
                </svg>`
            ),
        },
    ];
    
    export default function App() {
        const pagination = {
            clickable: true,
            renderBullet: function (index, className) {
                return `<span class=${className}>${icons[index].icon}</span>`
            },
        };
    
        return (
            <>
                <Swiper
                    pagination={pagination}
                    modules={[Pagination]}
                    className="mySwiper"
                >
                    <SwiperSlide>Slide 1</SwiperSlide>
                    <SwiperSlide>Slide 2</SwiperSlide>
                    <SwiperSlide>Slide 3</SwiperSlide>
                </Swiper>
            </>
        );
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search