Provide a client
Give an application its own Sinequa client — its own configuration, session and event subscribers — instead of the default one backing the free functions.
Every store, service and component in this library reaches the Sinequa backend through one client,
resolved from the ATOMIC_CLIENT injection token. provideAtomicClient() is how an application gives that
token its own client instead of the default one.
Concept — the default client
ATOMIC_CLIENT defaults to the client backing @sinequa/atomic's free functions (login(), fetchQuery(),
…), whose configuration is globalConfig. An application that never calls provideAtomicClient() behaves
exactly as before — there is nothing to migrate.
Minimal example
import { ApplicationConfig, provideAppInitializer } from "@angular/core";
import { bootstrapApp, provideAtomicClient } from "@sinequa/atomic-angular";
export const appConfig: ApplicationConfig = {
providers: [
// backendUrl may be omitted — bootstrapApp derives it from the browser URL.
provideAtomicClient({ app: "my-app" }),
provideAppInitializer(() => bootstrapApp({ createRoutes: true })),
],
};How it works
provideAtomicClient(config) registers a factory for ATOMIC_CLIENT that calls
createAtomicClient(config) from @sinequa/atomic — one client, one configuration, one session, one set of
event subscribers, isolated from whatever the default client is doing. injectAtomicClient() is
inject(ATOMIC_CLIENT) under a clearer name.
Registering provideAtomicClient() again in a route or component injector shadows the token for that subtree
only — which is how a second backend is served (see Serve a second backend).
Providing the client alone is rarely what a subtree serving a second backend wants, though: the library's
stores and services stay bound to whichever client was in scope when they were first constructed — use
provideAtomicScope() for a self-contained subtree.
Recipes
Configuration known only at start-up
Pass a function instead of an object when part of the configuration is resolved after this module is
evaluated — an SPFx web part supplying backendUrl at runtime, say. The object form is captured when the
providers are declared; the function form runs when the injector actually builds the client.
provideAtomicClient(() => ({ ...environment, ...hostOverrides() }))Reading the client and checking the session without redirecting
login() is not a question — for oauth/saml it navigates away to the identity provider. Ask
hasSession() instead to decide what to render.
import { Component, inject } from "@angular/core";
import { injectAtomicClient } from "@sinequa/atomic-angular";
@Component({ selector: "sample-component", template: `` })
export class SampleComponent {
private readonly client = injectAtomicClient(); // or inject(ATOMIC_CLIENT)
protected readonly isCredentialsMode = this.client.config.authMode?.kind === "credentials";
async checkSession() {
// Answers from the stored token when there is one, asks the server otherwise —
// never redirects, never throws.
return this.client.auth.hasSession();
}
}client.auth.isRedirectPending() tells a provider handshake apart from a plain missing session.
client.storagePrefix reads back the prefix namespacing this client's storage keys.
Options
Prop
Type
Pitfalls
What's next
Integration
Wiring the client, bootstrap, and cross-cutting interceptors, pipes, services and utilities into a host application.
Serve a second backend
Give a route or component subtree its own Sinequa client plus a self-contained copy of the library's stores and services, so two backends never leak into each other.