@reflct/react
Overview
A React library for integrating Reflct 3D scenes into your React apps.
Visit Reflct.app for more information.
Installation
[!IMPORTANT] Compatibility with React 19
Recent releases of React 19 had compatibility issues with our dependencies. So we’ve moved those dependencies to the peer dependencies to resolve the issues. Make sure to install correct versions of peer dependencies to use this package from now on.
To install the package, run:
# Install peer dependencies
npm install three@0.168.0 @react-three/fiber @react-three/drei
# Install the package
npm install @reflct/react
or if you’re using yarn:
# Install peer dependencies
yarn add three@0.168.0 @react-three/fiber @react-three/drei
# Install the package
yarn add @reflct/react
React 18
If you’re using React 18, you need to install the following peer dependencies:
- three@0.168.0
- @react-three/fiber@8
- @react-three/drei@9
# Install peer dependencies
npm install three@0.168.0 @react-three/fiber@8 @react-three/drei@9
# Install the package
npm install @reflct/react
Getting Started
Here’s a basic example of how to use the Viewer
component:
import React from "react";
import { Viewer } from "@reflct/react";
const Page = () => {
return <Viewer id={"your-scene-id"} apikey={"your-apikey"} />;
};
export default Page;
Advanced Usage
The Viewer
component includes props for listening to events and customizing the UI:
<Viewer
id={"your-scene-id"}
apikey={"your-apikey"}
isPreview={true}
sharedMemoryForWorkers={false}
sceneRevealMode="gradual"
className={"your-class-name"}
// Event handlers
onLoadStart={() => {}}
onLoadProgressUpdate={(progress) => {}}
onLoadComplete={(viewGroups, global) => {}}
onStateChangeStart={(targetView, targetViewGroup, global) => {}}
onStateChangeComplete={(currentView, currentViewGroup, global) => {}}
onError={(error) => {}}
/>
Props
Prop | Type | Description |
---|---|---|
id | string | The unique ID of your scene |
apikey | string | Your API key |
isPreview | boolean | Use a preview version of the scene |
sceneRevealMode | string | The mode to reveal the scene. ‘gradual’ or ‘instant’ |
sharedMemoryForWorkers | boolean | Use shared memory for workers |
className | string | Custom CSS class for the viewer |
Events
Event | Type | Description |
---|---|---|
onLoadStart | () => void | Triggered when the scene starts loading |
onLoadProgressUpdate | (progress: number) => void | Updates as the scene loads |
onLoadComplete | (viewGroups, global) => void | Triggered when the scene is fully loaded |
onStateChangeStart | (targetView, targetViewGroup, global) => void | Triggered at the start of a state change |
onStateChangeComplete | (currentView, currentViewGroup, global) => void | Triggered when a state change is complete |
onError | (error: string) => void | Triggered when an error occurs |
Example: Using Events and Metadata
You can use metadata from events to update your application logic, such as state or UI:
import React from "react";
import { Viewer } from "@reflct/react";
import useProductStore from "../stores/product-store";
const Page = () => {
const extractMetadata = (viewGroups, global, key) => {
return (
viewGroups[0].views[0].metadata?.[key] ||
viewGroups[0].metadata?.[key] ||
global.metadata?.[key]
);
};
return (
<Viewer
id={sceneId}
apikey={apikey}
onLoadComplete={(viewGroups, global) => {
useProductStore.setState((state) => {
state.loading = false;
state.title = extractMetadata(viewGroups, global, "productTitle");
state.subtitle = extractMetadata(
viewGroups,
global,
"productCategory"
);
const price = extractMetadata(viewGroups, global, "price");
state.price = !isNaN(Number(price)) ? Number(price) : null;
});
}}
/>
);
};
Customizing the UI
You can pass children to customize the viewer’s UI:
<Viewer id={"your-scene-id"} apikey={"your-apikey"}>
{({
currentView,
currentViewGroup,
global,
index,
automode,
setAutomode,
isLoading,
loadProgress,
nextView,
prevView,
summaryImage,
linkedScenes,
loadScene,
}) => <div>Custom Controls</div>}
</Viewer>
Prop | Type | Description |
---|---|---|
currentView | CurrentViewMetadata | Metadata for the current view |
currentViewGroup | ViewGroupMetadata | Metadata for the current view group |
global | GlobalMetadata | Global scene metadata |
index | number | Current view index |
automode | boolean | Is auto mode enabled? |
setAutomode | function | Function to toggle auto mode |
isLoading | boolean | Is the scene loading? |
loadProgress | number | The progress of the scene loading |
nextView | function | Function to navigate to the next view |
prevView | function | Function to navigate to the previous view |
summaryImage | string or null | The summary image of the scene |
linkedScenes | array | The linked scenes of the scene |
loadScene | function | The function to load linked scene |
If you wish to customise the UI of the hitpoints, you can do that by giving the hitPoint
prop.
<Viewer
id={"your-scene-id"}
apikey={"your-apikey"}
hitPoint={(state: {
index: number,
isSelected: boolean,
inCurrentGroup: boolean,
select: () => void,
}) => <button onClick={state.select}>Hitpoint</button>}
/>
Props | Type | Description |
---|---|---|
index | number | The index of the hitpoint |
isSelected | boolean | Whether the hitpoint is selected |
inCurrentGroup | boolean | Whether the hitpoint is in the current view group |
select | function (() => void) | The function to select the hitpoint |
CORS Issues and SharedArrayBuffer
This package uses SharedArrayBuffer
by default for improved performance. However, this may cause CORS issues in browser environments.
Security Requirements
To avoid CORS issues, ensure your document operates in a secure context. Add the following headers to your server configuration:
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
For more details, refer to the MDN documentation.
Disabling SharedArrayBuffer
If you cannot configure your server, disable SharedArrayBuffer
by setting the sharedMemoryForWorkers
prop to false
:
<Viewer
id={"your-scene-id"}
apikey={"your-apikey"}
sharedMemoryForWorkers={false}
/>