CesiumJS+NextJS

Hi, I am trying to define viewer ref in context provider and then reference it in other components using NextJs integration:
this is my context provider code

‘use client’;

import { IonImageryProvider, TerrainProvider, Viewer as CesiumViewer } from ‘cesium’;

import React, { createContext, useState, useRef, useContext, RefObject } from ‘react’;

import { CesiumComponentRef } from ‘resium’;

interface CesiumContextProps {viewerRef?: RefObject<CesiumComponentRef>;
}

const CesiumContext = createContext<CesiumContextProps | null>(null);

export const CesiumWrapper = ({ children }: {
children: React.ReactNode;
}) => {
const viewerRef = useRef<CesiumComponentRef>(null);
return (
<CesiumContext.Provider value={{viewerRef}}>{children}
</CesiumContext.Provider>
);
}

export const useCesiumContext = () => {
const context = useContext(CesiumContext);
return context;
}

this is my viewer page
import React, { useEffect } from ‘react’;

import { Ion, ShadowMode, CesiumTerrainProvider, IonImageryProvider, Math } from ‘cesium’;

import { ImageryLayer, Viewer } from ‘resium’

import { useCesiumContext } from ‘./context/page’;

import Tilesets from ‘./Tilesets’;

import Entities from ‘./Entities’;

// Set the default access token for Cesium ion
Ion.defaultAccessToken = process.env.NEXT_PUBLIC_CESIUM_ACCESS_TOKEN

export default function Cesium(){

const {
imageryProvider,
setImageryProvider,
terrainProvider,
setTerrainProvider,
showImagery,
tvwsModel,
buildings,
viewerRef,
setIsReady,
} = useCesiumContext();

// Set the base URL for Cesium ion
if (!Ion.defaultAccessToken) {
throw new Error(‘Ion default access token is not set.’);
}

return (
<>
<Viewer
full
ref={viewerRef}
terrainProvider={terrainProvider}
shadows={ShadowMode.ENABLED}
terrainShadows={ShadowMode.ENABLED}
timeline={false}
animation={false}
homeButton={false}
geocoder={false}
sceneModePicker={false}
navigationHelpButton={false}
baseLayerPicker={false}
vrButton={false}
infoBox={false}
selectionIndicator={false}
shouldAnimate={true}
contextOptions={{webgl: {alpha: true}}}
skyBox={false}
fullscreenButton={false}
maximumRenderTimeChange={Infinity}
>

  {showImagery && imageryProvider && <ImageryLayer show={true} alpha={0.5} imageryProvider={imageryProvider}/>}
  
  <Entities />
  <Tilesets />
</Viewer>

</>

);
}

Please what could I have done wrong it returns TypeError: viewerRef is undefined.

I think you’re getting the ref wrong. This code might work:

const [viewer, setViewer] = useState(null)

<Viewer
ref={(e) => {
setViewer(e?.cesiumElement || null);
}}
/>

Still having the same problem, I passed the viewer as props to other components,
I got TypeError viewer not defined.