SuperTokens Website Frontend SDK
SuperTokens Website Frontend SDK (npm package `supertokens-website`) is a JavaScript library designed to manage user authentication and session lifecycles for web applications. Currently at version 20.1.6, this SDK facilitates seamless integration with SuperTokens backend services, handling tasks like session creation, refresh, and invalidation automatically. It operates by intercepting network requests to maintain secure sessions through cookies and headers, without direct communication with the SuperTokens Core service from the frontend. Releases occur frequently, with patch and minor updates weekly or bi-weekly, and major versions typically every few months. Unlike `supertokens-web-js`, which is a plain JavaScript SDK for custom UIs, `supertokens-website` is intended as the foundational frontend SDK that can be used directly or integrated into higher-level framework-specific SDKs (e.g., `supertokens-auth-react`) to provide comprehensive authentication solutions, including pre-built UI components and robust session management features.
Common errors
-
Session refresh loop detected or session not being maintained.
cause Multiple potential causes including disabled cookie writes, incorrect backend configuration, or misconfigured API Gateway caching.fixEnsure browser cookies are enabled for your domain. Update `supertokens-website` to the latest version (>=20.1.2) to mitigate known issues. Verify backend SuperTokens SDK is updated and configured for correct session handling. If using a proxy/API gateway (like Vercel), ensure auth API responses are not cached (e.g., by setting `Cache-Control: no-store` header). -
JSON.parse: unexpected non-whitespace character at line 1 column 1 of the JSON data
cause An API endpoint, particularly a SuperTokens endpoint, returned a non-JSON response body when JSON was expected (e.g., plain text or HTML error page).fixUpdate `supertokens-website` to version >=20.1.0 which includes a fix for handling non-JSON bodies in XMLHttpRequest. Additionally, ensure your backend's SuperTokens endpoints consistently return valid JSON responses for all statuses. -
Missing 'front-token' header in successful refresh response.
cause The SuperTokens backend is not including the required `front-token` header in the response to a successful session refresh request.fixUpdate your SuperTokens backend SDK to a compatible version and verify its configuration to ensure it sends the `front-token` header as part of the refresh response. This is a critical component for frontend session state management. This started to throw an error since v20.1.5.
Warnings
- breaking The SDK now throws an error if the 'front-token' header is missing on a successful session refresh response from the backend. This enforces stricter compliance with expected backend behavior.
- breaking The behavior of `shouldDoInterceptionBasedOnUrl` changed. It now returns `true` for valid subdomains of `sessionTokenBackendDomain` and for requests with different ports but the same hostname or subdomain. This aligns cookie handling with browser behavior.
- breaking The `validatorId` property used in session claims has been renamed to `id`.
- breaking The method `getJWTPayloadSecurely` was renamed to `getAccessTokenPayloadSecurely`.
- gotcha A session refresh loop can occur if the browser's cookie writes are disabled (e.g., by privacy settings or extensions). The SDK will now provide console warnings/errors to help diagnose this.
- gotcha Incorrect CORS configuration on your backend can prevent session management. Specifically, the `Access-Control-Allow-Headers` must include `rid, fdi-version, anti-csrf, st-auth-mode`.
Install
-
npm install supertokens-website -
yarn add supertokens-website -
pnpm add supertokens-website
Imports
- SuperTokens
const SuperTokens = require('supertokens-website');import SuperTokens from 'supertokens-website';
- doesSessionExist
import { doesSessionExist } from 'supertokens-website'; - signOut
import { signOut } from 'supertokens-website'; - addAxiosInterceptors
import { addAxiosInterceptors } from 'supertokens-website';
Quickstart
import SuperTokens from "supertokens-website";
SuperTokens.init({
appInfo: {
appName: "My SuperTokens Web App",
apiDomain: "https://api.example.com", // URL of your auth backend
websiteDomain: "https://app.example.com", // URL of your frontend app
apiBasePath: "/auth", // Base path for SuperTokens APIs on your backend
websiteBasePath: "/auth" // Base path for SuperTokens UI on your frontend (if using custom UI)
},
// Additional configurations like preAPIHook, postAPIHook, cookieHandler, windowHandler can be added.
// enableDebugLogs: true, // Uncomment for detailed debug logs in the console.
});
async function handleAuthentication() {
console.log("Checking session status...");
const sessionExists = await SuperTokens.doesSessionExist();
if (sessionExists) {
const userId = await SuperTokens.getUserId();
const accessTokenPayload = await SuperTokens.getAccessTokenPayloadSecurely();
console.log(`User session exists. User ID: ${userId}`);
console.log("Access Token Payload:", accessTokenPayload);
// Example of a protected API call
try {
const response = await fetch("https://api.example.com/api/data");
if (response.status === 401) {
// SuperTokens interceptors should handle session refresh automatically.
// If refresh fails, it will lead to an unauthenticated state.
console.warn("API call returned 401. Session might be expired or refresh failed.");
alert("Your session has expired. Please log in again.");
await SuperTokens.signOut();
} else if (response.ok) {
const data = await response.json();
console.log("Successfully fetched protected data:", data);
} else {
console.error("Failed to fetch protected data:", response.status, response.statusText);
}
} catch (error) {
console.error("Error calling protected API:", error);
}
const logoutButton = document.getElementById("logout-btn");
if (logoutButton) {
logoutButton.onclick = async () => {
await SuperTokens.signOut();
console.log("User signed out.");
alert("You have been logged out.");
// Redirect user to login page or update UI state.
};
} else {
console.warn("No element with ID 'logout-btn' found for logout functionality.");
}
} else {
console.log("No active user session. User needs to log in.");
// Implement logic to show login UI or redirect to login page.
}
}
// Execute the authentication handler when the DOM is ready.
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", handleAuthentication);
} else {
handleAuthentication();
}