Skip to content

Extend

Import

import { extend } from '@react-three/fiber'

Description

When trying to reference libraries within the Canvas JSX, that are not part of @react-three/fiber or @react-three/drei, you may encounter an error similar to,

Uncaught Error: R3F: [Import] is not part of the THREE namespace! Did you forget to extend?

We can use the extend function from @react-three/fiber to add it to the JSX catalog.

For example, instead of using the @react-three/drei OrbitControls,

import { OrbitControls } from '@react-three/drei'

you may want to try the Official Threejs OrbitControls,

import { OrbitControls } from 'three/addons/controls/OrbitControls.js'

or the pmndrs/three-stlib OrbitControls.

import { OrbitControls } from 'three-stdlib'

Either way, the last two, are not part of the JSX catalog when using them in your R3F application.

So, we need to extend them after importing.

E.g.,

import { OrbitControls } from 'three/addons/controls/OrbitControls.js'
extend({ OrbitControls })

or

import { OrbitControls } from 'three-stdlib'
extend({ OrbitControls })

You will then be able to use it in your JSX, but note the lowercase first letter (camelCase).

<orbitControls />

Now with the OrbitControls in particular, it needs some defaults. Many library imports may require them. You will need to check your imported libraries official documentation for this.

In the case of OrbitControls, the constructor will need to know about the existing camera and renderers domElement.

This can be verified by checking the official Threejs OrbitControls → Constructor documentation.

In R3F, we can use useThree to get access to the existing camera and renderers domElement.

import { extend, useThree } from '@react-three/fiber'

Create a custom component. Controls may be a good name.

function Controls() {
  const {
    camera,
    gl: { domElement },
  } = useThree()

  return <orbitControls args={[camera, domElement]} />
}

And use it in your application somewhere.

function App() {
  return (
    <Canvas camera={{ position: [0, 0, 3] }}>
      <Polygon />
      <Controls />
    </Canvas>
  )
}

Working Examples

OrbitControls from three/addons

<>

OrbitControls from three-stdlib

<>

three/addons alias

addons is an alias for the folder examples/jsm. Not all development environments support aliases, so in that case, you can use,

import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'

instead of

import { OrbitControls } from 'three/addons/controls/OrbitControls.js'
Extend docs.pmnd.rs
OrbitControls (three/addons) sbedit.net
OrbitControls (three-stdlib) sbedit.net
Orbit Controls threejs.org

Comments