Skip to main content

Hydrogen with account component

Follow this guide to add the <shopify-account> component to your Hydrogen storefront, allowing customers to sign in and stay on the storefront, or navigate directly to customer account pages from the storefront.



Anchor to Step 1: Enable API permissionsStep 1: Enable API permissions

This requires setting the public-access-token attribute on your <shopify-store> component.

In your store's Shopify admin, open the Hydrogen app. Then select your Hydrogen storefront and navigate to Storefront settings > Storefront API.

Confirm that your Hydrogen app has the following Storefront API permissions:

  • unauthenticated_read_customers
  • unauthenticated_read_content
  • unauthenticated_read_product_listings

Anchor to Step 2: Pass tokens to the account componentStep 2: Pass tokens to the account component

To use the <shopify-account> component, you must provide the following two tokens:

In /app/root.jsx, replace the loader function with the following implementation. This passes publicAccessToken and customerAccessToken to downstream components.

/app/root.jsx

export async function loader(args) {
// Start fetching non-critical data without blocking time to first byte
const deferredData = loadDeferredData(args);

// Await the critical data required to render initial state of the page
const criticalData = await loadCriticalData(args);

const {storefront, env, customerAccount} = args.context;

// Try to get customer access token if logged in (for shopify-account web component)
let customerAccessToken = null;
try {
const isLoggedIn = await customerAccount.isLoggedIn();
if (isLoggedIn) {
customerAccessToken = await customerAccount.getAccessToken();
}
} catch (error) {
// Customer not logged in - that's fine
customerAccessToken = null;
}

return {
...deferredData,
...criticalData,
publicStoreDomain: env.PUBLIC_STORE_DOMAIN,
publicAccessToken: env.PUBLIC_STOREFRONT_API_TOKEN,
customerAccessToken,
shop: getShopAnalytics({
storefront,
publicStorefrontId: env.PUBLIC_STOREFRONT_ID,
}),
consent: {
checkoutDomain: env.PUBLIC_CHECKOUT_DOMAIN,
storefrontAccessToken: env.PUBLIC_STOREFRONT_API_TOKEN,
withPrivacyBanner: false,
// localize the privacy banner
country: args.context.storefront.i18n.country,
language: args.context.storefront.i18n.language,
},
};
}

In the /app/components/PageLayout.jsx file, replace PageLayout function as following code:

/app/components/PageLayout.jsx

/**
* @param {PageLayoutProps}
*/
export function PageLayout({
cart,
children = null,
footer,
header,
isLoggedIn,
publicStoreDomain,
publicAccessToken,
customerAccessToken,
}) {
return (
<Aside.Provider>
<CartAside cart={cart} />
<SearchAside />
<MobileMenuAside header={header} publicStoreDomain={publicStoreDomain} />
{header && (
<Header
header={header}
cart={cart}
isLoggedIn={isLoggedIn}
publicStoreDomain={publicStoreDomain}
publicAccessToken={publicAccessToken}
customerAccessToken={customerAccessToken}
/>
)}
<main>{children}</main>
<Footer
footer={footer}
header={header}
publicStoreDomain={publicStoreDomain}
/>
</Aside.Provider>
);
}

Near the bottom of /app/components/PageLayout.jsx, you should see * @property {string} publicStoreDomain. Add the following property types:

/app/components/PageLayout.jsx

* @property {string} publicAccessToken
* @property {string|null} customerAccessToken

Anchor to Step 3: Load the account JavaScript bundle and add the account componentStep 3: Load the account JavaScript bundle and add the account component

The <shopify-account> component bundle isn't included in the default Hydrogen storefront. Before using the component, be sure to load its dedicated bundle (https://cdn.shopify.com/storefront/web-components/account.js).

In /app/root.jsx, import Script from @shopify/hydrogen and add the following <Script> tag inside the <head> of the Layout component:

/app/root.jsx

import {useNonce, getShopAnalytics, Analytics, Script} from '@shopify/hydrogen';

...

