Skip to content

Framework quickstarts

One page per stack — Next.js, Nuxt, Express and the plain browser — and the two redirect URIs all of them share.

Four pages, one per stack. They differ only in where the callback lives and who owns the client instance; the sign-in itself is the same authorization-code flow with PKCE in every one of them.

  • Plain browser — any bundler, any framework with no module of ours. @kleora-io/browser.
  • Next.js — the App Router, with the same package used from a client component.
  • Nuxt — @kleora-io/nuxt, which brings its own callback page, route middleware and authenticated $fetch.
  • Express — the other half: verifying on your API what the browser signed in with.

What every one of them needs first

An App, and from its environment overview three values:

ValueLooks like
Issuerhttps://acme.sandbox.kleora.eu
Client idthe Default client's client_id
Redirect URIone you register yourself, below

Quickstart walks through creating the App if you have not. Develop against the sandbox issuer: it is the environment that accepts http://localhost redirect URIs at all, and its users never touch production.

Register both /callback and /auth/callback

A redirect URI is matched exactly — scheme, host, port and path. The two browser packages mount their callback in different places:

PackageWhere it lands
@kleora-io/browserWherever you point redirectUri. The examples use /callback.
@kleora-io/nuxt/auth/callback — the page the module adds, callbackPath's default.

So on the Default client of your sandbox environment, register both:

http://localhost:3000/callback
http://localhost:3000/auth/callback

Registering only the one your first stack happens to use is the mistake worth avoiding: the next person to try the Nuxt module against the same App gets invalid_redirect_uri on their very first sign-in, from an App that was working a minute earlier. Two entries cost nothing and the failure costs an afternoon.

Register a post-logout redirect URI too — http://localhost:3000/ — because logout() sends the browser there and that list is matched exactly as well. @kleora-io/nuxt defaults returnTo to the site root, so the root is the one entry it cannot do without.

Production differs in one way that bites early

A production environment accepts https:// redirect URIs only. The http://localhost entries you develop against cannot be carried across, so production gets its own list on its own client, with your real origin in it.