Skip to main content
The Gately SDK provides native adapters for popular JavaScript frameworks, making it easy to integrate authentication into your existing applications.

React Adapter

Use the React hook for reactive authentication state management.
import React from 'react'
import { useGately } from 'https://cdn.usegately.com/gately-sdk.esm.min.js'

function App() {
  const { 
    user, 
    session, 
    profile,
    loading, 
    error,
    login, 
    logout, 
    signup,
    loginWithGoogle,
    sendMagicLink,
    resetPassword,
    getUserProfile,
    updateUserProfile,
    changePassword,
    deleteAccount,
    client
  } = useGately('your-project-id')

  const handleLogin = async (e) => {
    e.preventDefault()
    const formData = new FormData(e.target)
    
    try {
      await login(
        formData.get('email'),
        formData.get('password')
      )
    } catch (error) {
      console.error('Login failed:', error)
    }
  }

  if (loading) return <div>Loading...</div>

  return (
    <div>
      {user ? (
        <div>
          <h1>Welcome, {user.email}!</h1>
          <button onClick={logout}>Logout</button>
        </div>
      ) : (
        <form onSubmit={handleLogin}>
          <input name="email" type="email" placeholder="Email" required />
          <input name="password" type="password" placeholder="Password" required />
          <button type="submit">Login</button>
        </form>
      )}
      
      {error && <p className="error">{error}</p>}
    </div>
  )
}

export default App

React Hook API

The useGately hook returns an object with the following properties:
user
User | null
Current authenticated user
session
Session | null
Current user session
profile
UserProfile | null
Current user profile
loading
boolean
Loading state for authentication operations
error
string | null
Error message from last operation
login
function
Login with email and password
logout
function
Logout current user
signup
function
Create new user account
client
GatelyBrowserClient
Direct access to the SDK client

Vue 3 Adapter

Use the Vue 3 composition API for reactive authentication.
<template>
  <div>
    <div v-if="loading">Loading...</div>
    
    <div v-else-if="user">
      <h1>Welcome, {{ user.email }}!</h1>
      <button @click="logout">Logout</button>
    </div>
    
    <form v-else @submit.prevent="handleLogin">
      <input v-model="form.email" type="email" placeholder="Email" required />
      <input v-model="form.password" type="password" placeholder="Password" required />
      <button type="submit">Login</button>
    </form>
    
    <p v-if="error" class="error">{{ error }}</p>
  </div>
</template>

<script setup>
import { ref, reactive } from 'vue'
import { useGately } from 'https://cdn.usegately.com/gately-sdk.esm.min.js'

const { 
  user, 
  session, 
  profile,
  loading, 
  error,
  login, 
  logout, 
  signup,
  loginWithGoogle,
  sendMagicLink,
  resetPassword,
  getUserProfile,
  updateUserProfile,
  changePassword,
  deleteAccount,
  client
} = useGately('your-project-id')

const form = reactive({
  email: '',
  password: ''
})

const handleLogin = async () => {
  try {
    await login(form.email, form.password)
    form.email = ''
    form.password = ''
  } catch (error) {
    console.error('Login failed:', error)
  }
}
</script>

Vue 3 Installation

import { useGately } from 'https://cdn.usegately.com/gately-sdk.esm.min.js'

Svelte Adapter

Use the Svelte store for reactive authentication state.
// stores/gately.js
import { createGatelyStore } from 'https://cdn.usegately.com/gately-sdk.esm.min.js'

export const gately = createGatelyStore('your-project-id')
<!-- App.svelte -->
<script>
  import { gately } from './stores/gately.js'
  
  let form = {
    email: '',
    password: ''
  }
  
  async function handleLogin() {
    try {
      await gately.login(form.email, form.password)
      form.email = ''
      form.password = ''
    } catch (error) {
      console.error('Login failed:', error)
    }
  }
  
  async function handleLogout() {
    await gately.logout()
  }
</script>

