Google sign-in
Configured on every backend, no client ID to register:redirectTo,
the SDK exchanges the code when the client initializes on that page, and
onAuthStateChange() fires. GitHub works the same way ("github"). Check what
else is enabled with
(await backend.auth.getPublicAuthConfig()).data.oAuthProviders.
Call it from a click handler, not an effect. In a preview pane the SDK needs to
open a window, and a browser only allows that inside a real user gesture.
Inside a preview or an iframe
Google refuses to render inside an iframe, so a framed page that redirects to it gets a 403 rather than a sign-in screen. The SDK handles this: when it detects that your app is framed, it opens the provider in a popup and finishes the sign-in in the page that opened it. Nothing to pass, and a top-level page still redirects as before. Force either flow when a product needs it:redirectTo on the same origin as the page starting the sign-in. A popup
can only hand its result back to a page it shares an origin with, so a
cross-origin one is refused up front with OAUTH_REDIRECT_CROSS_ORIGIN rather
than opening a window whose answer never arrives. Relative paths are fine.
If the popup is blocked, the call returns OAUTH_POPUP_BLOCKED and its
nextActions tells the user what to allow. A window the user closes returns
OAUTH_POPUP_CLOSED, so a cancelled sign-in is not an error state to invent
copy for.
Staying signed in
The SDK persists the session in a first-party cookie on your own origin, so a reload, a new tab, a framed preview and a visit tomorrow all restore the same user. Requires 0.7.0 or newer. What you write is the restore call, once, when your app mounts:getCurrentUser()on mount is what restores the session. Skip it and a signed-in user who reloads looks signed out.onAuthStateChange()reports changes only. It does not fire for the session that already exists, so use it alongside the call above rather than instead of it.- Keep a loading state. The restore is async, so a UI with only “signed in” and “signed out” flashes the login screen on every reload.
localStorage, no refresh timer, no expiry math, no
/api/auth/callback route. The SDK refreshes and rotates on its own, and keeps
browser storage empty, so an empty localStorage never means “signed out”.
getCurrentUser() answers { user: null } with error: null for a visitor who
has never signed in, and makes no request at all in that case.
Want the refresh token out of reach of your own JavaScript? Use
@resultdev/sdk/ssr, where it lives in an httpOnly cookie your own server
writes instead of one the SDK can read.