How to use Three.js inside Gatsby?

I’ve installed react-three-fiber and three packages. I’m following this tutorial, but I have doubts of where to put this line:

const rootElement = document.getElementById("root");

Also, I’m starting to receive this error:

Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.

My index.js:

import React, { Children, useRef, useState } from "react"

import {  Link } from "gatsby"

import { Canvas} from 'react-three-fiber'

import Layout from "../components/layout"

const IndexPage = () => {

  return(

    <Layout>

      <div>

        <h1>Hi</h1>

      </div>

      <canvas>

        <Children></Children>

      </canvas>

    </Layout>

    )

}

const rootElement = document.getElementById("root");

export default IndexPage

Any ideas?

Hey! You don’t need to use

const rootElement = document.getElementById(“root”);

You can just leave it out and render your canvas component wherever you want. As an example, I have…

function Box(props) {
    // This reference will give us direct access to the mesh
    const mesh = useRef()
  
    // Set up state for the hovered and active state
    const [hovered, setHover] = useState(false)
    const [active, setActive] = useState(false)
  
    // Rotate mesh every frame, this is outside of React without overhead
    useFrame(() => (mesh.current.rotation.x = mesh.current.rotation.y += 0.01))
  
    return (
      <mesh
        {...props}
        ref={mesh}
        scale={active ? [1.5, 1.5, 1.5] : [1, 1, 1]}
        onClick={(e) => setActive(!active)}
        onPointerOver={(e) => setHover(true)}
        onPointerOut={(e) => setHover(false)}>
        <boxBufferGeometry attach="geometry" args={[1, 1, 1]} />
        <meshStandardMaterial attach="material" color={hovered ? 'hotpink' : 'orange'} />
      </mesh>
    )
  }

and i’m using it like so

render() {
    return (
        <Canvas>
            <ambientLight />
            <pointLight position={[10, 10, 10]} />
            <Box position={[-1.2, 0, 0]} />
            <Box position={[1.2, 0, 0]} />
        </Canvas>
    )
  }

and it’s rendering fine!

1 Like