Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Load GLTF model in next.js / Error: Could not load <url> response.body.getReader is not a function

How to load a model GLTF model in next.js?

I spend hours looking for this. Nothing works :(


What I tried so far:

  • use different loaders ( useLoader(GLTFLoader,url) / useGLTF(url) and some more
  • wrap the component in a next/dynamic component / dont do it
  • solve the errors related to suspense not beeing support by installing next with react 18
  • tried this starter template
  • use three-stdlib
  • tried to write a custom loader in next.config.js

read every issue and forum post i could find on tis issue


The error i get at the moment is:

Server Error
Error: Could not load  <url> response.body.getReader is not a function

with a component looking like this:

import React from 'react'
import { useGLTF } from '@react-three/drei'
import { Canvas, } from '@react-three/fiber'
import { Suspense } from 'react/cjs/react.production.min';

export default function Spinner({ ...props }) {
  const model = useGLTF("http://localhost:3000/spinner.glb")
  return (
    <Suspense fallback={"loading"}>
      <Canvas
        camera={{ position: [1, 1, 1] }}
      >
        <primitive object={model.scene} />
        <color attach="background" args={["hotpink"]} />
      </Canvas>
    </Suspense>
  )
}

package.json:

  },
  "dependencies": {
    "@react-three/drei": "^7.27.3",
    "@react-three/fiber": "^7.0.21",
    "axios": "^0.24.0",
    "next": "^12.0.7",
    "react": "^18.0.0-beta-24dd07bd2-20211208",
    "react-dom": "^18.0.0-beta-24dd07bd2-20211208",
    "three": "^0.135.0",
    "three-stdlib": "^2.6.1"
  },
  "devDependencies": {
    "eslint": "8.4.1",
    "eslint-config-next": "12.0.7",
    "file-loader": "^6.2.0"
  }
}

node-version:

16 LTS
like image 373
Alex Avatar asked Sep 07 '25 13:09

Alex


1 Answers

Wrapping your Model component with the parent and using lazy import solves the issue, e.g.

Model component

import React from 'react'
import { useGLTF } from '@react-three/drei'

export default function Model() {
  const model = useGLTF("http://localhost:3000/spinner.glb")
  return (
     <primitive object={model.scene} />
  )
}

Scene component with lazy() import

import { lazy, Suspense } from 'react'
import { Canvas, } from '@react-three/fiber'

const ModelComponent = lazy(() => import("./model"));

export default function Spinner({ ...props }) {
  return (
    <Suspense fallback={"loading"}>
      <Canvas
        camera={{ position: [1, 1, 1] }}
      >
        <ModelComponent />
        <color attach="background" args={["hotpink"]} />
      </Canvas>
    </Suspense>
  )
}

This seems to be related to SSR. Similar problems are with TextureLoaders in Next and was having similar hard time to fix it and eventually found that solution with lazy() import. I had just tried that for the model load and it works fine. Can't track this original thread right now, but will try to track and add it here.

like image 95
obenda Avatar answered Sep 10 '25 03:09

obenda