Authentication & Session
To authenticate customers with the Recharge JavaScript SDK we will create a utility that validates the customer's session and logs into Recharge as needed and stores the Recharge Session via the rechargeSession.server module we previously setup.
Query & Login Utility Function
Create a rechargeUtil.ts module where we can add a couple utility functions.
loginRecharge- function encapsulating logic for logging into Recharge and getting a RechargeSessionrechargeQueryWrapperto help with data fetching (which is covered in the next section). This helper function handles any needed login retries or/and error handlingclearSession- function to clear the RechargeSession
- JavaScript
 - TypeScript
 
/app/lib/rechargeUtils.js
import { loginWithShopifyCustomerAccount } from '@rechargeapps/storefront-client';
import { json } from '@shopify/remix-oxygen';
const RECHARGE_SESSION_KEY = 'rechargeSession';
// loginHelper function
async function loginRecharge(context) {
  const customerAccessToken = await context.customerAccount.getAccessToken();
  const rechargeSession = await loginWithShopifyCustomerAccount(customerAccessToken);
  if (rechargeSession) {
    context.rechargeSession.set(RECHARGE_SESSION_KEY, rechargeSession);
  } else {
    // this should match your catch boundary
    throw json('No session created', { status: 400 });
  }
  return rechargeSession;
}
// helper function for data fetching
export async function rechargeQueryWrapper(rechargeFn, context) {
  let rechargeSession = context.rechargeSession.get(RECHARGE_SESSION_KEY);
  if (!rechargeSession) {
    rechargeSession = await loginRecharge(context);
  }
  try {
    return await rechargeFn(rechargeSession);
  } catch (e) {
    try {
      if (e?.status === 401) {
        // handle auth error, login again and retry request
        rechargeSession = await loginRecharge(context);
        return await rechargeFn(rechargeSession);
      }
      // this should match your catch boundary
      throw json(e.message, { status: e?.status });
    } catch (error) {
      // this should match your catch boundary
      throw json(e.message, { status: e?.status });
    }
  }
}
// helper function to clear session
export function clearSession(session) {
  session.unset(RECHARGE_SESSION_KEY);
}
/app/lib/rechargeUtils.ts
import { loginWithShopifyCustomerAccount } from '@rechargeapps/storefront-client';
import { json } from '@shopify/remix-oxygen';
import type { Session } from '@rechargeapps/storefront-client';
import type { AppLoadContext } from '@shopify/remix-oxygen';
import type { RechargeSession } from './rechargeSession.server';
const RECHARGE_SESSION_KEY = 'rechargeSession';
// loginHelper function
async function loginRecharge(context: AppLoadContext) {
  const customerAccessToken = await context.customerAccount.getAccessToken();
  const rechargeSession = await loginWithShopifyCustomerAccount(customerAccessToken);
  if (rechargeSession) {
    context.rechargeSession.set(RECHARGE_SESSION_KEY, rechargeSession);
  } else {
    // this should match your catch boundary
    throw json('No session created', { status: 400 });
  }
  return rechargeSession;
}
// helper function for data fetching
export async function rechargeQueryWrapper<T>(
  rechargeFn: (session: Session) => Promise<T>,
  context: AppLoadContext
): Promise<T> {
  let rechargeSession = context.rechargeSession.get(RECHARGE_SESSION_KEY);
  if (!rechargeSession) {
    rechargeSession = await loginRecharge(context);
  }
  try {
    return await rechargeFn(rechargeSession);
  } catch (e: any) {
    try {
      if (e?.status === 401) {
        // handle auth error, login again and retry request
        rechargeSession = await loginRecharge(context);
        return await rechargeFn(rechargeSession);
      }
      // this should match your catch boundary
      throw json(e.message, { status: e?.status });
    } catch (error) {
      // this should match your catch boundary
      throw json(e.message, { status: e?.status });
    }
  }
}
// helper function to clear session
export function clearSession(session: RechargeSession) {
  session.unset(RECHARGE_SESSION_KEY);
}
Handle logout
Update logout function to clear the rechargeSession.
- JavaScript
 - TypeScript
 
/app/routes/account_.logout.jsx
export async function action({ context }) {
  clearSession(context.rechargeSession);
  return context.customerAccount.logout();
}
/app/routes/account_.logout.tsx
export async function action({ context }: ActionFunctionArgs) {
  clearSession(context.rechargeSession);
  return context.customerAccount.logout();
}