npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@meshagent/meshagent-react-auth

v0.40.2

Published

Meshagent React Auth Helpers

Readme

Meshagent React Auth

React helpers for browser OAuth login against Meshagent.

This package sits on top of @meshagent/meshagent-ts-auth and gives you React-friendly hooks for:

  • starting a PKCE OAuth redirect
  • exchanging the callback code for tokens
  • refreshing access tokens before protected requests
  • loading the current user profile into auth state
  • subscribing to auth state from React components

It is designed for browser React apps and does not require React Query or a provider wrapper.

Install

npm install @meshagent/meshagent-react-auth

If your app also imports lower-level auth primitives or the core Meshagent client directly, add those as direct dependencies too:

npm install @meshagent/meshagent-ts-auth @meshagent/meshagent

Before You Get Started

Create an OAuth client in Meshagent Studio and register your callback URL.

  1. Sign in to https://studio.meshagent.com.
  2. Select your project
  3. Open "OAuth Clients" at the bottom of the left menu
  4. Click "New OAuth Client" button at the top
  5. Add
    • name for the client id (e.g. "My App")
    • enter "email" for the scope
    • add redirect URIs (e.g. "http://localhost:3000/")
  6. Upon successful creation, you will see the client id and client secret. Click "Copy" button to copy the client id and client secret to clipboard. You will need them later when you run the app.

You will need these values throughout the examples:

  • oauthClientId: the OAuth client ID from Meshagent Studio
  • callbackUrl: the URL Meshagent redirects back to after login - this must match the redirect URI you registered in Studio

Optional

  • serverUrl: your Meshagent API base URL, uses https://api.meshagent.com as default

What This Package Exports

  • useAuth: main hook for login, callback handling, session refresh, and current-user loading
  • useLoginScope: compatibility alias for the older signed-in hook API
  • useEnsureLogin: compatibility alias for the older same-page login API
  • useMAuthResponse: callback hook that exchanges the OAuth authorization code
  • useMeshagentAuth: React subscription hook for auth state
  • buildOAuthAuthorizeUrl: manual helper for custom login launches

Typical Flow

  1. Render your app normally. No auth provider wrapper is required.
  2. For the simplest same-page flow, run useAuth(...) and read auth state with useMeshagentAuth().
  3. If you prefer a dedicated callback route, render useMAuthResponse(...) on that route and protect the rest of the app with useAuth(...).
  4. Read live auth state anywhere with useMeshagentAuth().

useAuth(...) defaults autoSignIn to true, so it will immediately launch the OAuth redirect when there is no session yet. Set autoSignIn: false when you want to show your own "Sign in" button.

Quick Start

Simplest Flow: useAuth(...)

Use useAuth(...) when you want the same component to handle both the initial login redirect and the callback return.

If you omit callbackUrl, it uses the current page as the callback URL and strips the OAuth query params after a successful return.

import {
  useAuth,
  useMeshagentAuth,
} from "@meshagent/meshagent-react-auth";

const oauthClientId = "YOUR_OAUTH_CLIENT_ID";

export function App(): JSX.Element {
  const { failed, refreshing, refresh } = useAuth({
    oauthClientId,
  });
  const auth = useMeshagentAuth();

  if (refreshing) {
    return <p>Signing you in...</p>;
  }

  if (failed) {
    return (
      <div>
        <p>Authentication failed: {String(failed)}</p>
        <button onClick={refresh}>Retry</button>
      </div>
    );
  }

  return <pre>{JSON.stringify(auth, null, 2)}</pre>;
}

useAuth(...) uses the default shared meshagentAuth store by default, but it also accepts custom auth and storage instances when you need them. useEnsureLogin(...) remains available as a compatibility alias for this same-page flow.

1. Handle The OAuth Callback

Use useMAuthResponse(...) on the route that matches your registered callback URL.

If you do not pass authorizationCode, the hook reads ?code=... from window.location.

import { useEffect } from "react";

import { useMAuthResponse } from "@meshagent/meshagent-react-auth";

// callbackUrl must match redirect URI registered in Studio, e.g. "http://localhost:3000/auth/callback"
const callbackUrl = new URL("/auth/callback", window.location.origin);
const oauthClientId = "YOUR_OAUTH_CLIENT_ID";

