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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@tidecloak/react

v0.12.43

Published

TideCloak client-side React SDK

Downloads

704

Readme

TideCloak React SDK

Quick Start Guide

If you're new to TideCloak, the fastest way to get started with React + Vite is to follow our official Getting Started guide: https://github.com/tide-foundation/tidecloak-gettingstarted


Secure your React app with TideCloak: authentication, session management, data encryption, and role-based access.


1. Prerequisites

Before you begin, ensure you have the following:

  • React 18 or later
  • Node.js ≥18.17.0
  • A running TideCloak server you have admin control over
  • IGA enabled realm
  • A registered client in your realm with default user contexts approved and committed
  • A valid Tidecloak adapter JSON file (e.g., tidecloakAdapter.json)

2. Install @tidecloak/react

Add the TideCloak React SDK to your project:

npm install @tidecloak/react
# or
yarn add @tidecloak/react

This bundle provides:

  • <TideCloakContextProvider> - application-level context
  • useTideCloak() hook - access tokens and auth actions
  • <Authenticated> / <Unauthenticated> - UI guards
  • doEncrypt() / doDecrypt() - tag-based encryption/decryption

Note: Installing this package automatically adds a silent-check-sso.html file to your public directory. This file is required for silent SSO checks; if it doesn't exist, create it manually at public/silent-check-sso.html with the following content, otherwise the app will break:

<html>
  <body>
    <script>parent.postMessage(location.href, location.origin)</script>
  </body>
</html>

3. Initialize the Provider

Wrap your app's root with <TideCloakContextProvider> to enable authentication context throughout the component tree.

If you're using React Router, your setup might look like this:

File: src/App.tsx

import React from 'react';
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import { TideCloakContextProvider } from '@tidecloak/react';
import adapter from '../tidecloakAdapter.json';
import Home from './pages/Home';
import RedirectPage from './pages/auth/RedirectPage';

export default function App() {
  return (
    <TideCloakContextProvider config={adapter}>
      <BrowserRouter>
        <Routes>
          <Route path="/" element={<Home />} />
          <Route path="/auth/redirect" element={<RedirectPage />} />
          {/* Add additional routes here */}
        </Routes>
      </BrowserRouter>
    </TideCloakContextProvider>
  );
}

⚠️ If you don't define a route at /auth/redirect, and you're using the default redirectUri, your app will break after login/logout. Either create this route or override redirectUri in the provider config.

If you override the redirectUri, you must ensure that the custom path exists in your router. Otherwise, the app will redirect to a non-existent route and fail.


4. Redirect URI Handling

TideCloak supports an optional redirectUri config field. This defines where the user is sent after login/logout.

If omitted, it defaults to:

`${window.location.origin}/auth/redirect`

Example: If your app runs at http://localhost:3000, then by default the redirect path is http://localhost:3000/auth/redirect.

You must create this route if you use the default, or explicitly override it:

<TideCloakContextProvider config={{ ...adapter, redirectUri: 'https://yourapp.com/auth/callback' }}>
  <YourApp />
</TideCloakContextProvider>

⚠️ If you override the redirectUri, make sure the specified path exists in your app. Missing this route will cause failed redirects.

Example: Redirect Handling Page

File: src/pages/auth/RedirectPage.tsx

import { useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import { useTideCloak } from '@tidecloak/react';

export default function RedirectPage() {
  const { authenticated, isInitializing, logout } = useTideCloak();
  const navigate = useNavigate();

  useEffect(() => {
    const params = new URLSearchParams(window.location.search);
    if (params.get("auth") === "failed") {
      sessionStorage.setItem("tokenExpired", "true");
      logout();
    }
  }, []);

  useEffect(() => {
    if (!isInitializing) {
      navigate(authenticated ? '/home' : '/');
    }
  }, [authenticated, isInitializing, navigate]);

  return (
    <div style={{
      minHeight: '100vh',
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'center',
      fontSize: '1rem',
      color: '#555',
    }}>
      <p>Waiting for authentication...</p>
    </div>
  );
}

Description: This page helps finalize the login or logout flow, and also reacts to token expiration events that may have triggered a redirect. It's required if you're using the default redirectUri. If you override the redirect URI, the file is optional-but the route for the redirect must still exist in your app.


5. Using the useTideCloak Hook

Use this hook anywhere in your component tree to manage authentication:

import { useTideCloak } from '@tidecloak/react';

function Header() {
  const {
    authenticated,
    login,
    logout,
    token,
    tokenExp,
    refreshToken,
    getValueFromToken,
    getValueFromIdToken,
    hasRealmRole,
    hasClientRole,
    doEncrypt,
    doDecrypt,
  } = useTideCloak();

  return (
    <header>
      {authenticated ? (
        <>
          <span>Logged in</span>
          <button onClick={logout}>Log Out</button>
        </>
      ) : (
        <button onClick={login}>Log In</button>
      )}
      {token && (
        <small>Expires at {new Date(tokenExp * 1000).toLocaleTimeString()}</small>
      )}
    </header>
  );
}

| Name | Type | Description | | ------------------------------------- | -------------------------------------------- | ----------------------------------------------------------------------- | | authenticated | boolean | Whether the user is logged in. | | login() / logout() | () => void | Trigger the login or logout flows. | | token, tokenExp | string, number | Access token and its expiration timestamp. | | Automatic token refresh | built-in | Tokens refresh silently on expiration-no manual setup needed. | | refreshToken() | () => Promise<boolean> | Force a silent token renewal. | | getValueFromToken(key) | (key: string) => any | Read a custom claim from the access token. | | getValueFromIdToken(key) | (key: string) => any | Read a custom claim from the ID token. | | hasRealmRole(role) | (role: string) => boolean | Check a realm-level role. | | hasClientRole(role, client?) | (role: string, client?: string) => boolean | Check a client-level role; defaults to your app's client ID if omitted. | | doEncrypt(data) / doDecrypt(data) | (data: any) => Promise<any> | Encrypt or decrypt payloads via TideCloak's built-in service. |


6. Guard Components

Use these components to show or hide content based on authentication state:

import { Authenticated, Unauthenticated } from '@tidecloak/react';

function Dashboard() {
  return (
    <>
      <Authenticated>
        <h1>Dashboard</h1>
        {/* Protected widgets */}
      </Authenticated>

      <Unauthenticated>
        <p>Please log in to access the dashboard.</p>
      </Unauthenticated>
    </>
  );
}
  • <Authenticated>: renders children only when authenticated === true
  • <Unauthenticated>: renders children only when authenticated === false

7. Encrypting & Decrypting Data

Protect sensitive payloads using tag-based encryption/decryption:

// Encrypt:
const encryptedArray = await doEncrypt([
  { data: { email: '[email protected]' }, tags: ['email'] },
]);

// Decrypt:
const decryptedArray = await doDecrypt([
  { encrypted: encryptedArray[0], tags: ['email'] },
]);

Important: The data property must be either a string or a Uint8Array (raw bytes).
When you encrypt a string, decryption returns a string.
When you encrypt a Uint8Array, decryption returns a Uint8Array.

Valid example:

// Before testing below, ensure you've set up the necessary roles:
const multi_encrypted_addresses = await doEncrypt([
  {
    data: "10 Smith Street",
    tags: ["street"]
  },
  {
    data: "Southport",
    tags: ["suburb"]
  },
  {
    data: "20 James Street - Burleigh Heads",
    tags: ["street", "suburb"]
  }
]);

Invalid (will fail):

// Prepare data for encryption
const dataToEncrypt = {
  title: noteData.title,
  content: noteData.content
};

// Encrypt the note data using TideCloak (this will error)
const encryptedArray = await doEncrypt([{ data: dataToEncrypt, tags: ['note'] }]);

Permissions: Encryption requires _tide_<tag>.selfencrypt; decryption requires _tide_<tag>.selfdecrypt.

Order guarantee: Output preserves input order.


8. Advanced & Best Practices

  • Auto-Refresh: built-in, no manual timer setup required
  • Error Handling: check initError from useTideCloak
  • Custom Claims: access token fields with getValueFromToken() / getValueFromIdToken()
  • Role-Based UI: combine hasRealmRole, hasClientRole, and guard components
  • Lazy Initialization: optionally wrap <TideCloakContextProvider> around only protected routes