I’m using the react-p5
library for generating PerlinNoise wave animation in my about
page.
When I use the p5
on any page it returns a 404 page, but if click back to the home page and open about.js
using the link it will work. After refresh, it won’t work.
Everything works if I remove the p5
component from the file. I think the problem is with the p5
or p5 import
.
about.js
import React from 'react' // Importing Sketch import Sketch from 'react-p5' export default function about() { // Setup for creating canvas const setup = (p5, canvasParentRef) => { p5.createCanvas(p5.windowWidth, 100).parent(canvasParentRef) } let inc = 0.005; let start = 0; // Function to draw the wave const draw = p5 => { p5.background('rgba(255,255,255)') p5.stroke('rgb(0,0,0)'); p5.noFill(); p5.beginShape(); let xoff = start; for (let x = 0; x < p5.width; x++) { p5.stroke('#000'); let y = p5.noise(xoff) * p5.height; p5.vertex(x, y); xoff += inc; } p5.endShape(); start += inc; } return ( <> // Returning Sketch Component <Sketch setup={setup} draw={draw} /> </> ) }
Project Structure :
Advertisement
Answer
The problem is that Sketch component is wanting to access window
property, but window is undefined since we serve server side rendered About page.
How to get around this?
Best solution would be to create a separated component, we can call it DrawSketch
DrawSketch component is almost identical to your About page with exception that it is a component.
import React from "react"; import Sketch from "react-p5"; export default function DrawSketch() { const setup = (p5, canvasParentRef) => { p5.createCanvas(p5.windowWidth, 100).parent(canvasParentRef); }; let inc = 0.005; let start = 0; // Function to draw the wave const draw = (p5) => { p5.background("rgba(255,255,255)"); p5.stroke("rgb(0,0,0)"); p5.noFill(); p5.beginShape(); let xoff = start; for (let x = 0; x < p5.width; x++) { p5.stroke("#000"); let y = p5.noise(xoff) * p5.height; p5.vertex(x, y); xoff += inc; } p5.endShape(); start += inc; }; return <Sketch setup={setup} draw={draw} />; }
Next thing we want is to make sure that we will client side server our DrawSketch component, so it can has access to window
property.
In next.js you can use dynamic imports
Next.js supports ES2020 dynamic import() for JavaScript. With it you can import JavaScript modules dynamically and work with them. They also work with SSR.
Next step would be importing DrawSketch component we created inside your About view and declare it as dynamic component which is not server side rendered
.
import React from "react"; import dynamic from "next/dynamic"; const ClientSideSketch = dynamic(() => import("../components/DrawSketch"), { ssr: false }); export default function AboutPage() { return ( <> <ClientSideSketch /> </> ); }
I have edited codesandbox, so you can see working live example.