Alex
Alex

Reputation: 101

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:

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

Upvotes: 4

Views: 6090

Answers (3)

Abdelouahed EL HARIRI
Abdelouahed EL HARIRI

Reputation: 305

What worked in my case is :

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

import Spinner from "@/public/spinner.glb"

export default function Model () {
    const glb = useGLTF(Spinner.src)
    return (
            <primitive object={model.scene} />
    )
}

Upvotes: -1

Atang Motloli
Atang Motloli

Reputation: 39

In nextJS you don't need to use the suspense component. Use the useTexture hook from @react-three/drei instead of loading using useLoader.

This example code loads the model with texture.

import React from "react";
import { useTexture } from "@react-three/drei";

function Box() {
    const colorMap = useTexture("/img/robot.png");
    return (
        <mesh rotation={[90, 0, 20]}>
            <boxBufferGeometry attach="geometry" args={[2, 2, 2]} />
            <meshNormalMaterial attach="material" />
        </mesh>
    );
}

export default Box;

Upvotes: 0

grzehu
grzehu

Reputation: 156

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.

Upvotes: 10

Related Questions