export function AuthCallbackPage(): JSX.Element {
  const { status, error } = useMAuthResponse({
    callbackUrl,
    oauthClientId,
  });

  useEffect(() => {
    if (status === "success") {
      window.location.replace("/");
    }
  }, [status]);

  if (status === "idle") {
    return <p>Missing authorization code.</p>;
  }

  if (status === "loading") {
    return <p>Signing you in...</p>;
  }

  if (status === "error") {
    return <p>Authentication failed: {error}</p>;
  }

  return <p>Login complete. Redirecting...</p>;
}

After a successful exchange, the hook stores the access token, refresh token, expiration, and current user in the underlying auth store.

2. Protect The Signed-In Part Of Your App

Use useAuth(...) anywhere you want to ensure that:

  • the user has a session
  • the access token is still valid enough
  • the current user profile has been loaded into auth state

The example below disables auto-redirect so the UI can show manual sign-in buttons.

import {
  useAuth,
  useMeshagentAuth,
} from "@meshagent/meshagent-react-auth";
import { meshagentAuth } from "@meshagent/meshagent-ts-auth";

const callbackUrl = new URL("/auth/callback", window.location.origin);
const oauthClientId = "YOUR_OAUTH_CLIENT_ID";

export function ProtectedApp(): JSX.Element {
  const {
    failed,
    isSigningIn,
    refreshing,
    signIn,
    refresh,
    user,
  } = useAuth({
    callbackUrl,
    oauthClientId,
    scope: "email",
    autoSignIn: false,
  });

  if (refreshing) {
    return <p>Checking session...</p>;
  }

  if (!user) {
    return (
      <div>
        {failed ? <p>Authentication failed: {String(failed)}</p> : null}

        <button onClick={() => void signIn()} disabled={isSigningIn}>
          Sign in
        </button>

        <button onClick={() => void signIn("google")} disabled={isSigningIn}>
          Continue with Google
        </button>

        <button onClick={refresh} disabled={isSigningIn}>
          Retry
        </button>
      </div>
    );
  }

  return <AuthenticatedHome />;
}

function AuthenticatedHome(): JSX.Element {
  const auth = useMeshagentAuth();

  return (
    <div>
      <p>Signed in.</p>
      <pre>{JSON.stringify(auth, null, 2)}</pre>
      <button onClick={() => meshagentAuth.signOut()}>Sign out</button>
    </div>
  );
}

If you want automatic redirect instead of a sign-in screen, omit autoSignIn:

const auth = useAuth({ callbackUrl, oauthClientId });

When there is no session, that hook will immediately start the OAuth redirect flow.

3. Read Auth State Anywhere

useMeshagentAuth() is the smallest hook in the package. It subscribes to the underlying auth store and returns the current snapshot:

import { useMeshagentAuth } from "@meshagent/meshagent-react-auth";

export function SessionDebugPanel(): JSX.Element {
  const auth = useMeshagentAuth();

  return <pre>{JSON.stringify(auth, null, 2)}</pre>;
}

The returned snapshot has this shape:

{
  accessToken: string | null;
  refreshToken: string | null;
  expiration: Date | null;
  user: Record<string, unknown> | null;
}

user is intentionally application-specific. Model it in your app instead of assuming fixed fields in shared code.

Example: Manual Authorize URL

Use buildOAuthAuthorizeUrl(...) when you want manual control over when and how the browser is redirected.

This helper also saves the PKCE verifier so that useMAuthResponse(...) can complete the callback exchange later.

import { buildOAuthAuthorizeUrl } from "@meshagent/meshagent-react-auth";

const serverUrl = "https://api.meshagent.com";
const callbackUrl = new URL("/auth/callback", window.location.origin);
const oauthClientId = "YOUR_OAUTH_CLIENT_ID";

export async function signInWithGoogle(): Promise<void> {
  const authorizeUrl = await buildOAuthAuthorizeUrl({
    serverUrl,
    callbackUrl,
    oauthClientId,
    scope: "email",
    provider: "google",
    extraQueryParams: {
      invitation: "abc123",
    },
  });

  window.location.assign(authorizeUrl.toString());
}