{#if $gately.loading}
  <div>Loading...</div>
{:else if $gately.user}
  <div>
    <h1>Welcome, {$gately.user.email}!</h1>
    <button on:click={handleLogout}>Logout</button>
  </div>
{:else}
  <form on:submit|preventDefault={handleLogin}>
    <input 
      bind:value={form.email} 
      type="email" 
      placeholder="Email" 
      required 
    />
    <input 
      bind:value={form.password} 
      type="password" 
      placeholder="Password" 
      required 
    />
    <button type="submit">Login</button>
  </form>
{/if}

{#if $gately.error}
  <p class="error">{$gately.error}</p>
{/if}

Svelte Store API

The Svelte store provides reactive access to:
  • $gately.user - Current user
  • $gately.session - Current session
  • $gately.loading - Loading state
  • $gately.error - Error messages
  • gately.login() - Login method
  • gately.logout() - Logout method
  • gately.signup() - Signup method

Angular Adapter

Use the Angular service for authentication in Angular applications.
// auth.service.ts
import { Injectable } from '@angular/core'
import { GatelyService } from 'https://cdn.usegately.com/gately-sdk.esm.min.js'
import { BehaviorSubject, Observable } from 'rxjs'

@Injectable({
  providedIn: 'root'
})
export class AuthService {
  private gately: GatelyService
  private userSubject = new BehaviorSubject<any>(null)
  private loadingSubject = new BehaviorSubject<boolean>(true)
  private errorSubject = new BehaviorSubject<string | null>(null)

  constructor() {
    this.gately = new GatelyService('your-project-id')
    this.setupAuthListener()
  }

  private setupAuthListener() {
    this.gately.onAuthStateChange((user, session) => {
      this.userSubject.next(user)
      this.loadingSubject.next(false)
    })
  }

  get user$(): Observable<any> {
    return this.userSubject.asObservable()
  }

  get loading$(): Observable<boolean> {
    return this.loadingSubject.asObservable()
  }

  get error$(): Observable<string | null> {
    return this.errorSubject.asObservable()
  }

  async login(email: string, password: string) {
    try {
      this.loadingSubject.next(true)
      this.errorSubject.next(null)
      await this.gately.login(email, password)
    } catch (error: any) {
      this.errorSubject.next(error.message)
      throw error
    } finally {
      this.loadingSubject.next(false)
    }
  }

  async logout() {
    try {
      await this.gately.logout()
    } catch (error: any) {
      this.errorSubject.next(error.message)
    }
  }

  async signup(email: string, password: string, metadata?: any) {
    try {
      this.loadingSubject.next(true)
      this.errorSubject.next(null)
      await this.gately.signup(email, password, metadata)
    } catch (error: any) {
      this.errorSubject.next(error.message)
      throw error
    } finally {
      this.loadingSubject.next(false)
    }
  }
}
// app.component.ts
import { Component } from '@angular/core'
import { AuthService } from './auth.service'

@Component({
  selector: 'app-root',
  template: `
    <div *ngIf="auth.loading$ | async">Loading...</div>
    
    <div *ngIf="auth.user$ | async as user">
      <h1>Welcome, {{ user.email }}!</h1>
      <button (click)="logout()">Logout</button>
    </div>
    
    <form *ngIf="!(auth.user$ | async)" (ngSubmit)="login()">
      <input [(ngModel)]="form.email" name="email" type="email" placeholder="Email" required />
      <input [(ngModel)]="form.password" name="password" type="password" placeholder="Password" required />
      <button type="submit">Login</button>
    </form>
    
    <p *ngIf="auth.error$ | async as error" class="error">{{ error }}</p>
  `
})
export class AppComponent {
  form = {
    email: '',
    password: ''
  }

  constructor(public auth: AuthService) {}

  async login() {
    try {
      await this.auth.login(this.form.email, this.form.password)
      this.form.email = ''
      this.form.password = ''
    } catch (error) {
      console.error('Login failed:', error)
    }
  }

  async logout() {
    await this.auth.logout()
  }
}

Installation Instructions

  • React
  • Vue 3
  • Svelte
  • Angular
import { useGately } from 'https://cdn.usegately.com/gately-sdk.esm.min.js'

Framework-Specific Features

React Features

  • Reactive state management with hooks
  • Automatic re-rendering on auth state changes
  • TypeScript support with full type definitions
  • Integration with React Router for protected routes

Vue 3 Features

  • Composition API integration
  • Reactive refs and computed properties
  • Vue DevTools support
  • Template syntax integration

Svelte Features

  • Reactive store with automatic subscriptions
  • Minimal bundle size impact
  • SvelteKit integration
  • Built-in reactivity system

Angular Features

  • Injectable service pattern
  • RxJS observables for reactive programming
  • Dependency injection integration
  • Angular CLI and build system support

Protected Routes

React Router Example

import { Navigate } from 'react-router-dom'
import { useGately } from 'https://cdn.usegately.com/gately-sdk.esm.min.js'

function ProtectedRoute({ children }) {
  const { user, loading } = useGately('your-project-id')
  
  if (loading) return <div>Loading...</div>
  
  return user ? children : <Navigate to="/login" />
}

// Usage
<Route path="/dashboard" element={
  <ProtectedRoute>
    <Dashboard />
  </ProtectedRoute>
} />

Vue Router Example

// router/index.js
import { createRouter, createWebHistory } from 'vue-router'
import { useGately } from 'https://cdn.usegately.com/gately-sdk.esm.min.js'

const router = createRouter({
  history: createWebHistory(),
  routes: [
    {
      path: '/dashboard',
      component: Dashboard,
      meta: { requiresAuth: true }
    }
  ]
})

router.beforeEach((to, from, next) => {
  const { user } = useGately('your-project-id')
  
  if (to.meta.requiresAuth && !user.value) {
    next('/login')
  } else {
    next()
  }
})

Best Practices

  • Use framework-specific adapters for better integration
  • Avoid mixing different state management approaches
  • Handle loading and error states consistently
  • Use TypeScript for better type safety
  • Initialize the SDK once at the app level
  • Use memoization for expensive operations
  • Implement proper cleanup in component unmount
  • Avoid unnecessary re-renders
  • Implement consistent error handling across components
  • Show user-friendly error messages
  • Log errors for debugging purposes
  • Provide fallback UI for error states
  • Store project ID in environment variables
  • Validate user input before authentication
  • Implement proper session management
  • Use HTTPS in production

Migration Guide

Migrate from the core SDK to framework-specific adapters.
import { GatelyBrowserClient } from 'https://cdn.usegately.com/gately-sdk.esm.min.js'
import { useState, useEffect } from 'react'

function App() {
  const [user, setUser] = useState(null)
  const [loading, setLoading] = useState(true)
  
  useEffect(() => {
    const gately = new GatelyBrowserClient('your-project-id')
    
    gately.onAuthStateChange((user) => {
      setUser(user)
      setLoading(false)
    })
  }, [])
  
  // ... rest of component
}

Next Steps