reactjsnext.jsserver-side-renderingreact-particles-js

Is it in any way possible to use tsparticles with next.js and ssr?


I am building a customer center for my agency and for performance reasons we rely on ssr. I would really like to implement tsparticles, but after what i think is the correct way to set this up, i get this error:

Server Error
Error: Class extends value undefined is not a constructor or null

This might be caused by a React Class Component being rendered in a Server Component, React Class Components only works in Client Components. Read more: https://nextjs.org/docs/messages/class-component-in-server-component

The docs say "Warning: This file must be built for client side usage, SSR is not supported." somewhere in between different framework / library setups, so i don't really know what exactly this applies to.

Here are my files:

ParticlesBackrgound.js:

import Particles from "react-tsparticles";
import particlesConfig from "./config/particles-config";

const ParticlesBackground = () => {
    retun (
        <Particles params={particlesConfig}>

        </Particles>
    )
}

export default ParticlesBackground

particles-config.js:
const particlesConfig = {
    /* coniguraitons */
  }
 
export default particlesConfig

page.jsx:

import Link from 'next/link';
import Image from 'next/image'

import ParticlesBackground from 'src/app/ParticlesBackground.js';

export default function LandingPage() {
  return (
    <main id="landing-page-wrapper">

      <ParticlesBackground/>

      <h2>
        Customer Center
      </h2>

      <div id="login">
        <button className="strong-hover-shake">Login</button>
      </div>

    </main>
  )
}

I also tried to use transpile inside the next.config.js as i saw it in another issue, but that did not change anything

/** @type {import('next').NextConfig} */
const nextConfig = {}

module.exports = nextConfig

module.exports = {
    transpilePackages: ['tsparticles'],
    /* Your Next.js config */
};


Solution

  •  "Warning: This file must be built for client side usage, SSR is not supported."
    

    As per the above warning, it clearly tells that library doesn't supports Server-side rendering. If you read here on library tsParticles : Its compatible with React.js, NextJS not mentioned.

    This library is browser based, you need browser to render it.

    https://particles.js.org/docs/index.html

    If you read here react-tsparticles is official tsParticles ReactJS component. https://github.com/tsparticles/react#readme

    Here is a example code I made by using official documentations :

    https://www.npmjs.com/package/react-tsparticles#options-object

    https://github.com/tsparticles/react#readme

    Folder Structure :

    projectName
    ├── .gitignore
    ├── jsconfig.json
    ├── next.config.js
    ├── package-lock.json
    ├── package.json
    ├── postcss.config.js
    ├── public
    │   ├── images
    │   ├── next.svg
    │   └── vercel.svg
    ├── README.md
    ├── src
    │   └── app
    │       ├── api
    │       ├── comp
    │       │   ├── ParticlesBackrgound.js
    │       ├── favicon.ico
    │       ├── globals.css
    │       ├── layout.js
    │       ├── page.js
    │       ├── part
    │       │   └── page.js
    └── tailwind.config.js
    

    Don't forget to install : npm i tsparticles tsparticles-slim as this will used to load loadSlim or loadFull.

    tsparticles to import loadFull & tsparticles-slim for loadSlim

    Read here about loadSlim : https://particles.js.org/docs/functions/tsParticles_Slim_Bundle.index.loadSlim.html Loads the slime bundle with all plugins needed for running the tsParticles Slim package.

    Read here about loadFull: https://particles.js.org/docs/functions/tsParticles_Full_Bundle.index.loadFull.html Loads the full bundle with all plugins needed for running the tsParticles package.

    I have made a folder part which has page.js, this page will be available on route

    http://localhost:3000/part

    This page has Particles Background.

    page.js loc\src\app\part\page.js

    import React from 'react'
    import ParticlesBackrgound from '../comp/ParticlesBackrgound'
    const page = () => {
        return (
            <ParticlesBackrgound>
                <h1>Page with particles background !</h1>
                <div>
                    Lorem ipsum dolor, sit amet consectetur adipisicing elit. Velit, debitis nostrum est et impedit consequatur id quod autem a omnis unde ipsum, odio sunt nesciunt officia aliquam. Officiis atque ipsa corrupti qui similique distinctio in repellendus sequi libero cum assumenda, earum hic odio, quo laudantium. Nulla doloribus tempore sint amet.
                </div>
            </ParticlesBackrgound>
        )
    }
    
    export default page
    

    layout.js :

    <html lang="en">
      <body className={inter.className}>
        <ParticlesBackrgound>
          {children}
        </ParticlesBackrgound>
      </body>
    </html >
    

    ParticlesBackrgound.js

    Don't forget to add your particles config, by using prop options. options = {your config}

    'use client'
    import React, { useCallback } from 'react'
    import Particles from "react-tsparticles";
    import { loadFull } from "tsparticles";
    import { loadSlim } from "tsparticles-slim";
    
    
    const ParticlesBackrgound = ({ children }) => {
        const particlesInit = useCallback(async engine => {
            console.log(engine);
            await loadSlim(engine);
    
            // LOAD ANY ONE 
            // await loadFull(engine);
        }, []);
    
        const particlesLoaded = useCallback(async container => {
            await console.log(container);
        }, []);
    
    
        return (
    
            <>
    
                <Particles
                    id="tsparticles"
                    init={particlesInit}
                    loaded={particlesLoaded}
    
                    options={your config}
    
                />
                {children}
            </>
    
    
    
        )
    }
    
    export default ParticlesBackrgound
    

    Don't forget to add this under in your particlesConfig :

    fullScreen: {
        enable: true,
        zIndex: -1
    
        // IMPORTANT
    },
    

    Particles Config : I have passed this options directly (options ={below code}), you may make necessary changes wherever required.

    {
        fullScreen: {
            enable: true,
            zIndex: -1
            // IMPORTANT
        },
        background: {
            color: {
                value: "#0d47a1",
            },
        },
        fpsLimit: 120,
        interactivity: {
            events: {
                onClick: {
                    enable: true,
                    mode: "push",
                },
                onHover: {
                    enable: true,
                    mode: "repulse",
                },
                resize: true,
            },
            modes: {
                push: {
                    quantity: 4,
                },
                repulse: {
                    distance: 200,
                    duration: 0.4,
                },
            },
        },
        particles: {
            color: {
                value: "#ffffff",
            },
            links: {
                color: "#ffffff",
                distance: 150,
                enable: true,
                opacity: 0.5,
                width: 1,
            },
            move: {
                direction: "none",
                enable: true,
                outModes: {
                    default: "bounce",
                },
                random: false,
                speed: 6,
                straight: false,
            },
            number: {
                density: {
                    enable: true,
                    area: 800,
                },
                value: 80,
            },
            opacity: {
                value: 0.5,
            },
            shape: {
                type: "circle",
            },
            size: {
                value: { min: 1, max: 5 },
            },
        },
        detectRetina: true,
    }
    

    Read More at : https://particles.js.org/docs/classes/tsParticles_Engine.Options_Classes_Options.Options.html