Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG]: IntegrationError: payment Element didn't mount normally. #399

Closed
baptisteArno opened this issue Dec 22, 2022 · 4 comments
Closed
Labels
bug Something isn't working

Comments

@baptisteArno
Copy link

What happened?

When calling:

const paymentElement = elements?.create('payment')
paymentElement?.mount(paymentElementContainer)

Where paymentElementContainer is an HTMLElement, I get this runtime error: Uncaught IntegrationError: payment Element didn't mount normally.

What could cause this? I'm in a Shadow DOM, could that be the issue?

Environment

No response

Reproduction

No response

@baptisteArno baptisteArno added the bug Something isn't working label Dec 22, 2022
@tylersmith-stripe
Copy link
Contributor

tylersmith-stripe commented Dec 22, 2022

Hey @baptisteArno,

Attempting to render the Element into a Shadow DOM is very likely why you're seeing this error.

This is a known limitation of Elements, as the Element frames need to be able to communicate with the Light DOM. This error is explaining that the Element iframe is unreachable.

@tylersmith-stripe
Copy link
Contributor

You might find this comment, and referenced library, helpful! #143 (comment)

@baptisteArno
Copy link
Author

Thank you for providing a workaround 🙏

@baptisteArno
Copy link
Author

For those who'd like to embed a Payment Element form in a Shadow DOM, all you need to do is to mount it outside the Shadow DOM using a slot.

const slotName = 'stripe-payment-form'

const initShadowMountPoint = (element: HTMLElement) => {
  const rootNode = element.getRootNode() as ShadowRoot
  const host = rootNode.host
  const slotPlaceholder = document.createElement('div')
  slotPlaceholder.slot = slotName
  host.appendChild(slotPlaceholder)
  const paymentElementContainer = document.createElement('div')
  paymentElementContainer.id = 'payment-element'
  slotPlaceholder.appendChild(paymentElementContainer)
}

Then just render this anywhere:

<slot name={slotName} />

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants