Appearance
Frameworks
Every framework uses the same calls. Three rules apply everywhere:
- Call
init()once, in the browser only, after the app mounts. - In single-page apps, pass
trackRouteChanges: true. The SDK then re-runs itself on each client-side navigation, so page targeting stays correct. - Call
identify()after sign-in andreset()on sign-out.
Use these options in all examples:
ts
const options = {
publicKey: "pk_your_workspace_key",
apiUrl: "https://api.justonecx.qd.je",
trackRouteChanges: true,
};INFO
The examples import @justonecx/sdk. If you have not installed it, use the script tag instead.
React, Next.js, Remix, Preact
tsx
"use client"; // Next.js App Router only
import { useEffect } from "react";
import { identify, init } from "@justonecx/sdk";
export function JustOneCX({ user }: { user?: { id: string; plan: string } }) {
useEffect(() => void init(options), []);
useEffect(() => {
if (user) void identify(user.id, { plan: user.plan });
}, [user]);
return null;
}Render <JustOneCX user={user} /> once in your root layout.
Vue and Nuxt
ts
// Vue: main.ts, after app.mount()
import { init } from "@justonecx/sdk";
void init(options);ts
// Nuxt: plugins/justonecx.client.ts
// The ".client" suffix keeps it out of server rendering.
import { init } from "@justonecx/sdk";
export default defineNuxtPlugin(() => {
void init(options);
});Angular
ts
import { isPlatformBrowser } from "@angular/common";
import { Component, PLATFORM_ID, inject } from "@angular/core";
import { init } from "@justonecx/sdk";
@Component({ selector: "app-root", templateUrl: "./app.html" })
export class App {
constructor() {
if (isPlatformBrowser(inject(PLATFORM_ID))) void init(options);
}
}Svelte and SvelteKit
svelte
<script>
import { onMount } from "svelte";
import { init } from "@justonecx/sdk";
onMount(() => void init(options));
</script>Put this in +layout.svelte (SvelteKit) or App.svelte.
Solid and SolidStart
tsx
import { onMount } from "solid-js";
import { init } from "@justonecx/sdk";
onMount(() => void init(options));Astro, Lit, Alpine, jQuery, plain TypeScript
Call init(options) from any client-side script. In Astro, put it in a <script> tag so Astro bundles it for the browser.
Sites without a bundler
Plain HTML, WordPress, Webflow and Shopify: use the script tag. Add data-track-route-changes="true" if the site navigates on the client.
Identify after sign-in
ts
import { identify, reset } from "@justonecx/sdk";
async function onSignedIn(user: { id: string; plan: string }, userHash: string) {
await identify(user.id, { plan: user.plan }, { userHash });
}
async function onSignedOut() {
await reset();
}userHash comes from your server. See Identity verification.