Quick Start
Before integration, make sure your Embed Mode setup is completed in TaskOn dashboard:
And ensure you already have:
- A resolved embed domain (for example
https://your_embed_domain.com) - Your TaskOn keys (for example
TASKON_CLIENT_IDandTASKON_PRIVATE_KEY)
This guide shows the recommended host integration flow:
- Create
TaskOnEmbed - Call
init() - Listen to lifecycle events
- Handle login when
loginRequiredis emitted - Sync logout when host user logs out
- Clean up with
destroy()when unmounting
Install
npm install @taskon/embedPrepare a Container
Place a container element in your page. The SDK mounts its iframe inside it:
<div id="taskon-embed" style="width: 100%; height: 100%;"></div>Basic Integration
import { TaskOnEmbed, trackVisit } from "@taskon/embed";
// Optional conversion analytics (run once per page load)
await trackVisit();
const embed = new TaskOnEmbed({
baseUrl: "https://your_embed_domain.com",
containerElement: "#taskon-embed",
});
embed.on("loginRequired", () => {
// Open host login UI (modal/redirect/etc.)
openLoginModal();
});
embed.on("routeChanged", (fullPath) => {
// Optional: sync iframe route to host URL
// window.history.replaceState(null, "", `/taskon${fullPath}`);
console.log("TaskOn route changed:", fullPath);
});
embed.on("taskCompleted", (event) => {
console.log("Task completed:", event.taskName, event.rewards);
});
await embed.init();Login Example
Call embed.login(...) after user signs in to your host system:
const email = "[email protected]";
// Fetch signature from your backend
const signed = await fetch("/your/api", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
type: "Email",
account: email,
}),
}).then((res) => res.json());
await embed.login({
type: "Email",
account: email,
signature: signed.signature,
timestamp: signed.timestamp,
});Skip Re-signing with isAuthorized()
If the account is already authorized (cached), you can call login() without a
fresh signature — only fetch one when needed:
const isAuthorized = await embed.isAuthorized("Email", email);
if (isAuthorized) {
await embed.login({ type: "Email", account: email });
} else {
const signed = await fetch("/your/api", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ type: "Email", account: email }),
}).then((res) => res.json());
await embed.login({
type: "Email",
account: email,
signature: signed.signature,
timestamp: signed.timestamp,
});
}Login with an EVM Wallet
For wallet users, use type: "WalletAddress" and pass the wallet provider
(required for on-chain operations):
async function loginToTaskOnWithWallet(address: string, provider: any) {
const isAuthorized = await embed.isAuthorized("WalletAddress", address);
if (isAuthorized) {
await embed.login({ type: "WalletAddress", account: address, provider });
return;
}
// Backend signs with type "evm" for wallet accounts
const signed = await fetch("/your/api", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ type: "evm", account: address }),
}).then((res) => res.json());
await embed.login({
type: "WalletAddress",
account: address,
signature: signed.signature,
timestamp: signed.timestamp,
provider,
});
}Backend: Generate the Signature
The /your/api endpoint referenced above must sign the request server-side
with your private key, using signMessage from @taskon/embed/node. Never ship
TASKON_PRIVATE_KEY to the browser:
import { signMessage } from "@taskon/embed/node";
// Example Express.js endpoint
app.post("/your/api", (req, res) => {
const { account, type } = req.body; // type: "Email" | "evm"
// Verify the user is authenticated in YOUR system first
if (!isUserAuthenticated(req)) {
return res.status(401).json({ error: "Unauthorized" });
}
try {
const result = signMessage(
process.env.TASKON_CLIENT_ID!,
type === "Email" ? "Email" : "evm",
account,
process.env.TASKON_PRIVATE_KEY!, // Base64-encoded RSA private key
);
res.json(result); // { signature, timestamp }
} catch {
res.status(500).json({ error: "Signature generation failed" });
}
});Logout Example
Call embed.logout(...) when host user logs out:
// Recommended: keep authorization cache for fast re-login
await embed.logout();
// Optional: clear authorization cache completely
// await embed.logout({ clearAuth: true });SPA Cleanup
Always destroy the instance when route/view unmounts:
embed.destroy();Next Steps
- Configure tabs/language/size: Configuration
- Implement secure login: Authentication
- Learn runtime control APIs: Methods
- Handle business events: Events
- Handle reward callbacks: Webhooks