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:
Current authenticated user
Loading state for authentication operations
Error message from last operation
Login with email and password
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
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
- 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