Skip to content

Add @shopify/customer-api-client package for the Customer Account API #3082

@sdornan

Description

@sdornan

Background

My company is migrating from legacy customer accounts to the current Customer Account API for our headless Next.js storefront. We already use @shopify/admin-api-client and @shopify/storefront-api-client — both have been great to work with. The sane configuration defaults and automatic type generation via @shopify/api-codegen-preset have made them really convenient.

When planning the customer account migration, I noticed there's no equivalent client for the Customer Account API. @shopify/api-codegen-preset already references @shopify/customer-api-client as the module name for ApiType.Customer, so the package name and type infrastructure are clearly already planned — it just hasn't been implemented yet.

What I built

Rather than roll our own one-off solution, I decided to build the missing client modeled after the existing ones so it could be upstreamed and others could benefit from it too.

The new @shopify/customer-api-client package provides:

OAuth helpers — covering the full flow for both client types:

  • getAuthorizationUrl() — generates the authorization URL; includes PKCE for public clients (browser/mobile), omits it for confidential clients (server-side with clientSecret)
  • exchangeCode() — exchanges the authorization code for a token set
  • refreshToken() — refreshes an expired access token using the stored refresh token
  • getLogoutUrl() — returns the end-session URL

GraphQL client — authenticated requests using per-user customer access tokens:

  • fetch() / request() — delegates to @shopify/graphql-client with Authorization: {token} injected per-request (no Bearer prefix, per the Customer Account API docs)

Endpoint discovery — the GraphQL API URL and OAuth endpoints are discovered lazily at construction time via:

  • GET /.well-known/openid-configuration → OAuth endpoints
  • GET /.well-known/customer-account-api{ graphql_api } (which may be a merchant's custom vanity domain)

The client follows the same factory function pattern as @shopify/storefront-api-client and reuses @shopify/graphql-client for HTTP, retries, and logging.

I should note that while the implementation has full unit test coverage, we're still in the middle of our own migration so it hasn't been battle-tested in production yet. Happy to flag that clearly in any PR description.

I have a working implementation ready at athletic-greens/shopify-app-js — add-customer-api-client if maintainers are interested. Happy to adjust the design based on any feedback before opening a PR.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions