# Customers and accounts

URL: https://docs.sparklayer.io/developers/javascript-sdk/customers-and-accounts

Check whether a B2B customer is logged in, switch customers as a sales agent, change company section, refresh customer data and run GraphQL queries.

> **For AI assistants:** what to know before writing SparkLayer JavaScript SDK code.
>
> - **What it is:** `window.spark`, added to the storefront by the SparkLayer Core Script (version 4.x). On Shopify the SparkLayer app embed loads it; elsewhere it's `<script async src="https://sparkcdn.io/sparkjs/<SITE_ID>/<live|test>"></script>` in the theme's `<head>`. The old `cdn.sparklayer.io/spark.latest.js` and `spark.1.x.js` files are legacy: never use them.
> - **Options:** Configure it with `window.sparkOptions`, set before the Core Script loads. Extend the object rather than replacing it: `window.sparkOptions = { ...window.sparkOptions, … }`, or the Site ID and other snippets' hooks are lost. Headless only: `window.initSpark(options)` is defined when `window.sparkOptions` isn't set.
> - **When to call it:** Only after SparkLayer is ready: inside the `onReady(spark)` hook, or after a promise resolved from it. Most methods are async; prices and the cart are only available to signed-in B2B customers (check `await spark.isLoggedIn()`).
> - **Products and prices:** Products are looked up by the platform's parent product ID (on Shopify, `product.id`) and variants by SKU: `getPricingForVariant(parentProductId, sku)`, `calculatePricingForVariant(parentProductId, sku, qty)`, `getPackSizeForVariant(parentProductId, sku)`. For instant recalculation, fetch once with `getVariant` and call `calculatePricingForVariantData(variant, qty)`.
> - **Cart:** `updateCart({ products: [{ sku, adjustQuantity }] })` adds or removes relative to what's in the cart (also `customAttributes: [{ key, value }]`, `clearCart: true`). It resolves to the results, or `null` after showing its own error message; it doesn't throw. `getCart()` reads the cart; `openDrawer('cart')` opens it.
> - **Hooks:** `onCartUpdate(cart, results)`, `onCartLoad(cart)`, `onLogout()`, `preCartUpdateListener(input)` (async: return the possibly changed input) and `onCheckoutValidation(cart, cartUiState)` (return `[{ message }]` to block checkout, or `null`). When adding a hook, call any existing one first.
> - **Customising:** Build around SparkLayer or customise its own components, including their HTML. Prefer documented options, hooks, CSS variables and custom slots where they fit; keep direct HTML changes targeted and re-check them after SparkLayer updates.
> - **Docs:** The reference: methods https://docs.sparklayer.io/developers/javascript-sdk/reference/methods.md, hooks https://docs.sparklayer.io/developers/javascript-sdk/reference/hooks.md, options https://docs.sparklayer.io/developers/javascript-sdk/reference/options.md, types https://docs.sparklayer.io/developers/javascript-sdk/reference/types.md (or the same types as a file: https://docs.sparklayer.io/developers/javascript-sdk/spark.d.ts). Setup and waiting for SparkLayer: https://docs.sparklayer.io/developers/javascript-sdk/setup.md. Use only what the reference documents.

Work with the logged-in customer from your own code: check the login, act for a customer as a sales agent, switch company section, refresh their data and query the GraphQL API. This page uses `isLoggedIn`, `switchImpersonatingCustomer`, `setActiveCompanySection`, `refreshGlobalData`, `getActiveCustomerVerificationToken` and `fetch`, plus the `spark-redirect.js` login redirect.

