Skip to main content

Quick diagnosis

Server-side rendering errors

Error: “customElements is not defined”

Cause: Primer code is running on the server where Web Components API doesn’t exist. Solution: Ensure loadPrimer() is called only in client-side lifecycle methods.

Error: “window is not defined”

Cause: Code is accessing browser globals during server-side rendering. Solution: Add environment checks before accessing browser APIs:

Card form issues

Duplicate card forms

Cause: Using both <primer-card-form> and <primer-payment-method type="PAYMENT_CARD"> in the same layout. Why this happens: <primer-payment-method type="PAYMENT_CARD"> internally creates its own <primer-card-form>. When you also add a custom card form, you end up with two card forms on the page. Solution: Choose one approach:

Card inputs not working

Cause: Card input components placed outside <primer-card-form>. Solution: All card inputs must be descendants of the card form:

Dynamic rendering creates duplicates

Cause: When dynamically rendering payment methods, PAYMENT_CARD is included while also using a custom card form. Solution: Filter out PAYMENT_CARD when using a custom card form:

React-specific issues

Options not being applied

Cause: Creating new object references on every render forces unnecessary comparisons.
The Primer SDK implements deep comparison for the options property. This means unstable references won’t cause re-initialization, but they still add comparison overhead on every render.
Solution: Use stable references:

Calling methods before ready

Cause: Calling SDK methods before the checkout is initialized. Solution: Wait for the primer:ready event:

React 18 vs React 19 property assignment

Cause: React 18 converts object props to [object Object] strings for web components. Solution: Use the appropriate pattern for your React version:

Styling issues

CSS not applying to components

Cause: Trying to style internal elements with CSS selectors. Shadow DOM prevents external CSS from reaching internal elements. Solution: Use CSS variables instead:

Validation vs payment errors

Understanding the difference helps with proper error handling:
Don’t confuse these two error types. Validation errors prevent form submission and are shown inline. Payment failures occur after the form is submitted and require explicit handling.

Debugging tips

Log all Primer events

Verify component registration

Check available payment methods

Getting help

When contacting Primer support, include:
  1. The diagnosticsId from any error callbacks
  2. Your browser, OS version, and framework version
  3. Steps to reproduce the issue

See also

SSR guide

Server-side rendering patterns

React integration

React-specific guidance

Events guide

Event handling patterns

Build a custom card form

Card form tutorial