3D Twin Unit implementation guide

Apps should be implemented as embed elements on your website.
You should not implement app using iframe - it will heavily decrease mobile UX experience.
 
Element that is used to render app must have defined sizes - width and height. It is important for proper app rendering.
Your AppID:
Configure your implementation
link

Configuration below allows to adjust app behaviour to your needs. Select features and they will be added to example code on the right.

Features:

Load app as overlay
loadAsOverlay: boolean
Open app as screen overlay. This feature requires website to control app visibility.
Active unit (ID 3DEstate)
unitId: string
Sets open unit in app - uses internal 3DEstate unit ID
Active unit (ID in Clients CRM)
unitCustomCrmId: string
Sets open unit in app - uses clients CRM ID for unit (if such ID was passed to 3DEstate during integration)

Hooks:

Custom contact form
onContactFormClicked: (units: Unit[]) => void
App allows to user custom contact form when user clicks "send message" button. Provide function that should be executed on button click.
Custom handling of analytical events
onAnalyticEvent: (event: AnalyticEvent) => void
Function is called to handle analytical events
Action after user sent contact form request
onContactFormSent: (contactFormData: JsonObject) => void
Provided function will be called after user submiots contact request. Argument of function will contain user data and selected units.
"Phone" button in app
onPhoneClicked: () => void
Providing function will display "phone" button in app, which will trigger provided function.
Action after overlay app close
onOverlayClose: () => void
Function will be called after closing app that was opened in overlay mode
Additional data in 3D Estate Contact Form
rfpExternalData: () => JsonObject
Function that handles passing additional data to 3D Estate Contact Form. Function will be called when user sends contact form. Proper handling of extra data need configuration in 3D Estate system - please contact our support.
Add custom UTM data to contact form
rfpUtmData: () => UtmData
Function that handles passing additional UTM data to 3D Estate Contact Form. Function will be called when user sends contact form. Proper handling of extra data need configuration in 3D Estate system - please contact our support.
type UtmData = { utm_source?: string; utm_medium?: string; utm_campaign?: string; utm_term?: string; utm_content?: string; fbclid?: string; gclid?: string; [key: string]: string | undefined; }
Handling of custom app actions
onAppAction: (id: string, data: JsonObject) => void
Provided function will be called after a specific event, such as clicking an additional button in the details panel. The function returns the action ID and any additional data that may be passed as part of that action. Proper handling of the custom app action requires configuration in the 3D Estate system - please contact our support
Custom share link
onShareCustomLink: () => string
Provided function should return a custom link that will be used when the share button is clicked.
Custom share handling
onShare: () => void
Provided function will be called when the share button is clicked, allowing custom handling of the share action.

Interaction with app instance

Set app language
setLocale: (locale: string) => void
Call this function to change app language. App may support only selected languages.
Close App
closeApp: () => void
Allows to close app

App configuration:

Options that change the appearance and behaviour of the app. Passed inside the appFeatures object within props.

