---
title: login
description: >-
  The login feature lets merchants add Shop account authentication to their
  storefront.
source_url:
  html: 'https://shopify.dev/docs/api/shop-sdk/reference/login'
  md: 'https://shopify.dev/docs/api/shop-sdk/reference/login.md'
api_name: shop-sdk
---

# login

The `login` feature lets merchants add [Shop](https://shop.app) account authentication to their storefront.

The feature detects whether the current visitor is a known Shop user and can display a call-to-action button (for example, "Continue with Shop") or integrate inline with an existing email input field.

***

## Usage

Create a login instance via the SDK:

```javascript
const sdk = window.ShopSDK.initialize({
  apiKey: 'YOUR_CLIENT_ID',
});


const login = await sdk.create('login', {
  attributes: {
    emailInputSelector: '#email',
  },
  onComplete(event) {
    console.log('Authenticated:', event.email, event.signedIn);
  },
});


document.querySelector('#login-mount').appendChild(login.element);
```

You can also eagerly preload the feature loader before calling `create`:

```javascript
const sdk = window.ShopSDK.initialize({
  apiKey: 'YOUR_CLIENT_ID',
  features: { login: true },
});
```

#### LoginConfig

Config accepted by `sdk.create('login', config)`. Includes component attributes, appearance overrides, and event handlers.

The `login` feature provides Shop account authentication.

* **appearance**

  **AppearanceConfig**

  Component-level appearance overrides.

* **attributes**

  **LoginAttributes**

  Component attributes.

* **onBeforeAuthenticate**

  **() => void | Promise\<void>**

  Fired before authentication begins. Can be async.

* **onComplete**

  **(event: LoginCompleteEvent) => void**

  Fired when the login flow completes successfully.

* **onConfirmSuccess**

  **() => void**

  Fired after the user confirms a successful action.

* **onError**

  **(event: LoginErrorEvent) => void**

  Fired when an error occurs during the flow.

* **onGetEmailInput**

  **() => HTMLInputElement**

  Fired to retrieve the email input element (alternative to `emailInputSelector`).

* **onLoad**

  **(event: LoginLoadEvent) => void**

  Fired when the component loads and user recognition completes.

* **onReady**

  **(event: ReadyEvent) => void**

  SDK-level ready handler (fires when the element's loader resolves).

* **onRestart**

  **() => void**

  Fired when the user restarts the flow.

### AppearanceConfig

Appearance configuration for styling Shop SDK components. Set at the instance level in \`initialize()\` or per-feature in \`create()\`.

* preferredLoginExperience

  Preferred UX for the login experience: \`'redirect'\`, \`'popup'\`, or \`null\` for the default.

  ```ts
  'redirect' | 'popup' | null
  ```

* variables

  CSS custom property overrides.

  ```ts
  AppearanceVariables
  ```

### AppearanceVariables

CSS custom properties that control styling of Shop SDK components. All properties are optional — only set ones will be applied.

* \--buttons-radius

  Border radius for buttons (e.g. \`'12px'\`).

  ```ts
  string
  ```

* \--font-paragraph--line-height

  Line height for paragraph text (e.g. \`'22px'\`).

  ```ts
  string
  ```

* \--font-paragraph--size

  Font size for paragraph text (e.g. \`'16px'\`).

  ```ts
  string
  ```

* \--shop-pay-button-border-radius

  Border radius of the Shop Pay button (e.g. \`'4px'\`, \`'999px'\`).

  ```ts
  string
  ```

* \--shop-pay-button-height

  Height of the Shop Pay button (e.g. \`'48px'\`).

  ```ts
  string
  ```

* \--shop-pay-button-width

  Width of the Shop Pay button (e.g. \`'260px'\`, \`'100%'\`).

  ```ts
  string
  ```

* \--x-spacing-base

  Base spacing unit (e.g. \`'14px'\`).

  ```ts
  string
  ```

* \[variable: \`--${string}\`]

  ```ts
  string | undefined
  ```

### LoginAttributes

Attributes accepted by the \`login\` feature.

* apiKey

  Secondary client ID. If supplied, the client ID will receive a delegated consent token on behalf of the primary client ID.

  ```ts
  string
  ```

* buttonLayout

  Layout style for the button: \`'or'\` or \`'standalone'\`.

  ```ts
  LeadCaptureButtonLayout
  ```

* buttonType

  Type of CTA button shown when a Shop user is recognized.

  ```ts
  LeadCaptureButtonType
  ```

* clientId

  Primary Client ID. This client will be shown to the buyer in the sign in flow and is the Relying Party of the OAuth flow. If omitted, defaults to the Shopify Merchant.

  ```ts
  string
  ```

* devMode

  Enable development mode for testing.

  ```ts
  boolean
  ```

* emailInputSelector

  CSS selector for the email input on the page.

  ```ts
  string
  ```

* scope

  Space-separated list of OAuth scopes.

  ```ts
  string
  ```

* storefrontOrigin

  Origin of the embedding storefront.

  ```ts
  string
  ```

* uxMode

  UX mode for the auth flow: \`'iframe'\`, \`'windoid'\`, or \`'redirect'\`.

  ```ts
  'iframe' | 'windoid' | 'redirect'
  ```

### LeadCaptureButtonLayout

Layout style for the lead capture button. - \`'or'\` — Shows an “or” separator between the button and the form. - \`'standalone'\` — Shows the button without any separator.

```ts
'or' | 'standalone'
```

### LeadCaptureButtonType

The type of call-to-action button shown when a Shop user is recognized. - \`'none'\` — No button; uses inline email-based flow instead. - \`'claim'\` — Shows “Claim with Shop” button. - \`'continue'\` — Shows “Continue with Shop” button. - \`'favorite'\` — Shows “Favorite with Shop” button. - \`'notify'\` — Shows “Notify me with Shop” button. - \`'save'\` — Shows “Save with Shop” button.

```ts
'none' | 'claim' | 'continue' | 'favorite' | 'notify' | 'save'
```

### LoginCompleteEvent

Event payload dispatched when the login flow completes successfully.

* consentedScopes

  A space-separated list of OAuth scopes the user consented to.

  ```ts
  string
  ```

* customerAccessToken

  A customer access token issued after authentication, if available.

  ```ts
  string
  ```

* customerAccessTokenExpiresAt

  ISO 8601 timestamp of when the customer access token expires.

  ```ts
  string
  ```

* email

  The email address captured from the user.

  ```ts
  string
  ```

* emailVerified

  Whether the user's email has been verified.

  ```ts
  boolean
  ```

* shopConsentToken

  A token that can be exchanged in the Shop Partners API to receive access for a user in the Shop Users API

  ```ts
  string
  ```

* signedIn

  Whether the user signed in during the flow (as opposed to only providing their email).

  ```ts
  boolean
  ```

### LoginErrorEvent

Event payload dispatched when an error occurs during login.

* code

  A machine-readable error code.

  ```ts
  string
  ```

* email

  The email address associated with the error, if available.

  ```ts
  string
  ```

* message

  A human-readable error message.

  ```ts
  string
  ```

### LoginLoadEvent

Event payload dispatched when the login component finishes loading.

* userFound

  Whether a recognized Shop user was detected for the current browser session.

  ```ts
  boolean
  ```

### ReadyEvent

Event payload passed to the \`onReady\` handler when a feature element finishes loading.

* detail

  Underlying \`CustomEvent.detail\` from the element's \`'loaded'\` event, when available. Shape is feature-specific — e.g. for lead-capture this includes fields like \`userFound\`, \`loginTitle\`, etc. emitted by \`useAuthorizeEventListener\`.

  ```ts
  unknown
  ```

* elementTagName

  Tag name of the element that became ready, e.g. \`shop-lead-capture\`.

  ```ts
  string
  ```

#### LoginInstance

Runtime instance returned by `sdk.create('login')`.

Exposes methods, attribute setters, and event subscriptions for the login flow.

* **destroy**

  **() => void**

  **required**

  Tear down listeners and remove the element from the DOM if attached.

* **element**

  **HTMLElement**

  **required**

  The underlying custom element. The consumer is responsible for inserting it into the DOM.

* **notifyEmailFieldShown**

  **() => void**

  **required**

  Notify the component that the email field has been shown.

* **onBeforeAuthenticate**

  **(handler: () => void | Promise\<void>) => void**

  **required**

  Register an `onBeforeAuthenticate` handler.

* **onComplete**

  **(handler: (event: LoginCompleteEvent) => void) => void**

  **required**

  Register an `onComplete` handler.

* **onConfirmSuccess**

  **(handler: () => void) => void**

  **required**

  Register an `onConfirmSuccess` handler.

* **onError**

  **(handler: (event: LoginErrorEvent) => void) => void**

  **required**

  Register an `onError` handler.

* **onLoad**

  **(handler: (event: LoginLoadEvent) => void) => void**

  **required**

  Register an `onLoad` handler.

* **onReady**

  **(handler: (event: ReadyEvent) => void) => void**

  **required**

  Register an `onReady` handler. Fires immediately if already ready.

* **onRestart**

  **(handler: () => void) => void**

  **required**

  Register an `onRestart` handler.

* **setAttribute**

  **(attrs: Partial\<LoginAttributes>) => void**

  **required**

  Update one or more attributes on the underlying element.

* **start**

  **(email?: string) => void**

  **required**

  Trigger the login flow, optionally with a pre-filled email.

#### LoginCompleteEvent

Event payload dispatched when the login flow completes successfully.

* **email**

  **string**

  **required**

  The email address captured from the user.

* **signedIn**

  **boolean**

  **required**

  Whether the user signed in during the flow (as opposed to only providing their email).

* **consentedScopes**

  **string**

  A space-separated list of OAuth scopes the user consented to.

* **customerAccessToken**

  **string**

  A customer access token issued after authentication, if available.

* **customerAccessTokenExpiresAt**

  **string**

  ISO 8601 timestamp of when the customer access token expires.

* **emailVerified**

  **boolean**

  Whether the user's email has been verified.

* **shopConsentToken**

  **string**

  A token that can be exchanged in the Shop Partners API to receive access for a user in the Shop Users API

#### LoginErrorEvent

Event payload dispatched when an error occurs during login.

* **code**

  **string**

  **required**

  A machine-readable error code.

* **message**

  **string**

  **required**

  A human-readable error message.

* **email**

  **string**

  The email address associated with the error, if available.

#### LoginLoadEvent

Event payload dispatched when the login component finishes loading.

* **userFound**

  **boolean**

  **required**

  Whether a recognized Shop user was detected for the current browser session.

Examples

### Examples

* ####

  ##### Description

  Create a login instance with an email input and handle the complete event.

  ##### HTML

  ```html
  <script type="module">
    import 'https://cdn.shopify.com/shopifycloud/shop-js/modules/v2/loader.sdk.esm.js';

    const sdk = window.ShopSDK.initialize({
      apiKey: 'YOUR_CLIENT_ID',
      locale: 'en',
    });

    const login = await sdk.create('login', {
      attributes: {
        emailInputSelector: '#email',
      },
      onComplete(event) {
        console.log('Authenticated:', event.email, event.signedIn);
      },
    });

    document.querySelector('#login-mount').appendChild(login.element);
  </script>

  <form id="login-form">
    <label for="email">Email address</label>
    <input type="email" id="email" name="email" placeholder="Enter your email" />
  </form>

  <div id="login-mount"></div>
  ```

* ####

  ##### Description

  Show a "Continue with Shop" button for recognized users instead of an inline email input.

  ##### HTML

  ```html
  <script type="module">
    import 'https://cdn.shopify.com/shopifycloud/shop-js/modules/v2/loader.sdk.esm.js';

    const sdk = window.ShopSDK.initialize({
      apiKey: 'YOUR_CLIENT_ID',
      locale: 'en',
    });

    const login = await sdk.create('login', {
      attributes: {
        buttonType: 'continue',
        buttonLayout: 'standalone',
        scope: 'shop_app:oauth',
      },
      onComplete(event) {
        if (event.signedIn) {
          console.log('User signed in:', event.email);
          console.log('Token:', event.customerAccessToken);
        }
      },
      onError(event) {
        console.error('Login error:', event.code, event.message);
      },
    });

    document.querySelector('#login-mount').appendChild(login.element);
  </script>

  <div id="login-mount"></div>
  ```

***

## Related

[Overview - Shop SDK](https://shopify.dev/docs/api/shop-sdk/reference/shop-sdk)

***
