Setup
There are a few configuration things to setup when using the Recharge JavaScript SDK with Hydrogen. This page with guide you through them.
Dependencies
Add @rechargeapps/storefront-client
to your project:
- NPM
- Yarn
- PNPM
npm install @rechargeapps/storefront-client
yarn add @rechargeapps/storefront-client
pnpm add @rechargeapps/storefront-client
Config changes
Hydrogen may automatically add these for you when you run npm run dev
the first time. However if you get a ReferenceError: require is not defined
and your vite.config.js
file doesn't have these entries you may need to add them manually.
ssr: {
optimizeDeps: {
include: [
'lodash.partial',
'lodash.omit',
'js-xdr',
'qs/lib/stringify',
'isomorphic-fetch',
],
},
},
Environment variables
Add your Recharge Storefront Access Token
as an environment variable to your .env
file.
PUBLIC_RECHARGE_STOREFRONT_ACCESS_TOKEN=strfnt_...
RechargeSession
Add a rechargeSession
module that can be used to store the Recharge Session in your app. This uses secure cookie storage but can be customized to support other implementations.
- JavaScript
- TypeScript
/app/lib/rechargeSession.server.js
import { createCookieSessionStorage } from '@shopify/remix-oxygen';
// Recharge session is good for 60 minutes so set to 55 minutes to avoid race conditions
const RECHARGE_SESSION_DURATION = 60 * 55;
/**
* This is a custom session implementation for your Hydrogen shop.
* Feel free to customize it to your needs, add helper methods, or
* swap out the cookie-based implementation with something else!
*/
export class RechargeSession {
public isPending = false;
#sessionStorage;
#session;
/**
* @param {SessionStorage} sessionStorage
* @param {Session} session
*/
constructor(sessionStorage, session) {
this.#sessionStorage = sessionStorage;
this.#session = session;
}
/**
* @static
* @param {Request} request
* @param {string[]} secrets
*/
static async init(request, secrets) {
const storage = createCookieSessionStorage({
cookie: {
name: 'session_recharge',
httpOnly: true,
path: '/',
sameSite: 'lax',
secrets,
maxAge: RECHARGE_SESSION_DURATION,
},
});
const session = await storage.getSession(request.headers.get('Cookie')).catch(() => storage.getSession());
return new this(storage, session);
}
get has() {
return this.#session.has;
}
get get() {
return this.#session.get;
}
get flash() {
return this.#session.flash;
}
get unset() {
this.isPending = true;
return this.#session.unset;
}
get set() {
this.isPending = true;
return this.#session.set;
}
destroy() {
return this.#sessionStorage.destroySession(this.#session);
}
commit() {
this.isPending = false;
return this.#sessionStorage.commitSession(this.#session);
}
}
/app/lib/rechargeSession.server.ts
import { type HydrogenSession } from '@shopify/hydrogen';
import { createCookieSessionStorage, type SessionStorage, type Session } from '@shopify/remix-oxygen';
// Recharge session is good for 60 minutes so set to 55 minutes to avoid race conditions
const RECHARGE_SESSION_DURATION = 60 * 55;
/**
* This is a custom session implementation for your Hydrogen shop.
* Feel free to customize it to your needs, add helper methods, or
* swap out the cookie-based implementation with something else!
*/
export class RechargeSession implements HydrogenSession {
public isPending = false;
#sessionStorage;
#session;
constructor(sessionStorage: SessionStorage, session: Session) {
this.#sessionStorage = sessionStorage;
this.#session = session;
}
static async init(request: Request, secrets: string[]) {
const storage = createCookieSessionStorage({
cookie: {
name: 'session_recharge',
httpOnly: true,
path: '/',
sameSite: 'lax',
secrets,
maxAge: RECHARGE_SESSION_DURATION,
},
});
const session = await storage.getSession(request.headers.get('Cookie')).catch(() => storage.getSession());
return new this(storage, session);
}
get has() {
return this.#session.has;
}
get get() {
return this.#session.get;
}
get flash() {
return this.#session.flash;
}
get unset() {
this.isPending = true;
return this.#session.unset;
}
get set() {
this.isPending = true;
return this.#session.set;
}
destroy() {
return this.#sessionStorage.destroySession(this.#session);
}
commit() {
this.isPending = false;
return this.#sessionStorage.commitSession(this.#session);
}
}
Typings
If using TypeScript add PUBLIC_RECHARGE_STOREFRONT_ACCESS_TOKEN
and rechargeSession
in env.d.ts
.
/// <reference types="vite/client" />
/// <reference types="@shopify/remix-oxygen" />
/// <reference types="@shopify/oxygen-workers-types" />
// Enhance TypeScript's built-in typings.
import '@total-typescript/ts-reset';
import type { HydrogenContext, HydrogenSessionData, HydrogenEnv } from '@shopify/hydrogen';
import type { createAppLoadContext } from '~/lib/context';
import { RechargeSession } from '~/lib/rechargeSession.server';
declare global {
/**
* A global `process` object is only available during build to access NODE_ENV.
*/
const process: { env: { NODE_ENV: 'production' | 'development' } };
interface Env extends HydrogenEnv {
// declare additional Env parameter use in the fetch handler and Remix loader context here
PUBLIC_RECHARGE_STOREFRONT_ACCESS_TOKEN: string;
}
}
declare module '@shopify/remix-oxygen' {
interface AppLoadContext extends Awaited<ReturnType<typeof createAppLoadContext>> {
// to change context type, change the return of createAppLoadContext() instead
rechargeSession: RechargeSession;
}
interface SessionData extends HydrogenSessionData {
// declare local additions to the Remix session data here
}
}