using Three.js in Nextjs 14 – ReferenceError: document is not defined

I know this specific error has been asked here multiple times but i think this situation is unique enough to deserve its own post.

So i Just started thinkering with three.js in nextjs 14.
Everything seems to work perfectly locally but i still see the following error:
ReferenceError: document is not defined

I think there’s a point in here somewhere that uses the document to early to create the canvas i think but i haven’t located it yet as i suppose it will be in the threejs code itself.

Anyone here done something similar like this and knows where this issue get triggered?

"use client";
export const dynamic = "auto";
import { ISSPosition, fetchISSPosition } from "@/lib/api";
import { convertCoordsToSphere } from "@/lib/functions";
import React, { useRef, useEffect, useState } from "react";
import * as THREE from "three";

const earthRadius = 10;
const scene = new THREE.Scene();

// Fog setup
...

// Camera and renderer setup
...

const renderer = new THREE.WebGLRenderer({
  alpha: true,
  antialias: true,
});

// Lighting setup
...

// Earth model setup
const geometry = new THREE.SphereGeometry(earthRadius, 64, 64);
const earthMat = new THREE.MeshPhongMaterial({
  shininess: 350,
  map: new THREE.TextureLoader().load("/earth_texture.jpg"),
  bumpMap: new THREE.TextureLoader().load("/earth_texture.jpg"),
});
const earth = new THREE.Mesh(geometry, earthMat);
earth.receiveShadow = true;
earth.rotation.x = 0.3;
scene.add(earth); // Add Earth to the scene upfront

// ISS model setup
...

const animate = () => {
  requestAnimationFrame(animate);
  earth.rotation.y -= 0.001;

  renderer?.render(scene, camera);
};

const ThreeScene = () => {
  const [issPosition, setIssPosition] = useState<ISSPosition>();
  const containerRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    const fetchISSData = async () => {
      setIssPosition(await fetchISSPosition());
    };

    const intervalId = setInterval(fetchISSData, 5000);

    if (typeof window !== "undefined") {
      containerRef.current?.appendChild(renderer.domElement);
    }

    animate();

    const handleResize = () => {
      if (renderer) {
        let size =
          window.innerWidth * 0.8 > 800 ? 800 : window.innerWidth * 0.8;
        renderer.setSize(size, size);
      }
    };

    handleResize();
    window.addEventListener("resize", handleResize);

    return () => {
      clearInterval(intervalId);
    };
  }, []);

  useEffect(() => {
    const animate = () => {
      requestAnimationFrame(animate);

      if (issPosition) {
        const pointCoords = convertCoordsToSphere(
          Number(issPosition.iss_position.latitude),
          -Number(issPosition.iss_position.longitude),
          earthRadius
        );

        issPoint.position.copy(pointCoords.applyMatrix4(earth.matrix));
        scene.add(issPoint);
      }

      renderer.render(scene, camera);
    };

    animate();
  }, [issPosition]);

  return (
    typeof window !== "undefined" && (
      <>
        <div className="m-auto max-w-fit" ref={containerRef}></div>
        {issPosition ? (
          <div className="flex flex-col gap-2 mb-8 w-fit justify-center items-center mx-auto">
            <span>Latitude: {issPosition?.iss_position.latitude}</span>
            <span>Longitude: {issPosition?.iss_position.longitude}</span>
          </div>
        ) : (
          <div className="flex gap-4 justify-center">
            <p className="mb-4">Locating ISS</p>
            <i className="border-b- border-primary w-4 h-4 rounded-full animate-spin"></i>
          </div>
        )}
      </>
    )
  );
};

export default ThreeScene;