FAQ's
Frequently asked questions
How much effort on tech side is the integration of Cello?
The complexity of integrating Cello can vary greatly, depending on your individual setup. Integration generally consists of frontend integration and user authentication. For our typical customer, setting up these components on a development environment requires hours, not days. The integration of attribution and reward automation is also relatively straightforward, though it depends on your existing setup.
The Cello Floating Action Button is overlaying or covering another component within my product. What can I do?
Sometimes, the Cello Floating Action Button or the Referral Component might overlay another component in your product. Here's what you can do:
- Adjust the z-index: Cello can modify the z-index of the Floating Action Button or the Referral Component. This ensures that your other components can cover the Cello elements.
- Hide the element: Using the
cello.hide()
function, you can hide the Floating Action Button or the Referral Component when other components are open. Implement this function in your frontend.
You can also use the cello.hide()
function to hide the Cello Floating Action Button on specific pages.
Is it possible to hide the Cello Floating Action Button on certain pages?
You can hide the Cello Floating Action Button using the cello.hide()** function when other components open. The implementation has to be done in your frontend.
What exactly is the productUserId
that is required in the user authentication?
The productUserId
is the internal user id that you are using inside your product to uniquely identify users.
Do you support server-side rendering?
No, we do not support server-side rendering at the moment
Do you support Angular?
As mentioned before, the Cello Referral Component is being loaded independently from your angular app and appends itself to <body>
tag. That being said, you need to just make sure that the injected HTML code is not being overridden by your angular app. This can be achieved in various ways. The safest choice would be not to use <body> as your AppRoot element as it would create a race condition.
@Component({
selector: 'app-root',
})
<body>
<app-root></app-root>
</body>
The other option that we have seen customers implement is to load the cello javascript dynamically from your angular app, making sure that it is being loaded after angular is finished rendering its own components.
Here is an example that has been provided by one of our customers:
export interface CelloReferralPayload {
productId: string;
token: string;
showOnBoot: boolean;
productUserId: string;
language: string;
iat: string;
}
@Injectable({ providedIn: 'root' })
export class CelloReferralAdapter {
constructor(@Inject(DOCUMENT) private document: Document, @Inject(WINDOW) private window: Window) {}
async init(payload: CelloReferralPayload, isProd: boolean){
await this.loadScript(isProd
? 'https://assets.cello.so/app/latest/cello.js'
: 'https://assets.sandbox.cello.so/app/latest/cello.js');
await this.wait(1000);
(this.window as Window & {Cello: any}).Cello('boot', payload);
}
async wait(timeout: number) {
// due to a race condition a timeout is needed after initializing the script.
return new Promise<void>(resolve => setTimeout(() => resolve(), timeout));
}
async loadScript(src: string): Promise<void> {
return new Promise(resolve => {
const script = this.document.createElement('script');
script.onload = () => resolve();
script.type = 'module';
script.src = src;
this.document.head.appendChild(script);
});
}
}
What about other frameworks?
Since Cello is a Javascript library running on browser, then it works naturally with all frameworks that end up resulting in a standard HTML/Javascript application. That includes React, Angular, Vue and all similar JS/TS libraries.