Nextjs and Threejs fiber url problem

I’m a bit at a loss here: I can get an utah teapot obj file to render, with light and everything, but I get an mysterious error which annoyingly means that vercel won’t accept it. I’m new with both nextjs and threejs (but not with opengl), so the problem might very well be between the chair and the keyboard :slight_smile:

Here is the error (redacted some of the lines because they have my file structure :slight_smile: ):

✓ Compiled in 115ms (1412 modules)
 ⚠ Fast Refresh had to perform a full reload due to a runtime error.
 ⨯ TypeError: Failed to parse URL from ./teapot.obj
    at Render (./app/render.tsx:34:12)
Cause: TypeError [ERR_INVALID_URL]: Invalid URL
    at new NodeError (node:internal/errors:387:5)
    at URL.onParseError (node:internal/url:565:9)
    at new URL (node:internal/url:641:5)
    at new Request ([...]/node_modules/next/dist/compiled/undici/index.js:2:43743)
    at new <anonymous> ([...]/node-polyfill-fetch.js:11:17)
    at FileLoader.load (webpack-internal:///(ssr)/./node_modules/three/build/three.module.js:42422:15)
    at OBJLoader.load (webpack-internal:///(ssr)/./node_modules/three/examples/jsm/loaders/OBJLoader.js:444:10)
    at Render (webpack-internal:///(ssr)/./app/render.tsx:34:12)
    at oX [...]
  input: './teapot.obj',
  code: 'ERR_INVALID_URL'
}

I use the following imports:

import { Canvas, useLoader } from "@react-three/fiber";
import { OBJLoader } from "three/examples/jsm/loaders/OBJLoader";

it fails immediately upon the line

const obj = useLoader(OBJLoader, /teapot.obj);

teapot.obj is located in my public folder

I also tried to add an env variable pointing to localhost changing that line to:

const obj = useLoader(OBJLoader, ${process.env.NEXT_PUBLIC_BASE_URL}/teapot.obj);

but then I get the following error:

ReferenceError: ProgressEvent is not defined
    at eval (webpack-internal:///(ssr)/./node_modules/three/build/three.module.js:42483:25)
 ⨯ node_modules/three/build/three.module.js (42072:0) @ eval
 ⨯ unhandledRejection: ReferenceError: ProgressEvent is not defined
    at eval (webpack-internal:///(ssr)/./node_modules/three/build/three.module.js:42483:25)
null
 ⨯ node_modules/three/build/three.module.js (42072:0) @ eval
 ⨯ unhandledRejection: ReferenceError: ProgressEvent is not defined
    at eval (webpack-internal:///(ssr)/./node_modules/three/build/three.module.js:42483:25)
null

I have no idea how to continue from here. Any suggestions?

not familiar with obj loader but does it perhaps try to access external files? otherwise try to access the public file in the browser url bar, if you can’t get it something is off: typo, wrong file, file isn’t there, …

I don’t know how clear this was from my original post but: when only using /teapot.obj (without using the base url env), utah teapot is rendered successfully! My problem is the first error which makes the pipeline in vercel fail. I might be wrong, but I think that it is a clear indication that the file both exists and works.

The error is visible both in the pipeline and locally.

Visiting localhost:3000/teapot.obj in the browser downloads the file perfectly.

Also for clarification: currently process.env.NEXT_PUBLIC_BASE_URL is set to “localhost:3000”.
console log also confirms that it is properly set. Nextjs shouldn’t need this however!

Next.Js tries to build most of the components on the server by default, where there’s no WebGL imlementation. Have you tried to set your component as a client component (by writing ‘use client’ on top of the file)?

Yes, I do use ‘use client’ :slight_smile:

But you are right in that it’s a good first thing to try!

In the React-Three/Next starter project, the components that render GLTF objects are lazily loaded: https://github.com/pmndrs/react-three-next/blob/fbb4c12db8eaf07440b62344fc54207e603e98e8/app/page.jsx#L7

I don’t know if it’s mandatory, but that might be a hint.

1 Like