If you pass custom auth or storage, use the same instances in both the login-launch side and the callback side. Passing storage alone changes PKCE verifier storage. Session persistence follows the auth instance you use.

API Reference

useAuth(options)

Primary auth hook for browser login flows.

What it does:

  • launches the browser OAuth redirect when there is no session yet
  • exchanges the callback code when the current URL matches the callback URL
  • loads the current user into auth state
  • refreshes the access token when needed before protected requests
  • signs out automatically if token refresh fails
  • signs out automatically if profile loading returns 401 or 403
  • strips OAuth query params from the current URL after a successful callback exchange
  • dedupes duplicate effect runs for the same login attempt

Important options:

  • oauthClientId: required OAuth client ID
  • serverUrl: optional Meshagent base URL, defaults to https://api.meshagent.com
  • callbackUrl: optional callback URL, defaults to the current page
  • scope: optional OAuth scope, defaults to "profile"
  • provider: optional provider slug to pass through to /oauth/authorize
  • extraQueryParams: optional extra query params for /oauth/authorize
  • storage: optional custom storage for PKCE verifier caching
  • auth: optional custom MeshagentAuth instance
  • autoSignIn: optional, defaults to true

Returned fields:

| Field | Meaning | | --- | --- | | failed | Most recent error, or null | | isCancelled | Currently always false in this browser redirect implementation | | isSigningIn | true while a sign-in launch is in progress | | refreshing | true while callback exchange, session validation, or profile loading is running | | user | Current user from auth state, or null | | signIn(provider?) | Starts the OAuth redirect, optionally forcing a provider | | refresh() | Re-runs the auth flow | | isLoginLaunched | Useful for deciding when to show login or retry UI |

useAuth(...) replaces the overlap between useEnsureLogin(...) and useLoginScope(...). Both legacy names still exist as wrappers for compatibility.

Legacy Aliases

useEnsureLogin(options) is a compatibility wrapper over useAuth(...) for the old same-page login API. It still returns:

| Field | Meaning | | --- | --- | | status | "loading", "success", or "error" | | error | Error message string, or null | | refresh() | Re-runs the auth flow |

useLoginScope(options) is a compatibility wrapper over useAuth(...) for the older signed-in hook API. It returns the same fields as useAuth(...), while keeping callbackUrl required and preserving its previous default scope behavior.

useMAuthResponse(props)

Hook for your OAuth callback route.

What it does:

  • reads the authorization code from authorizationCode or the current URL
  • exchanges the code at /oauth/token
  • stores access token, refresh token, and expiration in auth state
  • loads the current user profile
  • stores that user in auth state

It does not navigate away after success. Redirect to the rest of your app yourself. If you used custom storage for the PKCE verifier during login launch, pass that same storage here.

Return value:

| status | Meaning | | --- | --- | | "idle" | No authorization code was found | | "loading" | Token exchange is in progress | | "success" | Exchange and profile load completed | | "error" | Exchange failed |

The returned error is the message string from the failed query, or null.

useMeshagentAuth(auth?)

Subscribes to a MeshagentAuth store with useSyncExternalStore and returns the current snapshot.

Use this anywhere you want React components to update when tokens, expiration, or user state changes.

buildOAuthAuthorizeUrl(params)

Builds the /oauth/authorize URL and stores a PKCE verifier before redirect.

Supported parameters:

  • serverUrl
  • callbackUrl
  • oauthClientId
  • scope
  • provider
  • extraQueryParams
  • storage

Use this helper when the default signIn() behavior is too opinionated and you need manual redirect control. storage here controls where the PKCE verifier is cached before the redirect.

Notes

  • This package is for browser redirect-based OAuth flows. useAuth(...) and its legacy aliases will throw if they try to launch login outside a browser environment.
  • No provider wrapper is required. useAuth(...), useEnsureLogin(...), useLoginScope(...), and useMAuthResponse(...) manage their own async state.
  • useMAuthResponse(...) does not clear the code query parameter or navigate after success. Most apps should redirect away from the callback page after status === "success".
  • Sign-out functionality lives in @meshagent/meshagent-ts-auth, for example meshagentAuth.signOut().
  • If you need the low-level primitives directly, see @meshagent/meshagent-ts-auth. This package is the React layer on top of it.