Hide share button
appFeatures.disableShare: boolean
Hides the share button in the app.
Disable contact form
appFeatures.disableRFP: boolean
Removes the contact form and every enquiry button - in the unit details, the unit list and the compare screen.
Disable unit compare
appFeatures.disableUnitCompare: boolean
Removes the unit compare screen and every "add to compare" button.
Auto-open on mobile when a unit is selected
appFeatures.autoOpenOnMobileIfUnitOpen: boolean
On mobile devices the app opens automatically when a unit is set at start-up (for example via unitId or unitCustomCrmId). With no unit selected the app stays collapsed.
Hide fullscreen button
appFeatures.disableFullscreenButton: boolean
Hides the button that toggles fullscreen mode.
Hide screenshot button
appFeatures.disableScreenshotButton: boolean
Hides the screenshot button from every bottom navigation - the building viewer and all tour players.
Hide outlines toggle
appFeatures.disableOutlinesSwitchButton: boolean
Hides the button that toggles unit outline visibility. The outlines themselves are unaffected.
Disable investment tour
appFeatures.disableInvestmentTour: boolean
Removes every entry point to the investment tour: the button in the building viewer navigation and the tour pins. Unrelated POI pins keep their own configuration.
App mode
appFeatures.smUnitMode: "default" | "viewer-only" | "details-only"
Sets the app layout: default - 3D model together with the unit details panel, viewer-only - 3D model only, details-only - unit details panel only.
App mode (desktop)
appFeatures.smUnitModeDesktop: "default" | "viewer-only" | "details-only"
Overrides the app mode for desktop only. Falls back to smUnitMode when not set.
App mode (mobile)
appFeatures.smUnitModeMobile: "default" | "viewer-only" | "details-only"
Overrides the app mode for mobile only. Falls back to smUnitMode when not set.
Mobile render mode
appFeatures.smUnitMobileRender: "modal" | "inline"
Sets how the app renders on mobile devices: modal - a full-screen overlay opened by the user, inline - the app embedded directly in the page content. The inline mode only applies to the viewer-only and details-only modes; in default mode the app always opens as a modal.
Allowed unit media
appFeatures.smUnitMediaAllow: MediaSelectorItem[]
List of media that should be available in the app. Once this list is set, all other media are hidden. The media field sets the media type, the optional id field points to one specific entry.
type MediaSelectorItem = { media: | "ttdh" | "topView" | "tour" | "unitImages" | "externalImages" | "externalUrl" | "externalUrls" | "unitView"; id?: number; // narrow the rule down to one specific media entry }
Disabled unit media
appFeatures.smUnitMediaDisable: MediaSelectorItem[]
List of media that should be hidden in the app. All remaining media stay available. The media field sets the media type, the optional id field points to one specific entry.
type MediaSelectorItem = { media: | "ttdh" | "topView" | "tour" | "unitImages" | "externalImages" | "externalUrl" | "externalUrls" | "unitView"; id?: number; // narrow the rule down to one specific media entry }
Media navigation with a single item
appFeatures.smUnitMediaShowMediaNavForSingleItem: boolean
By default the media navigation is hidden when a unit has only one media item. This option keeps it visible.
Disable building view
appFeatures.smUnitDisableBuildingView: boolean
Removes the building view from the unit media - it is not just hidden in the navigation, it also cannot be selected. If the unit has no other media, the app shows a "no media available" message.
Hide unit name
appFeatures.smUnitDynamicIslandDisableUnitName: boolean
Hides the unit name on the media navigation bar.
Embedded app aspect ratio
appFeatures.smUnitDesktopInlineRatio: number
The app calculates its height as width multiplied by the given value. This only applies when the parent element has no definite height and the app therefore has to size itself. Each mode has its own value, since each has a different natural shape.
// desktop, "default" mode // default value: 0.5625 (16:9)
Embedded app aspect ratio
appFeatures.smUnitDesktopViewerInlineRatio: number
The app calculates its height as width multiplied by the given value. This only applies when the parent element has no definite height and the app therefore has to size itself. Each mode has its own value, since each has a different natural shape.
// desktop, "viewer-only" mode // default value: 0.5625 (16:9)
Embedded app aspect ratio
appFeatures.smUnitDesktopDetailsInlineRatio: number
The app calculates its height as width multiplied by the given value. This only applies when the parent element has no definite height and the app therefore has to size itself. Each mode has its own value, since each has a different natural shape.
// desktop, "details-only" mode // default value: 0.75 (4:3)
Embedded app aspect ratio
appFeatures.smUnitMobileViewerInlineRatio: number
The app calculates its height as width multiplied by the given value. This only applies when the parent element has no definite height and the app therefore has to size itself. Each mode has its own value, since each has a different natural shape.
// mobile, "viewer-only" mode, only with smUnitMobileRender: "inline" // default value: 1.5
Simple config
Advanced config
Code in HTML section
content_copy
<div id="sm3de"></div> <script> window.AppLauncher3DEOAConfig = { appId: "[PUT-YOUR-APPID-HERE]", rootElement: "sm3de", }; </script> <script src="https://oneappappsprd.blob.core.windows.net/$web/launcher/production/app.js"></script>
Example CSS Styles for propper layout
content_copy
<style> #sm3de { width: 100%; height: calc(100vh - 100px); // adjust to website } </style>