Skip to main content
SDK v7.x · Last verified March 2026 · iOS · Android · Web · Flutter
// 1. Visitor login (anonymous, read-only)
await Client.loginAsVisitor();

// 2. Upgrade to authenticated user
await Client.login({ userId: 'user-123', displayName: 'Jane' });

// 3. Update the user profile
await UserRepository.updateUser('user-123', {
  displayName: 'Jane Doe',
  description: 'Hello world!',
  avatarFileId: 'uploaded-avatar-id',
});
Full walkthrough below ↓
Platform note — code samples below use TypeScript. Every method has an equivalent in the iOS (Swift), Android (Kotlin), and Flutter (Dart) SDKs — see the linked SDK reference in each step.
A great onboarding funnel lets users browse before committing. social.plus supports three user types — visitors (anonymous, read-only), authenticated users (full access), and bots (crawler/SEO). This guide walks through the entire flow from first launch to complete profile.
Prerequisites: SDK installed → SDK Setup, plus an API key from the social.plus console. Production apps also need a backend server to generate auth tokens.
After completing this guide you’ll have:
  • Visitor mode enabled so unauthenticated users can browse content
  • A smooth visitor → authenticated transition with session continuity
  • Profile setup step (display name, avatar) at first login

Quick Start: Login as Visitor

Let users browse your app without creating an account:
TypeScript
import { Client } from '@amityco/ts-sdk';

const client = Client.createClient('your-api-key', 'sg');

try {
  await Client.loginAsVisitor({ sessionHandler });
} catch (error) {
  console.error('Visitor login failed:', error);
}
Full reference → Visitor Mode

Step-by-Step Implementation

1

Initialize the SDK

Create the client once at app startup. This must happen before any login call.
TypeScript
import { Client } from '@amityco/ts-sdk';

const client = Client.createClient('your-api-key', 'sg');
Full reference → Authentication
2

Login as a visitor (anonymous browsing)

Visitors get read-only access — they can view feeds, communities, and profiles but cannot post, comment, react, or follow. The SDK skips MQTT connections and push notification registration for visitors, saving resources.
TypeScript
try {
  await Client.loginAsVisitor({ sessionHandler });
  console.log('Visitor login successful');
} catch (error) {
  console.error('Visitor login failed:', error);
}
Full reference → Visitor Mode
3

Detect user type and gate write actions

Check the current user type before allowing write operations. Show a signup prompt when visitors try to interact.
TypeScript
import { Client, UserTypeEnum } from '@amityco/ts-sdk';

const userType = Client.getCurrentUserType();
if (userType === UserTypeEnum.VISITOR) {
  // Show signup/login prompt
  showSignupModal('Create an account to post');
}
Full reference → Visitor Mode
4

Login with authentication

After the user signs up or logs in through your auth system, call the authenticated login. In production, always pass an authToken generated by your backend.
TypeScript
try {
  await client.login({
    userId: 'user-123',
    displayName: 'John Doe',
    authToken: 'token-from-your-backend', // Required in production
  }, sessionHandler);
  console.log('Login successful');
} catch (error) {
  console.error('Login failed:', error);
}
Full reference → Authentication
5

Observe session state changes

Monitor the session lifecycle to show the right UI: loading spinner during establishing, navigate to app on established, re-auth prompt on tokenExpired.
TypeScript
import { Client } from '@amityco/ts-sdk';

Client.onSessionStateChange((state: Amity.SessionStates) => {
  switch (state) {
    case 'established':
      navigateToApp();
      break;
    case 'tokenExpired':
      showTokenRefreshIndicator();
      break;
    case 'terminated':
      handleSessionTermination();
      break;
  }
});
Full reference → Authentication
6

Set up the user profile

After first login, let users set their display name, bio, and avatar. The SDK auto-creates the user record on first login — this step updates it.
TypeScript
import { UserRepository } from '@amityco/ts-sdk';

const { data: updatedUser } = await UserRepository.updateUser('userId', {
  displayName: 'Jane Smith',
  description: 'Loves hiking and photography',
});
Full reference → Update User Information
7

Implement session handler for token refresh

In production, tokens expire. The session handler lets the SDK request a fresh token from your backend without interrupting the user.
TypeScript
const sessionHandler: Amity.SessionHandler = {
  sessionWillRenewAccessToken: async (renewal: Amity.AccessTokenRenewal) => {
    try {
      const newToken = await AuthService.refreshToken();
      renewal.renewWithAuthToken(newToken);
    } catch (error) {
      renewal.unableToRetrieveAuthToken();
    }
  },
};
Full reference → Authentication
8

Secure logout

Always call secureLogout() when the user logs out. This clears the session, stops real-time connections, and unregisters push tokens.
TypeScript
await Client.secureLogout();
Full reference → Authentication

Connect to Moderation & Analytics

Track how many visitors browse vs. convert to authenticated users. Visitor device IDs are available via client.getVisitorDeviceId() for analytics attribution.
Use Client.loginAsBot() for search engine crawlers to index public content. Bots have even more restricted permissions than visitors — they can only read, never interact.Visitor Mode — Bot Users
Receive a user.created webhook event when a visitor converts to an authenticated user (first login). Use this to trigger welcome emails or onboarding flows.Webhook Events

Common Mistakes

Hardcoding auth tokens in client-side code — Auth tokens should be generated server-side. Embedding them in your app exposes them to extraction.
// ❌ Bad — token in source code
await Client.login({ userId: 'u1', authToken: 'hardcoded-secret' });

// ✅ Good — fetch token from your backend
const { authToken } = await yourServer.getAmityToken(currentUser.id);
await Client.login({ userId: currentUser.id, authToken });
Skipping the session handler — Without a session handler, expired sessions silently fail. Always implement sessionHandler to detect token expiry and re-authenticate.
Calling write APIs as a visitor — Visitors are read-only. Attempting to create posts or reactions as a visitor throws a permission error. Gate write actions behind an authentication check.

Best Practices

  • Show a subtle “Sign up for full access” banner while visitors browse — don’t block the experience
  • Track which actions visitors attempt most (post, react, comment) to optimize your signup prompt placement
  • Pre-fill the display name from your auth provider so users don’t have to type it twice
  • Gate write actions at the UI layer (disable buttons) rather than catching SDK errors
  • Never ship without auth tokens in production — without them, anyone can impersonate any userId
  • Use secureLogout() on every logout path (manual logout, session expiry, account deletion)
  • Implement the session handler — without it, sessions will fail silently when tokens expire
  • Store auth tokens server-side and pass them to the client at login time; never generate tokens client-side
  • Visitors skip MQTT connections and push notification registration automatically — no extra optimization needed
  • Cache the user type check result per session; getCurrentUserType() is synchronous and fast
  • For SSR/SEO, use bot mode to pre-render public content without consuming authenticated user slots

Dive deeper: Getting Started Reference has full parameter tables, method signatures, and platform-specific details for every API used in this guide.

Next Steps

Your next step → Build a Social Feed

Users can sign in — now give them a feed full of content to explore.
Or explore related guides:

User Profiles & Social Graph

Build the profile page your new users land on

Build a Social Feed

Show the feed that visitors browse before signing up

Notifications & Engagement

Set up push notifications after first login