HelloJohn / docs
SDKsJavaScript SDK

Examples

Practical code examples for the HelloJohn JavaScript SDK — Svelte, SolidJS, Vanilla JS, and common integration patterns.

Examples

Practical integration patterns for @hellojohn/js across different frameworks and use cases.


Svelte

Auth Store

// src/lib/auth.ts
import { HelloJohn } from "@hellojohn/js";
import { writable, derived } from "svelte/store";

export const hj = new HelloJohn({
  tenantId: import.meta.env.PUBLIC_HJ_TENANT_ID,
});

export const session = writable(null);
export const isAuthenticated = derived(session, ($s) => $s !== null);

// Initialize on app start
hj.session.onSessionChange((s) => session.set(s));
hj.session.getSession().then((s) => session.set(s));

Sign-In Component

<!-- SignIn.svelte -->
<script lang="ts">
  import { hj } from "$lib/auth";
  let email = "", password = "", error = "";

  async function submit() {
    const { error: err } = await hj.auth.signIn({ email, password });
    if (err) error = err.message;
    else window.location.href = "/dashboard";
  }
</script>

<form on:submit|preventDefault={submit}>
  <input bind:value={email} type="email" placeholder="Email" />
  <input bind:value={password} type="password" placeholder="Password" />
  {#if error}<p class="error">{error}</p>{/if}
  <button type="submit">Sign In</button>
</form>

SolidJS

// src/auth.ts
import { HelloJohn } from "@hellojohn/js";
import { createSignal, createEffect } from "solid-js";

const hj = new HelloJohn({ tenantId: import.meta.env.VITE_HJ_TENANT_ID });

export function createAuth() {
  const [session, setSession] = createSignal(null);

  createEffect(() => {
    hj.session.getSession().then(setSession);
    const { unsubscribe } = hj.auth.onAuthStateChange((_, s) => setSession(s));
    return unsubscribe;
  });

  return {
    session,
    isAuthenticated: () => session() !== null,
    signIn: hj.auth.signIn.bind(hj.auth),
    signOut: hj.auth.signOut.bind(hj.auth),
  };
}

Vanilla JavaScript

Complete Auth Flow

<!DOCTYPE html>
<html>
<body>
  <div id="app">
    <div id="auth-ui">
      <input id="email" type="email" placeholder="Email" />
      <input id="password" type="password" placeholder="Password" />
      <button id="sign-in">Sign In</button>
      <button id="sign-out" style="display:none">Sign Out</button>
    </div>
    <div id="user-info" style="display:none">
      <p id="user-id"></p>
    </div>
  </div>

  <script type="module">
    import { HelloJohn } from "https://cdn.hellojohn.dev/js/latest/hellojohn.esm.js";

    const hj = new HelloJohn({ tenantId: "tnt_01HABCDEF654321" });

    // Listen for auth state changes
    hj.auth.onAuthStateChange((event, session) => {
      if (session) {
        document.getElementById("auth-ui").style.display = "none";
        document.getElementById("user-info").style.display = "block";
        document.getElementById("user-id").textContent = `User: ${session.userId}`;
        document.getElementById("sign-out").style.display = "inline";
      } else {
        document.getElementById("auth-ui").style.display = "block";
        document.getElementById("user-info").style.display = "none";
      }
    });

    document.getElementById("sign-in").addEventListener("click", async () => {
      const email = document.getElementById("email").value;
      const password = document.getElementById("password").value;
      const { error } = await hj.auth.signIn({ email, password });
      if (error) alert(error.message);
    });

    document.getElementById("sign-out").addEventListener("click", () => {
      hj.auth.signOut();
    });

    // Check existing session on load
    hj.session.getSession();
  </script>
</body>
</html>

Making Authenticated API Calls

async function fetchUserData() {
  const token = await hj.session.getAccessToken();

  if (!token) {
    // Not authenticated
    window.location.href = "/sign-in";
    return;
  }

  const res = await fetch("/api/user-data", {
    headers: {
      Authorization: `Bearer ${token}`,
      "Content-Type": "application/json",
    },
  });

  if (res.status === 401) {
    // Token was rejected — sign out
    await hj.auth.signOut();
    window.location.href = "/sign-in";
    return;
  }

  return res.json();
}

OAuth Callback Handling

After OAuth redirect, exchange the code for a session:

// On your callback page (e.g., /auth/callback)
async function handleCallback() {
  const { error } = await hj.session.exchangeCodeForSession(window.location.href);

  if (error) {
    console.error("OAuth error:", error.message);
    window.location.href = "/sign-in?error=oauth_failed";
    return;
  }

  // Redirect to intended destination
  const redirectTo = sessionStorage.getItem("redirectAfterLogin") ?? "/dashboard";
  sessionStorage.removeItem("redirectAfterLogin");
  window.location.href = redirectTo;
}

handleCallback();

On this page