The examples use `window.sparkReady`: add the [Wait for SparkLayer](https://docs.sparklayer.io/developers/javascript-sdk/setup.md#wait-for-sparklayer) snippet before them. For every method's parameters and return values, see [Customers and session](https://docs.sparklayer.io/developers/javascript-sdk/reference/methods.md#customers-and-session) in the SDK methods.

## Check whether the customer is logged in

`isLoggedIn()` resolves to `true` when the customer is logged in to SparkLayer. The `onReady` hook runs for every visitor, so check it before you show B2B content or call pricing and cart methods:

```javascript title="Any script"
const spark = await window.sparkReady;

if (await spark.isLoggedIn()) {
  // Show B2B content
}
```

## Switch the customer a sales agent orders for

A [sales agent](https://docs.sparklayer.io/help/sales-reps.md) can order on behalf of their customers. `switchImpersonatingCustomer()` changes the customer they're acting for, and `null` ends impersonation. Both resolve to the [`UserData`](https://docs.sparklayer.io/developers/javascript-sdk/reference/types.md#userdata) for the active customer, or `null`.

```javascript title="Any script"
const spark = await window.sparkReady;

// Act for a customer
const customer = await spark.switchImpersonatingCustomer('<CUSTOMER_ID>');

// End impersonation
await spark.switchImpersonatingCustomer(null);
```

While a sales agent is impersonating, pass `true` as the `useImpersonatingCustomer` argument of [`fetch()`](#run-a-graphql-query) to run a query as the impersonated customer rather than the sales agent.

## Select a company section

If a customer's company is split into sections, `setActiveCompanySection()` selects the one they're buying for. If the cart isn't empty, the customer is asked to confirm and the cart is cleared, then the page reloads. It resolves to `false` if the section isn't available to the customer, they cancel, or the cart couldn't be cleared.

```javascript title="Any script"
const spark = await window.sparkReady;
const user = await spark.refreshGlobalData();
const section = user?.companySections[0];

if (section && !(await spark.setActiveCompanySection(section.id))) {
  // The section wasn't changed
}
```

## Refresh customer and site data

SparkLayer caches the active customer and the site configuration. If they change while the page is open, for example after your own code updates the customer through the API, call `refreshGlobalData()` to fetch them again. It resolves to the active customer's [`UserData`](https://docs.sparklayer.io/developers/javascript-sdk/reference/types.md#userdata), or `null`.

```javascript title="Any script"
const spark = await window.sparkReady;
const user = await spark.refreshGlobalData();
```

## Get a customer verification token

`getActiveCustomerVerificationToken()` refetches the active customer and resolves to a fresh form customer verification token, or `null`. When a sales agent is impersonating, the token is for the impersonated customer; otherwise it's for the logged-in customer.

```javascript title="Any script"
const spark = await window.sparkReady;
const token = await spark.getActiveCustomerVerificationToken();
```

## Run a GraphQL query

`spark.fetch` runs a GraphQL query as the signed-in customer. This one reads their email address:

```javascript title="GraphQL query"
const spark = await window.sparkReady;
const response = await spark.fetch(`query {
  loggedInCustomer {
    id
    email
  }
}`);

if (response.status === 200) {
  const { data, errors } = await response.json();
  if (!errors?.length) console.log(data.loggedInCustomer.email);
}
```

`fetch` returns a standard `Response`: check `status`, then call `json()` for the `data` and `errors`. See [fetch()](https://docs.sparklayer.io/developers/javascript-sdk/reference/methods.md#fetch) for its other arguments.

## Redirect to the login page

`spark-redirect.js` sends customers who aren't logged in to your login page when they follow a link that needs SparkLayer, such as the **View order** button in some emails. This lets SparkLayer open what the link was for once they've logged in.

Add it to your theme in addition to the Core Script. On Shopify, put it outside the `{%- if customer.metafields.sparklayer.authentication -%}` block, so it loads for customers who aren't logged in:

```html title="theme.liquid"
<script async src="https://cdn.sparklayer.io/spark-redirect.js"></script>
```

By default, customers are sent to `/account/login`. To use another path, set `window.sparkRedirectLoginPath` before the script:

```html title="theme.liquid"
<script>
  window.sparkRedirectLoginPath = '/account/login';
</script>
<script async src="https://cdn.sparklayer.io/spark-redirect.js"></script>
```

## Next steps

- [Events and analytics](https://docs.sparklayer.io/developers/javascript-sdk/events-and-analytics.md): Run your code when the customer logs out, the cart changes or SparkLayer is ready.
- [Sales rep setup](https://docs.sparklayer.io/help/sales-reps.md): Add sales agents and choose which customers they can order for.
- [Customer methods](https://docs.sparklayer.io/developers/javascript-sdk/reference/methods.md#customers-and-session): Every customer and session method, and the UserData type.
