Customization
The SDK UI is a pre-configured component that you can fine-tune to match your brand. This page explains how to customize its appearance and layout using CSS classes, style properties, and CSS variables, plus how to drive its loader state, configure success and error messaging, and apply resend cooldowns — all without forking the component.
CustomCSS and CustomJS apply to the entire page. This page focuses on styling the SDK UI specifically. To change the text inside the rendered component (button labels, descriptions, etc.), see Localization.
What you can customize
The SDK UI replaces the mandatory <div> in your HTML for Auth, Profile, and Workflow flows (the container you pass to init()). It's a pre-built component with a fixed internal structure, so you can't edit its HTML directly. Instead, you can customize:
- Text content — modify text like button labels or form descriptions through Localization.
- Appearance and layout — adjust the look (colors, fonts) and structure (width, padding) using style properties and CSS classes.
- Surrounding page — use CSS variables in your own HTML to align the rest of the page with the SDK UI's style.
This approach gives you flexibility while preserving the integrity of the SDK UI's functionality.
SDK UI structure
The SDK UI is composed of several key elements, each controlled by specific CSS classes and style properties. Understanding its structure helps you target the right parts for customization:
Main card · loginradius-card-container
├── Header area · loginradius-card-header-container
│ ├── Logo (if enabled)
│ └── Header / subheader · loginradius-card-header, loginradius-card-subheader
├── Form area · loginradius-form-container
│ ├── Social buttons · social-buttons
│ ├── Separator · loginradius-or-separator
│ └── Input fields / buttons · loginradius-login-form, loginradius-button-container
└── Footer · loginradius-footer-container
| Area | Description |
|---|---|
| Main card | The overall container for the SDK UI. Styled with properties like Card.Width and Card.Background Color. |
| Header area | The logo (if enabled) and header/subheader text. Styled with properties like Header Font Size. |
| Form area | Input fields, primary/secondary buttons, and social login options. Styled with properties like Input Fields.Background Color and Social.Layout. |
| Separator | The "Or" separator between social login and email/password fields. |
| Footer | A footer area for additional links or text. Styled with properties like Footer.Background Color. |
This structure is rendered automatically when the mandatory <div> is replaced, and you control its appearance through the template editor.
CSS classes for the SDK UI
For advanced layout adjustments, target the following CSS classes in the CustomCSS section of the template editor. Each maps to a specific part of the SDK UI:
| Class | Targets |
|---|---|
loginradius-card-container | Main container for the entire SDK UI (overall size, alignment) |
loginradius-card-header-container | Container for the logo and header content (logo and header layout) |
loginradius-card-content | Wraps the header and subheader text (spacing around text) |
loginradius-card-header | The main header text (e.g. "Sign In") |
loginradius-card-subheader | The subheader text (e.g. "Enter your details") |
loginradius-form-container | The main form container (social buttons, separator, input fields) |
loginradius-or-separator | The "Or" separator container between social and email login |
loginradius-or-separator-text | The text within the "Or" separator (e.g. "Or") |
loginradius-login-form | Container for the input fields and buttons (form layout) |
loginradius-form-group | Container for an input field such as email or password |
loginradius-button-container | Container for primary and secondary buttons (e.g. "Sign In") |
loginradius-footer-container | The footer container for links or additional text |
Example — center the SDK UI and style the header:
.loginradius-card-container {
max-width: 450px;
margin: 20px auto; /* center the SDK UI */
}
.loginradius-card-header {
font-size: var(--sdk-header-font-size);
color: var(--sdk-card-text-color);
text-align: center;
}
Example — lay out social buttons in a grid:
.loginradius-form-container .social-buttons {
display: grid;
grid-template-columns: repeat(3, 1fr); /* 3 social buttons per row */
gap: 10px;
}
Customizable style properties
The SDK UI's appearance is controlled by style properties, shown as human-readable names in the template editor (e.g. Card.Background Color). Each property maps to a CSS variable that you can reuse in your own HTML or in CustomCSS — letting you keep the surrounding page consistent with the SDK UI. Refer to the Styles section of the template editor for the full list of properties and their corresponding CSS variables.
Loading customization
While the SDK is busy with a request — such as initializing or processing an authentication flow — it reports its state through the onLoading callback. Use it to show or hide your own loading indicator so users get visual feedback during network activity.
The callback receives a single boolean argument:
| Argument | Type | Description |
|---|---|---|
loading | boolean | true when the SDK starts processing a request; false when it finishes. |
The JavaScript SDK accepts onLoading in the constructor options; the React SDK exposes it as a prop on LoginRadiusProvider.
Toggle a loader element
Add a loader to your page, hidden by default:
<div id="my-loader" style="display: none;">Loading…</div>
Define a handler that shows or hides it based on the loading flag, and pass it to the SDK:
JavaScript SDK
React SDK
import { LoginRadiusSDK } from "@loginradius/loginradius-js";
function onLoading(isLoading) {
const loader = document.getElementById("my-loader");
if (!loader) return;
loader.style.display = isLoading ? "block" : "none";
}
const LRObject = new LoginRadiusSDK({
apiKey: "<YOUR_API_KEY>",
callbackUrl: window.location.origin,
onLoading,
});
import { LoginRadiusProvider } from "@loginradius/loginradius-react";
const loginRadiusOptions = {
apiKey: "<YOUR_API_KEY>",
callbackUrl: "<YOUR_CALLBACK_URL>",
};
function onLoading(isLoading: boolean) {
const loader = document.getElementById("my-loader");
if (!loader) return;
loader.style.display = isLoading ? "block" : "none";
}
export default function App() {
return (
<LoginRadiusProvider options={loginRadiusOptions} onLoading={onLoading}>
{/* Your app components */}
</LoginRadiusProvider>
);
}
Drive the indicator from framework state
In a framework-driven app you'll usually render the indicator from reactive state rather than touching the DOM directly. Pass the state setter straight to onLoading:
JavaScript SDK
React SDK
import { LoginRadiusSDK } from "@loginradius/loginradius-js";
// Replace `loadingState` with your framework's reactive primitive
// (Vue ref, Svelte writable store, Angular signal, etc.)
const loadingState = { value: false };
const LRObject = new LoginRadiusSDK({
apiKey: "<YOUR_API_KEY>",
callbackUrl: window.location.origin,
onLoading: (isLoading) => {
loadingState.value = isLoading;
},
});
import { useState } from "react";
import { LoginRadiusProvider, Auth } from "@loginradius/loginradius-react";
export default function App() {
const [isLoading, setIsLoading] = useState(false);
return (
<LoginRadiusProvider options={loginRadiusOptions} onLoading={setIsLoading}>
{isLoading && (
<div className="app-loader" role="status" aria-live="polite">
Loading…
</div>
)}
<Auth />
</LoginRadiusProvider>
);
}
onLoading reflects the SDK's internal busy state only — it does not indicate whether an action succeeded or failed. Handle results with each component's onSuccess and onError callbacks.
Success and error messages
After a user completes (or fails) an action — registering, resetting a password, updating a profile — the SDK surfaces a status message. You control how these messages appear with two options settings:
successMessageConfig— how confirmation messages are displayed after a successful action.errorMessageConfig— how messages are displayed when an action fails.
Both accept the same two fields, so you can style success and error feedback independently.
| Field | Type | Values | Description |
|---|---|---|---|
messageType | string | 'toast', 'container', 'none' | Where the message is rendered. See the display modes below. |
duration | number | Duration in milliseconds | How long the message stays visible before it dismisses automatically. |
Display modes
toast— a floating notification that overlays the page and dismisses afterduration. Good for non-blocking, transient feedback.container— the message renders inline, within the SDK UI's designated message area. It stays in the layout flow rather than floating over content.none— the SDK renders no message. Use this when you want to present feedback yourself through the component'sonSuccess/onErrorcallbacks.
Defaults
Each option has a different default so success and error feedback behave sensibly out of the box:
| Option | Default messageType | Default duration |
|---|---|---|
successMessageConfig | 'container' | 3200 |
errorMessageConfig | 'toast' | 3200 |
Examples
Configure both when you instantiate the SDK (JavaScript) or when you mount LoginRadiusProvider (React):
JavaScript SDK
React SDK
const LRObject = new LoginRadiusSDK({
apiKey: "<YOUR_API_KEY>",
// Show success confirmations as a toast for 5 seconds
successMessageConfig: {
messageType: "toast",
duration: 5000,
},
// Keep errors inline within the SDK UI
errorMessageConfig: {
messageType: "container",
duration: 4000,
},
});
const loginRadiusOptions = {
apiKey: "<YOUR_API_KEY>",
// Show success confirmations as a toast for 5 seconds
successMessageConfig: {
messageType: "toast",
duration: 5000,
},
// Keep errors inline within the SDK UI
errorMessageConfig: {
messageType: "container",
duration: 4000,
},
};
<LoginRadiusProvider options={loginRadiusOptions}>{/* ... */}</LoginRadiusProvider>;
Suppress the built-in messages entirely and handle feedback yourself:
JavaScript SDK
React SDK
const LRObject = new LoginRadiusSDK({
apiKey: "<YOUR_API_KEY>",
successMessageConfig: { messageType: "none" },
errorMessageConfig: { messageType: "none" },
});
LRObject.init("auth", {
container: "auth-container",
onSuccess: (res) => showMyOwnToast("Welcome back!"),
onError: (err) => showMyOwnError(err),
});
const loginRadiusOptions = {
apiKey: "<YOUR_API_KEY>",
successMessageConfig: { messageType: "none" },
errorMessageConfig: { messageType: "none" },
};
<LoginRadiusProvider options={loginRadiusOptions}>
<Auth
onSuccess={(res) => showMyOwnToast("Welcome back!")}
onError={(err) => showMyOwnError(err)}
/>
</LoginRadiusProvider>;
duration is ignored when messageType is 'none'. With 'none', drive all user-facing feedback from the component's onSuccess and onError callbacks.
Resend button cooldown
Flows that send a one-time code or link — Forgot Password, Registration, One-Click Sign-in, Two-Factor Authentication, Forgot PIN, and workflow OTP steps — expose a resend button. Use the resendRestriction options setting to put a cooldown timer on that button: after the user clicks resend, the button is disabled and shows a countdown, then reactivates once the configured number of seconds has elapsed. This throttles repeated send requests across all components.
For example, ForgotPassword: 5 disables the Forgot Password resend button for 5 seconds after each click. If a flow is not listed, its resend button has no cooldown.
resendRestriction is organized by delivery channel — email and sms — plus a workflow map for Identity Orchestration steps:
JavaScript SDK
React SDK
const LRObject = new LoginRadiusSDK({
apiKey: "<YOUR_API_KEY>",
resendRestriction: {
email: {
ForgotPassword: 5,
Registration: 10,
OneClickSignin: 8,
TwoFactorAuthentication: 3,
ForgotPIN: 5,
},
sms: {
ForgotPassword: 30,
Registration: 45,
OneClickSignin: 30,
TwoFactorAuthentication: 15,
},
workflow: {
loginWorkflow: {
smsotp: 15,
emailotp: 10,
// Custom resend buttons are keyed by their button ID
"<AdditionalButtonID>": 20,
},
signupWorkflow: {
smsotp: 30,
},
// Keyed by workflow name, then by button ID
"<WorkflowName>": {
"<ButtonID>": 10,
},
},
},
});
const loginRadiusOptions = {
apiKey: "<YOUR_API_KEY>",
resendRestriction: {
email: {
ForgotPassword: 5,
Registration: 10,
OneClickSignin: 8,
TwoFactorAuthentication: 3,
ForgotPIN: 5,
},
sms: {
ForgotPassword: 30,
Registration: 45,
OneClickSignin: 30,
TwoFactorAuthentication: 15,
},
workflow: {
loginWorkflow: {
smsotp: 15,
emailotp: 10,
"<AdditionalButtonID>": 20,
},
signupWorkflow: {
smsotp: 30,
},
"<WorkflowName>": {
"<ButtonID>": 10,
},
},
},
};
<LoginRadiusProvider options={loginRadiusOptions}>{/* ... */}</LoginRadiusProvider>;
| Key | Type | Description |
|---|---|---|
email | object | Cooldown in seconds per email-based flow: ForgotPassword, Registration, OneClickSignin, TwoFactorAuthentication, ForgotPIN. |
sms | object | Cooldown in seconds per SMS-based flow: ForgotPassword, Registration, OneClickSignin, TwoFactorAuthentication. |
workflow | object | Cooldowns for Identity Orchestration workflows, keyed by workflow name, then by button ID (smsotp, emailotp, or a custom resend button's ID). Value is in seconds. |
Best practices
When you customize the SDK UI, work iteratively and keep page-level styling consistent with the component:
- Start small — adjust one property or class at a time and preview the effect.
- Use previews — check how changes look across different screen sizes.
- Combine the tools — use style properties for quick visual changes, CSS classes for SDK UI layout, and CSS variables for page-wide consistency.
- Avoid
!important— the SDK UI ships its own specificity model; reach for class-level overrides before forcing precedence. - Treat resend cooldowns as user-protection — set them long enough to prevent abuse, short enough that legitimate retries still feel responsive.
By combining these tools, you can create an SDK UI that matches your brand's look and feel without losing accessibility, localization, or the SDK's built-in safety controls.
Related resources
Frontend SDKs overview
Compare the JavaScript and React SDKs and pick the right fit for your stack.
Options
Every option you can pass to the SDK.
Localization
Translate text inside the SDK UI.
JavaScript SDK components
Reference for the pre-built UI components in the JavaScript SDK.
React SDK components
Reference for the pre-built JSX components in the React SDK.