3D Twin List 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.
 
On desktop devices, element that is used to render app, should have defined width and height. On mobile devices only width should be defined - height will be auto-adjusted accordingly to height of unit list. That way - app will use default scroll of page for scrolling list. Those settings are crucial for proper app behaviour.
Your AppID:
Basic implementation

Basic implementation is to copy HTML code on the right and paste it in target place in website code.
Proper app rendering requires target element to have defined width and size.

Code in HTML section
content_copy
<div id="sm3de"></div> <script src="https://oneappappsprd.z6.web.core.windows.net/launcher/production/app.js" data-appid="[PUT-YOUR-APPID-HERE]"> </script>
Example CSS Styles for propper layout
content_copy
<style> #sm3de { width: 100%; height: auto; @media (min-width: 800px){ // desktop height: calc(100vh - 100px); // adjust to website } } </style>
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.

Init units filters
unitFilterOverride: { default: Record< string, | { min: number | null | undefined; max: number | null | undefined; } | { selected: | number[] | ((options: { values: (string | number)[] }[]) => number[] | undefined) | undefined } | { textSearch: string; } | undefined >; init: Record< string, | { min: number | null | undefined; max: number | null | undefined; } | { selected: | number[] | ((options: { values: (string | number)[] }[]) => number[] | undefined) | undefined } | { textSearch: string; } | undefined >; }
Sets default and init filtering of units in app
// Range config min: number | null | undefined // pass value for min range max: number | null | undefined // pass value for max range /** * null -> force empty value * undefined -> inherit default value from config */ // Select config selected: | number[] | ((options: { values: (string | number)[] }[]) => number[] | undefined) | undefined /** * EXAMPLE * ======= * Status options: [All, Available, Reserved, Sold] * Indexes: * 0 -> All * 1 -> Available * 2 -> Reserved * 3 -> Sold * * To select option "Available" code should be: * selected: [1] * * To select more options "Available, Reserved": * selected: [1, 2] * * To select dynamically generated options with function code should be: * selected: (options) => { * const index = options.findIndex(option => option.values.includes("{option-value-or-id}")) * return index < 0 ? undefined : [index]; * } */

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.
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.
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: auto; @media (min-width: 800px){ // desktop height: calc(100vh - 100px); // adjust to website } } </style>
URL Params
link

It is possible to set default and start values for the filtering module. To do this, add parameters to the URL as shown in the example below.


Set filters
It is possible to set default and start values for the filtering module. To do this, add parameters to the URL as shown in the example below.
https://your-url.com/?sm-filters-rooms-default-min=2&sm-filters-rooms-default-max=3&sm-filters-status=1,2 Range filters - default state &sm-filters-{filterName}-default-min={number} &sm-filters-{filterName}-default-max={number} - init state &sm-filters-{filterName}-init-min={number} &sm-filters-{filterName}-init-max={number} Select filters - default state &sm-filters-{filterName}-default=number,number // provide indexes of options that should be selected - init state &sm-filters-{filterName}-init=number,number // provide indexes of options that should be selected EXAMPLE Status options: [All, Available, Reserved, Sold] Indexes: 0 -> All 1 -> Available 2 -> Reserved 3 -> Sold Selected All: &sm-filters-status-default=0 Selected Available,Reserved: &sm-filters-status-default=1,2