Skip to main content

LoginForm

<allegro-login-form> is a web component that authenticates readers via a magic login link sent to their email, a six-digit one-time code, or via Google, Apple, or Facebook OAuth. The email-based method is chosen with the login-method attribute — magic link by default. On mobile the email input and button stack vertically; on wider screens (≥40em) they sit inline.

Set login-method="magic-link-otp" to send a single email containing both a magic link and a six-digit code. The form has one submit button, just like the single-method layouts; submitting it emails the reader both options and shows the code-entry screen. Clicking the link in the email authenticates directly (the form polls for that in the background), or the reader can type the code instead — whichever they do first signs them in.

Usage

<allegro-login-form></allegro-login-form>

Customise the text labels via HTML attributes:

<allegro-login-form
placeholder-text="Your email"
button-text="Get my link"
publisher-name="Example News"
continue-text="Keep Reading"
hide-third-party="true"
></allegro-login-form>

Send a magic link and a one-time code together from a single form:

<allegro-login-form login-method="magic-link-otp" button-text="Sign in securely"></allegro-login-form>

Attributes

AttributeTypeDefaultDescription
placeholder-texttextEnter your emailPlaceholder shown inside the email input.
button-texttextSign inLabel for the submit button in every login method.
login-methodselectmagic-linkAuthentication method: magic-link (emails a login link), otp (emails a 6-digit code), or magic-link-otp (emails both a link and a code).
hide-third-partybooleanfalseSet to true to hide all social login buttons (Google, Apple, Facebook).
publisher-nametext(empty)Publisher name shown in the success state, e.g. "Welcome back to Example News!"
continue-texttext(empty)Override the continue button label in the success state.
learn-more-urltext(empty)URL to navigate to when the continue button is clicked in success state.
tracking-datatext(empty)JSON object of custom data merged into every tracked event, e.g. "{'campaign': 'header'}".

States

The component moves through several states as the chosen sign-in flow advances. link-sent appears for the magic-link method, and code-entry for the one-time-code method (login-method="otp") and for the combined login-method="magic-link-otp" method — submitting the combined form always sends the single email and moves straight to code-entry, since the reader can either type the code there or click the link in the email. The expired state adapts its wording to match whichever method was last used.

StateTriggerDescription
emailInitial render (unauthenticated, no token in URL)Email input + social login buttons.
loadingInitial render when allegro_token is present in the URLSpinner shown while the SDK validates the token.
link-sentallegro:login-form:magic-link:sent fires (magic-link method)"Check your email inbox" with a resend option.
code-entryA one-time code was requested successfully (otp or magic-link-otp method)Six code-input boxes where the reader types the code.
successInitial render (already authenticated), or a magic link / one-time code is validated successfullyCheckmark + "Welcome back" with a continue button.
expiredallegro:magic-link:failed fires, or an entered one-time code has expired or been locked"Your link has expired" with a send-new-link button.

If the user is already signed in when the component renders, it skips straight to the success state.

Events

Dispatched by this component

NameBubblesDetailDescription
allegro:login-form:magic-link:sentyes{ email: string, data?: Record<string, unknown> }Fired after a magic link is successfully sent. Triggers the link-sent state.
allegro:login-form:authenticatedyes(none)Fired on every auth flow (magic link, one-time code, and social), before any flow-specific event.
allegro:login-form:magic-link:authenticatedyes(none)Fired after a magic link is validated successfully. Follows allegro:login-form:authenticated.
allegro:login-form:third-party:authenticatedyes{ provider: string, session_id: string, token: string }Fired after a successful Google or Apple login. Follows allegro:login-form:authenticated. provider is the provider name (e.g. google).
allegro:login-form:continueyes(none)Fired when the user clicks the continue button in the success state.

Listened to by this component (on window)

NameDetailDescription
allegro:magic-link:authenticated(none)Dispatched by the SDK after a magic link is validated successfully. Transitions to the success state.
allegro:magic-link:failed{ error: string }Dispatched by the SDK when magic link validation fails (e.g. expired token). Transitions to the expired state.

Slots

Slot nameAppears in stateDescription
headeremailRendered above the email input. Use for a title or description. Hidden once the form transitions to another state.
footeremailRendered below the email input (and social buttons when present). Use for supplementary links. Hidden once the form transitions to another state.
after-formemailRendered between the email input and the social login buttons. Use for supplementary inputs such as newsletter opt-in checkboxes. Values from named inputs inside this slot are included in the magic link request data.
successsuccessReplaces the entire success state UI (icon, heading, body, and continue button). When omitted, the default success UI is shown as fallback content.
after-continuesuccessRendered directly below the continue button in the default success UI. Ignored when the success slot is provided.
<allegro-login-form publisher-name="Example News">
<div slot="header">
<h2>Sign in to continue</h2>
<p>Access your account below.</p>
</div>
<p slot="footer">
<a href="/register">Don't have an account? Sign up</a>
</p>
</allegro-login-form>

To override the entire success state:

<allegro-login-form publisher-name="Example News">
<div slot="success">
<h2>You're in!</h2>
<p>Redirecting you now…</p>
</div>
</allegro-login-form>

Tracked Events

The component records the following analytics events via the Allegro SDK.

