---
title: Sign in with Shop
description: Add a Sign in with Shop button to your self-hosted login page using the shop-login-button web component and OpenID Connect.
source_url:
  html: https://shopify.dev/docs/api/shop/guides/use-cases/sign-in
  md: https://shopify.dev/docs/api/shop/guides/use-cases/sign-in.md
---

# Sign in with Shop

Add the `<shop-login-button>` web component to your self-hosted login page so Shop users can authenticate with their existing Shop account. The component renders the official button and initiates the OIDC authorization flow when clicked.

**Developer preview:**

The Shop platform is in early access. Features and APIs may change before general availability.

***

## What you'll learn

In this guide, you'll learn how to do the following tasks:

* Add the `<shop-login-button>` component to your login page.
* Configure PKCE and redirect the user through the OIDC authorization flow.
* Exchange the authorization code for tokens after the callback.

***

## Requirements

* A [Shop app](https://shopify.dev/docs/api/shop/guides/creating-a-client) with a client ID, client secret, and a configured redirect URI.
* A server-side environment where you can securely handle the token exchange.

***

## Step 1: Add the `<shop-login-button>` component

Load the `<shop-login-button>` script and add the component to your login page. Generate a `state` value and a PKCE `code_verifier` server-side, hash the verifier with SHA-256 to produce the `code_challenge`, then embed them as attributes.

## HTML

```html
<script type="module" src="https://cdn.shopify.com/shopifycloud/shop-js/modules/v2/loader.shop-login-button.esm.js"></script>


<shop-login-button
  ux-mode="redirect"
  client-id="YOUR_CLIENT_ID"
  code-challenge-method="S256"
  code-challenge="YOUR_CODE_CHALLENGE"
  response-type="code"
  scope="openid email"
  redirect-uri="https://your-domain.com/auth/callback"
  state="YOUR_STATE_VALUE"
  analytics-context="loginWithShopSelfServe"
></shop-login-button>
```

Store the `code_verifier` and `state` in the user's session before the page loads; you'll need them to validate the callback.

### Component attributes

| Attribute | Description |
| - | - |
| `client-id` | Your client ID from the [Dev Dashboard](https://shopify.dev/docs/api/shop/guides/creating-a-client). |
| `ux-mode` | Set to `redirect` to handle auth through page redirects. |
| `code-challenge-method` | Set to `S256`. |
| `code-challenge` | Your PKCE code challenge (SHA-256 hash of the `code_verifier`). |
| `response-type` | Set to `code` for the authorization code flow. |
| `scope` | Required: `openid email`. Add `profile` to also receive the user's name and picture. |
| `redirect-uri` | Your callback URL, matching a redirect URI registered on your app. |
| `state` | A random, unguessable string to prevent CSRF attacks. Validate it in the callback. |
| `analytics-context` | Set to `loginWithShopSelfServe`. |
| `bordered` | Optional. When present, adds a light border to the button. |
| `full-width` | Optional. When present, expands the button to fill its container width. |

***

## Step 2: Handle the callback

When the user completes sign-in, Shop redirects to your `redirect-uri` with `code` and `state` query parameters. In your callback handler:

1. Verify the `state` matches the value you stored in the user's session.
2. Exchange the `code` for tokens by calling the token endpoint:

## cURL

```bash
curl -X POST https://accounts.shop.app/oauth/token \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  --data-urlencode 'grant_type=authorization_code' \
  --data-urlencode 'client_id=YOUR_CLIENT_ID' \
  --data-urlencode 'client_secret=YOUR_CLIENT_SECRET' \
  --data-urlencode 'code=AUTHORIZATION_CODE' \
  --data-urlencode 'code_verifier=YOUR_CODE_VERIFIER' \
  --data-urlencode 'redirect_uri=https://your-domain.com/auth/callback'
```

The response includes an `id_token` (a signed JWT with identity claims like `sub`, `email`, and optionally `name` and `picture`), an `access_token`, and a `refresh_token`. Keep all three server-side and never expose them to the browser.

***

## OIDC endpoints

| Endpoint | URL |
| - | - |
| Issuer | `https://accounts.shop.app` |
| Discovery | `https://accounts.shop.app/.well-known/openid-configuration` |
| Authorization | `https://accounts.shop.app/oauth/authorize` |
| Token | `https://accounts.shop.app/oauth/token` |
| UserInfo | `https://accounts.shop.app/oauth/userinfo` |
| JWKS | `https://accounts.shop.app/auth/jwks` |

***

## Next steps

* Store the `sub` claim from the `id_token` alongside your own user record to enable returning sign-ins without a full OIDC flow.
* Exchange a `consentToken` for a user access token to read and write Shop User data. See [Store metafields on Shop users](https://shopify.dev/docs/api/shop/guides/use-cases/metafields).
* Use the [lead capture](https://shopify.dev/docs/api/shop/guides/use-cases/lead-capture) component to collect email addresses from users who aren't yet signed in.

***