ClerkService
The ClerkService provides integration with Clerk authentication, managing user sign-in, sign-out, and session token retrieval for Convex backend authentication.
Location
src/app/services/clerk.service.ts
Properties
The Clerk instance used for all authentication operations
Signal indicating whether the Clerk SDK has finished loading
Signal containing the current user object, or null if not authenticated
Initialization
The service automatically initializes Clerk on construction:
constructor() {
this.clerk = new Clerk(environment.clerkPublicKey);
this.init();
}
private async init() {
await this.clerk.load();
this.loaded.set(true);
this.clerk.addListener(() => {
this.user.set(this.clerk.user ?? null);
});
}
This sets up:
- Clerk SDK with the public key from environment config
- Reactive user state via signals
- Automatic updates when auth state changes
Methods
openSignIn()
Opens the Clerk sign-in modal.
async openSignIn(): Promise<void>
Example:
async showLogin() {
await this.clerkService.openSignIn();
}
openSignUp()
Opens the Clerk sign-up modal.
async openSignUp(): Promise<void>
Example:
async showRegister() {
await this.clerkService.openSignUp();
}
signOut()
Signs the user out and clears the user state.
async signOut(): Promise<void>
Example:
async logout() {
await this.clerkService.signOut();
// User signal will automatically be set to null
}
getToken()
Retrieves the current session token for authenticating with Convex.
async getToken(options?: { template?: string; skipCache?: boolean }): Promise<string | null>
Optional JWT template name to use (e.g., “convex”)
Whether to bypass the token cache and fetch a fresh token
Returns: The JWT token string, or null if no active session
Example:
async getConvexToken() {
const token = await this.clerkService.getToken({
template: 'convex'
});
return token;
}
The token is used by the Convex client to authenticate API requests. See the Backend integration guide for details on the Convex + Clerk setup.
isLoaded()
Waits for the Clerk SDK to finish loading.
async isLoaded(): Promise<void>
Example:
async ensureLoaded() {
await this.clerkService.isLoaded();
// Now safe to interact with Clerk
}
Usage in components
Check authentication status
import { Component, inject } from '@angular/core';
import { ClerkService } from '../services/clerk.service';
@Component({
selector: 'app-navbar',
template: `
@if (user()) {
<button (click)="signOut()">Sign Out</button>
<span>{{ user()?.firstName }}</span>
} @else {
<button (click)="signIn()">Sign In</button>
}
`
})
export class Navbar {
private clerkService = inject(ClerkService);
user = this.clerkService.user;
async signIn() {
await this.clerkService.openSignIn();
}
async signOut() {
await this.clerkService.signOut();
}
}
Wait for Clerk to load
@Component({
selector: 'app-root',
template: `
@if (loaded()) {
<router-outlet />
} @else {
<div>Loading...</div>
}
`
})
export class App {
private clerkService = inject(ClerkService);
loaded = this.clerkService.loaded;
}
Environment configuration
The service requires the Clerk public key to be configured in the environment file:
// src/environments/environment.development.ts
export const environment = {
clerkPublicKey: 'pk_test_...',
// other config
};
Make sure to use the correct Clerk public key for your environment. Use test keys for development and production keys for production builds.
Integration with Convex
The ClerkService works together with ClerkAuthService to provide authentication for Convex:
- User signs in via ClerkService
- ClerkService retrieves the JWT token
- ClerkAuthService passes the token to Convex client
- Convex validates the token and creates authenticated sessions
See the Backend integration page for the complete authentication flow.
Signal reactivity
Both loaded and user are Angular signals, making them fully reactive:
// In template - automatically updates when state changes
{{ user()?.firstName }}
// In component - use computed for derived state
isAdmin = computed(() =>
this.clerkService.user()?.publicMetadata?.role === 'admin'
);
The ClerkService handles the client-side authentication UI and state, while ClerkAuthService bridges Clerk with the Convex backend.