EventWhenData
magic_link_requestedA magic link is requested — on the initial submit, or when resent from the link-sent state.{ created: boolean }
otp_requestedA one-time code is requested — on the initial submit, or when resent from a code-entry state.{ created: boolean }
otp_validatedA submitted one-time code is accepted and the device is authenticated.(none)
loginAuthentication completes through a social / SSO provider.{ provider: string }

created is true when a new audience member was created for the email address, and false when an existing member was matched.

note

Magic link validation is tracked separately as magic_link_validated by the SDK when the link is opened, since that happens on the page the link points to rather than within the form.

CSS Variables

All visual properties are exposed as CSS custom properties so the component can be themed from the host page without piercing the shadow DOM.

allegro-login-form {
--loginForm--input--background: #fff;
--loginForm--submit--background: #1a1a1a;
}

General

VariableDefaultDescription
--loginForm--base-font-size1remBase unit all internal sizing is derived from. Defaults to the document's rem. See the note below.
--loginForm--colorblackBase text colour for the component.
--loginForm--font-familysystem-ui, sans-serifFont family applied to the entire component.
Sizing on pages with a non-16px root

Internally the form scales every dimension — padding, font sizes, spacing — from --loginForm--base-font-size, which defaults to the page's rem. If the host page sets a root font-size other than the usual 16px (for example a 10px root), the form renders too small or too large. Pin the base to a fixed value so the form sizes consistently regardless of the host page:

allegro-login-form {
--loginForm--base-font-size: 16px;
}

Input

VariableDefaultDescription
--loginForm--input--background#fffInput background colour.
--loginForm--input--border1px solid #cccInput border shorthand.
--loginForm--input--border-radius0.375remCorner radius applied to the input.
--loginForm--input--font-size1remInput text size.
--loginForm--input--padding0.75rem 1remInput padding shorthand.
--loginForm--input--focus-border-color#555Border colour when the input is focused.

Submit button

VariableDefaultDescription
--loginForm--submit--background#000Button background colour.
--loginForm--submit--color#fffButton text colour.
--loginForm--submit--border-radius0.375remCorner radius applied to the button.
--loginForm--submit--font-size0.875remButton text size.
--loginForm--submit--font-weight700Button font weight.
--loginForm--submit--font-familyinheritButton font family. Inherits the surrounding font by default.
--loginForm--submit--padding0.75rem 1.25remButton padding shorthand.
--loginForm--submit--text-transformuppercaseCSS text-transform applied to button label.

Divider

VariableDefaultDescription
--loginForm--divider--color#333Text and line colour for the "OR" divider.
--loginForm--divider--line-colorcurrentColorOverride only the line colour independently.
--loginForm--divider--margin1rem 0Vertical spacing around the divider.

Social buttons

VariableDefaultDescription
--loginForm--social--background#fffSocial button background colour.
--loginForm--social--hover-background#f9fafbSocial button background on hover.
--loginForm--social--border1px solid #d1d5dbSocial button border shorthand.
--loginForm--social--border-radius0.5remSocial button corner radius.
--loginForm--social--color#111Social button text colour.
--loginForm--social--font-familyinheritSocial button font family. Inherits the surrounding font by default.
--loginForm--social--font-size1remSocial button text size.
--loginForm--social--line-height1.25Social button line height.
--loginForm--social--height42pxMinimum button height below the 640px breakpoint (stacked).
--loginForm--social--height-desktop48pxMinimum button height at 640px and above (side-by-side).
--loginForm--social--padding0.5rem 1remSocial button padding shorthand.
--loginForm--social--gap0.5remGap between social buttons when stacked; same value applies in the side-by-side layout.

Loading spinner

VariableDefaultDescription
--loginForm--loading--track-colorcurrentColorSpinner colour. Inherits the component text colour by default.
VariableDefaultDescription
--loginForm--state-icon--background#111Background colour of the circular state icon.
--loginForm--state-heading--color#111Heading text colour.
--loginForm--state-heading--font-size1.25remHeading font size.
--loginForm--state-heading--font-weight700Heading font weight.
--loginForm--state-body--color#555Body and disclaimer text colour.
--loginForm--state-body--font-size0.9375remBody text size.
--loginForm--resend--color#555Resend link text colour.
--loginForm--resend--hover-color#111Resend link text colour on hover.
--loginForm--resend--font-size0.875remResend link font size.
--loginForm--resend-error--color#b91c1cText colour for the inline error shown below the resend/send-new-link button.

Error message

VariableDefaultDescription
--loginForm--error--background#fef2f2Error container background colour.
--loginForm--error--border1px solid #fecacaError container border shorthand.
--loginForm--error--accent-color#dc2626Left accent border colour.
--loginForm--error--border-radius0.375remError container corner radius.
--loginForm--error--color#b91c1cError message text colour.
--loginForm--error--icon-colorcurrentColorError icon colour (inherits text colour by default).
--loginForm--error--padding0.625rem 0.875remError container padding.

Example: Dark Background

When placing the component on a dark or coloured background, override the divider and social button colours so they read clearly:

allegro-login-form {
--loginForm--divider--color: rgba(255, 255, 255, 0.7);
--loginForm--social--background: transparent;
--loginForm--social--border: 1px solid rgba(255, 255, 255, 0.4);
--loginForm--social--color: #fff;
--loginForm--social--hover-background: rgba(255, 255, 255, 0.08);
}