export function Layout({children}) {
const nonce = useNonce();
const data = useRouteLoaderData('root');

return (
<html lang="en">
<head>
<meta charSet="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<link rel="stylesheet" href={resetStyles}></link>
<link rel="stylesheet" href={appStyles}></link>
<Meta />
<Links />
<Script
src="https://cdn.shopify.com/storefront/web-components/account.js"
type="module"
crossOrigin="anonymous"
/>
</head>
{/* ... */}
</html>
);
}

In /app/components/Header.jsx, replace the Header function with the following code:

/app/components/Header.jsx

/**
* @param {HeaderProps}
*/
export function Header({
header,
isLoggedIn,
cart,
publicStoreDomain,
publicAccessToken,
customerAccessToken,
}) {
const {shop, menu} = header;

return (
<header className="header">
<NavLink prefetch="intent" to="/" style={activeLinkStyle} end>
<strong>{shop.name}</strong>
</NavLink>
<HeaderMenu
menu={menu}
viewport="desktop"
primaryDomainUrl={header.shop.primaryDomain.url}
publicStoreDomain={publicStoreDomain}
/>
<HeaderCtas
cart={cart}
publicStoreDomain={publicStoreDomain}
publicAccessToken={publicAccessToken}
customerAccessToken={customerAccessToken}
/>
</header>
);
}

...

export function HeaderMenu({
...
})

In the middle of /app/components/Header.jsx file, replace the HeaderCtas function with the code below so we can replace the default Sign In with the <shopify-account> component.

  • sign-in-url: The URL you provide in the sign-in-url attribute should point to the page that initiates the authorization request. In Hydrogen, the default path is /account/login.

/app/components/Header.jsx

export function Header({
header,
isLoggedIn,
cart,
publicStoreDomain,
publicAccessToken,
customerAccessToken,
}) {
...
}

/**
* @param {{
* cart: HeaderProps['cart'];
* publicStoreDomain: string;
* publicAccessToken: string;
* customerAccessToken: string | null;
* }}
*/
function HeaderCtas({cart, publicStoreDomain, publicAccessToken, customerAccessToken}) {
return (
<nav className="header-ctas" role="navigation">
<HeaderMenuMobileToggle />
{/* Shopify Account Web Component */}
<shopify-store
store-domain={publicStoreDomain}
public-access-token={publicAccessToken}
customer-access-token={customerAccessToken}
>
<shopify-account sign-in-url="/account/login" />
</shopify-store>
<SearchToggle />
<CartToggle cart={cart} />
</nav>
);
}

Near the bottom of /app/components/Header.jsx, you should see * @property {string} publicStoreDomain. Add the following property types:

/app/components/Header.jsx

function HeaderCtas({cart, publicStoreDomain, publicAccessToken, customerAccessToken}) {
...
}

* @property {string} publicAccessToken
* @property {string|null} customerAccessToken

You can style the <shopify-account> component to match your storefront. For details, please refer to this documentation.


Anchor to Step 4: Handle login URL parametersStep 4: Handle login URL parameters

As of version 2025.7.3 of @shopify/hydrogen, we've introduced additional options to improve the login experience. You can learn more here.

If your Hydrogen storefront was created recently, you don't have to do anything else.

If you're using @shopify/hydrogen earlier than 2025.7.3, upgrade to the latest version. Then update the loader function in /app/routes/account_.login.jsx as shown below.

/app/routes/account_.login.jsx

export async function loader({request, context}) {
const url = new URL(request.url);
const acrValues = url.searchParams.get('acr_values') || undefined;
const loginHint = url.searchParams.get('login_hint') || undefined;
const loginHintMode = url.searchParams.get('login_hint_mode') || undefined;
const locale = url.searchParams.get('locale') || undefined;

return context.customerAccount.login({
countryCode: context.storefront.i18n.country,
acrValues,
loginHint,
loginHintMode,
locale,
});
}

Anchor to Step 5: Deploy your code to production OxygenStep 5: Deploy your code to production Oxygen

The Customer Account API doesn't support localhost, so you'll need to deploy your code before testing this feature. Commit your changes and run the following command to deploy:

Terminal

npx shopify hydrogen deploy

After deployment, open your production Hydrogen storefront—you should see the account component present.


Was this page helpful?