Runtime Hooks
Plugins can access the configurator’s current state using React hooks that K3 automatically injects during loading.
Read-Only Hooks
__PROTECTED_0__
useConfigurationVariables,
useConfigurationVariable,
useBOM,
useTotalPrice,
useFormattedTotalPrice,
useApp,
useK3PluginSettings,
getSettings,
} from "k3-plugin-api";
const MyComponent = () => {
const variables = useConfigurationVariables(); // alle Konfigurationsvariablen
const color = useConfigurationVariable("color"); // einzelne Variable per Key
const bom = useBOM(); // Stückliste
const price = useTotalPrice(); // Gesamtpreis als Zahl
const formattedPrice = useFormattedTotalPrice(); // z.B. "1.299,00 €"
const app = useApp(); // App-Metadaten (Produkt, Plan…)
const settings = useK3PluginSettings("vendor.my-plugin"); // eigene Plugin-Settings
return <p>{formattedPrice}</p>;
};
All hooks automatically re-render the component when the respective value changes.
| Hook / Function | What is returned |
|---|---|
useConfigurationVariables() | All variables with key as Record<string, K3ConfigurationVariableEntry> |
useConfigurationVariable(key) | Individual variable value via a stable key |
useBOM() | Current bill of materials (K3BomEntry[]) |
useTotalPrice() | Total price as number |
useFormattedTotalPrice() | Localized price string (e.g., "1.299,00 €") |
useApp() | App metadata (K3AppInfo | null) – product, plan, flags |
useK3PluginSettings(pluginId) | Plugin settings are reactive (re-rendered when changes are made) |
getSettings(pluginId) | Plugin settings as a snapshot (not reactive) |
The hooks only work in React components rendered within the configurator. getSettings() can also be used outside of components (e.g., in callbacks).
Setting Properties
Plugins can not only read configuration values, but also actively set them:
__PROTECTED_1__
useSetConfigurationVariable,
useAcceptConfigurationConflict,
useRejectConfigurationConflict,
} from "k3-plugin-api";
const MyControls = () => {
const setVariable = useSetConfigurationVariable();
const acceptConflict = useAcceptConfigurationConflict();
const rejectConflict = useRejectConfigurationConflict();
const onPickColor = async (valueId: number) => {
const res = await setVariable("color", valueId);
if (res.conflict) {
// Änderung wurde noch nicht übernommen – res.changes zeigt, was sich ändern würde
console.log("Würde auch ändern:", res.changes);
acceptConflict(); // oder: rejectConflict()
}
};
const onSetWidth = async () => {
await setVariable("width", 120); // Zahlenmerkmal: Rohwert, Snapping passiert intern
};
return <button onClick={() => onPickColor(42)}>Farbe setzen</button>;
};
| Hook / Function | Description |
|---|---|
useSetConfigurationVariable() | Returns setVariable(keyOrId, value) → Promise<K3SetVariableResult> |
useAcceptConfigurationConflict() | Accepts the pending rule conflict and applies the changes |
useRejectConfigurationConflict() | Rejects the pending rule conflict |
In the event of a rule conflict, the change is not applied immediately (result.conflict === true). result.changes lists the affected characteristics—after which a decision can be made using accept or reject.
Controlling Component Instances
For characteristics of the “Component” type, instances can be read and modified dynamically:
__PROTECTED_2__
useConfigurationInstances,
useAddConfigurationInstance,
useRemoveConfigurationInstance,
} from "k3-plugin-api";
const CabinetControls = () => {
const cabinets = useConfigurationInstances("cabinets"); // reaktive Liste
const addInstance = useAddConfigurationInstance();
const removeInstance = useRemoveConfigurationInstance();
return (
<>
<button onClick={() => addInstance("cabinet")}>Schrank hinzufügen</button>
{cabinets.map((c) => (
<button key={c.id} onClick={() => removeInstance(c.id)}>
{c.label} entfernen
</button>
))}
</>
);
};
| Hook / Function | Description |
|---|---|
useConfigurationInstances(keyOrId) | Reactive list of instances of a component variable |
useAddConfigurationInstance() | Returns add(valueKeyOrId, parentInstanceId?) → Promise<K3SetVariableResult> |
useRemoveConfigurationInstance() | Returns remove(instanceId) → Promise<K3SetVariableResult> |
useOpenInstance() | Reactive: the instance currently open in the user’s sidebar (K3OpenInstance) |
useOpenInstance() indicates which of several similar subconfigurations is currently being edited. If nothing is open at the top level, then isRoot === true.
Control the Camera
A plugin can set the viewer’s camera, for example, to look directly at a page section as soon as the user opens it:
__PROTECTED_3__
const setCameraPosition = useSetCameraPosition();
const openInstance = useOpenInstance();
useEffect(() => {
if (openInstance.id !== sidewallId) return;
// 1 m entlang der Wandnormale heraustreten und zurückschauen.
setCameraPosition({
position: [wall.x + normal.x, wall.y, wall.z + normal.z],
lookAt: [wall.x, wall.y, wall.z],
objectNames: [wallObjectName], // K3 rahmt auf diese Objekte ein
});
return () => setCameraPosition(null); // Kamera wieder freigeben
}, [openInstance.id, sidewallId, setCameraPosition]);
camera.position directlyA write operation via useThree() will be overwritten in the next frame—the K3 camera system and OrbitControls continuously adjust the camera. Only useSetCameraPosition() behaves the same way as the named cameras in the Scene Editor.
Fields of K3CameraTarget:
| Field | Meaning |
|---|---|
position | World coordinates of [x, y, z], toward which the camera is moving |
lookAt | World coordinates that the camera is targeting |
focusType | "dynamic" (default): K3 frames the bounding box of objectNames/modelIds and maintains the direction. "static": position and lookAt are used unchanged |
objectNames | Restricts the dynamic focus to these Three.js object names |
modelIds | Restricts dynamic focus to these K3 model IDs |
zoom | Zoom factor (orthographic) or view angle multiplier (perspective) |
disableFocus | Suppresses K3’s own scene focus animation as long as this camera is active (default true) |
There is only one camera. If multiple plugins set it simultaneously, the last one takes precedence; the takeover is logged. Release the camera using setCameraPosition(null)—this only works if your plugin is still holding it.
See Orbit-Rotation einschränken for information on how to additionally restrict the camera’s rotation.
Rendering Features: StandaloneVariable
The StandaloneVariable component allows a single feature to be rendered directly in the plugin UI—regardless of which step it appears in within the configurator:
__PROTECTED_4__
const MyWidget = () => (
<div>
<StandaloneVariable variableKey="color" />
<StandaloneVariable variableKey="width" />
</div>
);
The feature must be created in the configurator. It can optionally be “removed from the step” so that it appears only here and not in the normal group view.