@airsoko/oauth-client
v0.1.0
Published
Client SDK for Airsoko OAuth — sign in customers with your shop OAuth client in Next.js apps
Maintainers
Readme
@airsoko/oauth-client
Public client SDK for Airsoko merchant shop OAuth — let customers sign in to your app with Airsoko consent.
Zero runtime dependencies. Works in any JavaScript environment; Next.js helpers are optional peer imports.
Install
npm install @airsoko/oauth-clientCreate an OAuth client (merchant admin)
Before wiring this package, register your app as an OAuth client in the Airsoko Merchant Admin panel:
- Sign in to your shop dashboard (Merchant Admin), e.g.
https://admin.airsoko.com. - Open Settings → OAuth clients (
/settings/oauth-clients). - Click Create client and fill in:
- Name — your app name (shown on the consent screen).
- Redirect URIs — one per line; must match your app exactly, e.g.
https://your-app.com/auth/airsoko/callback - Allowed scopes — typically
profile,email,customer:read(see the scope hint in the UI). - Client type —
confidentialfor server-side apps (recommended).
- Save the client ID and client secret when shown (secret is only displayed once; use Rotate secret if you lose it).
- Register the same redirect URI(s) you use in your app — mismatches will fail at callback.
Requires merchant permission Settings edit (SETTINGS_EDIT).
Environment
Paste credentials from the admin UI into your app:
NEXT_PUBLIC_AIRSOKO_API_BASE=https://api.airsoko.com
NEXT_PUBLIC_AIRSOKO_OAUTH_CLIENT_ID=your_client_id
AIRSOKO_OAUTH_CLIENT_SECRET=your_client_secret
NEXT_PUBLIC_AIRSOKO_OAUTH_REDIRECT_URI=https://your-app.com/auth/airsoko/callback
NEXT_PUBLIC_AIRSOKO_OAUTH_SCOPES=profile,email,customer:readAIRSOKO_OAUTH_CLIENT_SECRET is server-only — never expose it in client bundles.
Next.js — one catch-all page (recommended)
Create a single file; login and callback are handled automatically:
// pages/auth/airsoko/[[...slug]].tsx
export { default, getServerSideProps } from '@airsoko/oauth-client/next/pages'| URL | Action |
|-----|--------|
| /auth/airsoko/login | Starts OAuth (redirects to Airsoko consent) |
| /auth/airsoko/callback?code=… | Exchanges code, sets session cookie, redirects home |
| /auth/airsoko?code=… | Callback when redirect URI is the base path |
Register https://your-app.com/auth/airsoko/callback in the OAuth client redirect URIs in Merchant Admin.
Custom options
import { createAirsokoAuthPageHandlers } from '@airsoko/oauth-client/next/pages'
export const { default, getServerSideProps } = createAirsokoAuthPageHandlers({
basePath: '/auth/airsoko',
tokenCookieName: 'airsoko_access_token',
defaultRedirectPath: '/account',
})Next.js — API catch-all
// pages/api/auth/airsoko/[[...slug]].ts
import { createAirsokoAuthHandler } from '@airsoko/oauth-client/next/api'
export default createAirsokoAuthHandler({ basePath: '/auth/airsoko' })Set NEXT_PUBLIC_AIRSOKO_OAUTH_REDIRECT_URI to https://your-app.com/api/auth/airsoko/callback and add that URI in Merchant Admin.
Next.js App Router
// app/auth/airsoko/[...slug]/route.ts
import { createAirsokoAuthAppRouteHandlers } from '@airsoko/oauth-client/next/app'
export const { GET } = createAirsokoAuthAppRouteHandlers({ basePath: '/auth/airsoko' })Next.js middleware (protect routes)
Gate routes like /account or /author — unauthenticated visitors are redirected to /auth/airsoko/login and return after OAuth callback.
// middleware.ts (project root)
import { createAirsokoAuthMiddleware } from '@airsoko/oauth-client/next/middleware'
const { middleware, config: middlewareConfig } = createAirsokoAuthMiddleware({
protectedPaths: ['/account', '/author'],
})
export { middleware }
export const config = middlewareConfigOr split exports:
import { withAirsokoAuth, airsokoAuthMiddlewareConfig } from '@airsoko/oauth-client/next/middleware'
export const middleware = withAirsokoAuth({
protectedPaths: ['/account', '/author'],
})
export const config = airsokoAuthMiddlewareConfig({
protectedPaths: ['/account', '/author'],
})The middleware checks the airsoko_access_token cookie (set by the callback route). OAuth paths under /auth/airsoko stay public.
Sign-in button (React)
Use the built-in client button — click starts login, callback sets the cookie, user lands back on destinationUrl:
'use client' // App Router only
import { SignInWithAirsokoButton } from '@airsoko/oauth-client/react'
export function LoginCard() {
return (
<SignInWithAirsokoButton className='btn' destinationUrl='/account'>
Sign in with Airsoko
</SignInWithAirsokoButton>
)
}Or call the helper directly:
import { signInWithAirsoko } from '@airsoko/oauth-client'
<button type='button' onClick={() => signInWithAirsoko({ basePath: '/auth/airsoko' })}>
Sign in with Airsoko
</button>Requires the catch-all auth page (pages/auth/airsoko/[[...slug]].tsx) for login + callback.
Manual integration (any Node / server)
import {
buildAirsokoAuthorizeUrl,
createPkcePair,
createOAuthState,
exchangeAirsokoOAuthCode,
assertAirsokoOAuthServerConfig,
} from '@airsoko/oauth-client'
const config = assertAirsokoOAuthServerConfig()
const state = createOAuthState()
const pkce = await createPkcePair()
const authorizeUrl = buildAirsokoAuthorizeUrl({
...config,
state,
codeChallenge: pkce.codeChallenge,
codeChallengeMethod: pkce.codeChallengeMethod,
})
// After callback:
const token = await exchangeAirsokoOAuthCode({
code,
clientId: config.clientId,
clientSecret: config.clientSecret,
redirectUri: config.redirectUri,
apiBase: config.apiBase,
state,
codeVerifier: pkce.codeVerifier,
})Templates
Copy-ready examples ship in templates/:
templates/pages-auth-airsoko-catch-all.page.tsxtemplates/pages-auth-airsoko-catch-all.api.tstemplates/app-auth-airsoko-route.tstemplates/middleware.ts
Publish / build
npm run build # compile → dist/ (prints confirmation when done)
npm run rebuild # clean + full compile
npm publish --access public # prepublishOnly runs build firstdist/ is gitignored but included in the npm tarball via the files field.
First publish (@airsoko scope)
If publish fails with 404 Not Found - PUT @airsoko/oauth-client, the @airsoko npm organization does not exist yet or your account is not a member:
Log in:
npm loginCreate the org: npmjs.com/org/create → name
airsokoAdd your npm user as an owner/member of
@airsokoPublish again from this package directory:
cd packages/airsoko-oauth-client npm publish --access public
Verify login: npm whoami
License
MIT — see LICENSE.
