Sign In
Render the credentials form or drive the SSO/OAuth/SAML/bearer handshake automatically, with declarative Signal Forms validation and safe post-login navigation.
SignIn is the credentials form and the entry point of the whole authentication sequence. In the external
modes (sso, oauth, saml, bearer) it shows a loader and starts the handshake itself instead of rendering
a form; in credentials mode it renders a real <form> built on
Signal Forms.
Route /login to AuthPageComponent, not SignInComponent
SignInComponent only ever renders the credentials form. Route /login (and /logout) to
AuthPageComponent instead — it switches between sign-in, change-password, forgot-password and signed-out
based on the route and the mode query param. See Authentication flows.
Minimal example
import { Component } from "@angular/core";
import { SignInComponent } from "@sinequa/atomic-angular";
@Component({
selector: "sample-component",
imports: [SignInComponent],
template: `<sign-in (forgotPassword)="onForgotPassword()" />`,
})
export class SampleComponent {
onForgotPassword() {
/* show your own reset screen */
}
}How it works
initialize() runs with syncUrl: false — deliberately: this component navigates to the returnUrl itself,
and letting the query-params store sync to the URL first would navigate to the bare route, dropping the
returnUrl's search parameters (and running the search twice, once on empty text).
The authenticated DOM event only drives navigation for the external handshake — a credentials login owns
its own sequence, and navigating from that event too would race the application initialization.
Recipes
Embedded in a dialog or a wizard step
Opt out of the behaviours that assume the component owns the whole page. autoStart matters most: without it,
mounting the form in an external auth mode would redirect the entire page to the identity provider.
import { Component, signal } from "@angular/core";
import { SignInComponent } from "@sinequa/atomic-angular";
@Component({
selector: "sign-in-step",
imports: [SignInComponent],
template: `
<sign-in
[fullscreen]="false"
[autoStart]="false"
[redirectAfterSuccess]="false"
class="w-full max-w-sm"
(success)="step.set('done')"
/>
`,
})
export class SignInStepComponent {
readonly step = signal("credentials");
}Extending the component
Subclass it to replace the template while keeping the whole authentication sequence. Bind your controls to
signInForm — the validation schema comes along with it, so [formRoot] alone drives submit interception,
preventDefault() and validity gating.
import { Component } from "@angular/core";
import { FormField, FormRoot } from "@angular/forms/signals";
import { SignInComponent } from "@sinequa/atomic-angular";
@Component({
selector: "custom-sign-in",
imports: [FormRoot, FormField],
template: `
<form [formRoot]="signInForm" class="flex flex-col gap-4">
<input [formField]="signInForm.username" autocomplete="username" placeholder="Username" />
<input type="password" [formField]="signInForm.password" autocomplete="current-password" placeholder="Password" />
<button type="submit" [disabled]="signInForm().invalid()">Sign In</button>
</form>
`,
})
export class CustomSignInComponent extends SignInComponent {}Options
Prop
Type
Prop
Type
Pitfalls
What's next
Authentication
Sign-in, password reset and change, session guards and interceptors, and the principal store.
Authentication flows
How AuthGuard, the auth interceptor, SignIn and logout fit together end to end — the Angular-side orchestration on top of @sinequa/atomic's core authentication state machine.