The hosted UI is a small Go module, but the structure carries the whole product story: providers come and go, the UI does not change.
Renderer surface
RenderLogin(w, r, ViewConfig)RenderLogout(w, r, ViewConfig)RenderError(w, r, ViewConfig, err)StaticFS()for/static/...
ViewConfig is the contract
The host app passes branding, FlowConfig and FeatureFlags. FlowConfig carries the API URL, the session cookie name, the logout path, and — critically — SDKScript: the URL of the browser SDK bundle for the active provider. AuthKit does not know whether that bundle talks to Hanko, Supabase or a custom Postgres backend.
Why this matters
- The same UI module renders the login page for every provider we support today and tomorrow.
- Provider-specific assets live in their own static FS (for example
authkit-hanko) and are merged on the same/static/prefix. - i18n is embedded in the binary; there is no runtime download of language files.
Operational properties
- Templates compile to Go via templ; XSS escaping is automatic.
- Dark theme is a CSS toggle stored in
localStorage, with a no-flash inline boot script. - The static bundle is content-hashed and cached aggressively at the edge.