Skip to content

Commit 0e2a9a8

Browse files
committed
🔧 fix ssr
1 parent d3e621e commit 0e2a9a8

File tree

2 files changed

+70
-64
lines changed

2 files changed

+70
-64
lines changed

build-index-html.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { App } from "./src/App/App";
55

66
console.log("📸 rendering loading screen to string...");
77

8-
const appContent = renderToString(React.createElement(App, { loading: true }));
8+
const appContent = renderToString(React.createElement(App));
99

1010
console.log("🖊 replacing content in index.html...");
1111

src/App/App.tsx

Lines changed: 69 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,13 @@ const xr8ApiKey: string | undefined = import.meta.env.VITE_XR8_API_KEY;
2525
const touchSupported =
2626
typeof document !== "undefined" && "ontouchend" in document;
2727

28-
export const App = ({ loading = false }: { loading?: boolean }) => {
28+
const useIsSSR = () => {
29+
const [isSSR, setNotSSR] = React.useReducer((_: boolean) => false, true);
30+
React.useEffect(setNotSSR, []);
31+
return isSSR;
32+
};
33+
34+
export const App = () => {
2935
let [state, setState] = React.useState<
3036
| { type: "loading" }
3137
| { type: "waiting-user-input" }
@@ -44,8 +50,8 @@ export const App = ({ loading = false }: { loading?: boolean }) => {
4450
| { type: "flat" }
4551
>({ type: "waiting-user-input" });
4652

47-
// force the state to loading
48-
if (loading) state = { type: "loading" };
53+
// force the state to be loading in SSR
54+
if (useIsSSR()) state = { type: "loading" };
4955

5056
const uiTunnel = React.useMemo(tunnel, []);
5157

@@ -100,66 +106,68 @@ export const App = ({ loading = false }: { loading?: boolean }) => {
100106

101107
return (
102108
<>
103-
<CanvasContainerPortal>
104-
<Canvas
105-
camera={{
106-
position: new THREE.Vector3(0, 6, 6),
107-
near: 0.1,
108-
far: 1000,
109-
}}
110-
shadows
111-
style={{
112-
position: "fixed",
113-
top: 0,
114-
left: 0,
115-
right: 0,
116-
bottom: 0,
117-
touchAction: "none",
118-
opacity: readyForRender ? 1 : 0,
119-
}}
120-
>
121-
{state.type === "xr8" && state.xr8 && (
122-
<XR8Controls
123-
xr8={state.xr8}
124-
onPoseFound={() => setState((s) => ({ ...s, poseFound: true }))}
125-
onCameraFeedDisplayed={() =>
126-
setState((s) => ({ ...s, cameraFeedDisplayed: true }))
109+
{state.type !== "loading" && (
110+
<CanvasContainerPortal>
111+
<Canvas
112+
camera={{
113+
position: new THREE.Vector3(0, 6, 6),
114+
near: 0.1,
115+
far: 1000,
116+
}}
117+
shadows
118+
style={{
119+
position: "fixed",
120+
top: 0,
121+
left: 0,
122+
right: 0,
123+
bottom: 0,
124+
touchAction: "none",
125+
opacity: readyForRender ? 1 : 0,
126+
}}
127+
>
128+
{state.type === "xr8" && state.xr8 && (
129+
<XR8Controls
130+
xr8={state.xr8}
131+
onPoseFound={() => setState((s) => ({ ...s, poseFound: true }))}
132+
onCameraFeedDisplayed={() =>
133+
setState((s) => ({ ...s, cameraFeedDisplayed: true }))
134+
}
135+
/>
136+
)}
137+
138+
{state.type === "webXR" && state.webXRSession && (
139+
<WebXRControls
140+
worldSize={8}
141+
webXRSession={state.webXRSession}
142+
onPoseFound={() => setState((s) => ({ ...s, poseFound: true }))}
143+
onCameraFeedDisplayed={() =>
144+
setState((s) => ({ ...s, cameraFeedDisplayed: true }))
145+
}
146+
/>
147+
)}
148+
149+
<React.Suspense fallback={null}>
150+
<Environment />
151+
152+
{
153+
/* preload the dice model */
154+
!readyForGame && (
155+
<Dice
156+
position={[999, 999, 9999]}
157+
scale={[0.0001, 0.0001, 0.0001]}
158+
/>
159+
)
127160
}
128-
/>
129-
)}
130-
131-
{state.type === "webXR" && state.webXRSession && (
132-
<WebXRControls
133-
worldSize={8}
134-
webXRSession={state.webXRSession}
135-
onPoseFound={() => setState((s) => ({ ...s, poseFound: true }))}
136-
onCameraFeedDisplayed={() =>
137-
setState((s) => ({ ...s, cameraFeedDisplayed: true }))
138-
}
139-
/>
140-
)}
141-
142-
<React.Suspense fallback={null}>
143-
<Environment />
144-
145-
{
146-
/* preload the dice model */
147-
!readyForGame && (
148-
<Dice
149-
position={[999, 999, 9999]}
150-
scale={[0.0001, 0.0001, 0.0001]}
151-
/>
152-
)
153-
}
154161

155-
{readyForGame && <Game UiPortal={uiTunnel.In} />}
156-
</React.Suspense>
162+
{readyForGame && <Game UiPortal={uiTunnel.In} />}
163+
</React.Suspense>
157164

158-
<directionalLight position={[10, 8, 6]} intensity={0} castShadow />
165+
<directionalLight position={[10, 8, 6]} intensity={0} castShadow />
159166

160-
<Ground />
161-
</Canvas>
162-
</CanvasContainerPortal>
167+
<Ground />
168+
</Canvas>
169+
</CanvasContainerPortal>
170+
)}
163171

164172
{false && <Visualizer />}
165173

@@ -197,10 +205,8 @@ export const App = ({ loading = false }: { loading?: boolean }) => {
197205
);
198206
};
199207

200-
const CanvasContainerPortal = ({ children }: { children?: any }) => {
201-
if (typeof document === "undefined") return null;
202-
return createPortal(children, document.getElementById("canvas-container")!);
203-
};
208+
const CanvasContainerPortal = ({ children }: { children?: any }) =>
209+
createPortal(children, document.getElementById("canvas-container")!);
204210

205211
const Over = ({ children }: { children?: any }) => (
206212
<div

0 commit comments

Comments
 (0)