Trying to use this library with SSR using Next.js and getting errors. What would it take to support SSR if it's not a fault of my own?
I'm fairly new to React but I'm using Next.js v4 with React 16 to get SSR. Wrapping anything with <StripeProvider> results in an error: ReferenceError: window is not defined.
This appears to come from Provider.js#L30. Moving the bit of code concerned by window into componentDidMount didn't help (Elements.js is unhappy because it can't get the context in time from what I gather). Any chance to defer that once on the client?
I've put together a quick test case (stock Next.js install with a page that has StripeProvider > Elements > CardElement: https://github.com/MathieuLoutre/nextjs-stripe-elements
If you're not interested in SSR support, I'm also investigating triggering a re-render once on the client that includes the StripeProvider (but in that case it would be great if it could be scoped just to a part of the form and not the whole form!). I'll keep experimenting but I thought I'd flag this up as it's a great way to get a Stripe form up and running quickly and still be robust.
Indeed, holding off the render until it hits the client seems to work, although it doesn't feel too clean.
export default ({ client }) => {
if (client.rendered) {
return (
<StripeProvider apiKey={process.env.STRIPE_API_KEY}>
<Elements>
<CheckoutForm />
</Elements>
</StripeProvider>
)
}
else {
return <div />
}
}
client being a value set to true using setState or Redux (or whatever else) in the componentDidMount of the parent container/wrapper/app. CheckoutForm is the one calling injectStripe.
In the meantime, would it be really bad to have that component inside the checkout form and essentially just wrapping a component that had injectStripe and a CardElement? What would be better perf-wise? Trying to limit the jump between server rendered and client takeover.
Somehow only just came across #64 despite having used the search function before creating the issue. Anyway, I've updated my test repo with the pattern described above and the failing server side render: https://github.com/MathieuLoutre/nextjs-stripe-elements
If the deferring method is the only supported way at the moment, it would be great to have that in the docs (with maybe the suggestion of the pattern above, if that's standard enough?). Might help to flag it upfront. Happy to do a PR to the docs if that would be considered.
@MathieuLoutre in Next you can use process.browser to detect if you are rendering on the server or client. Thanks for figuring out the above, I just got stuck on the same issue. I totally agree it would be great if this package was SSR-friendly.
Glad this helped @keeth. I didn't know about process.browser but you still need to re-render when you get to the client and I don't think Next has something for this out of the box. I'm using a flag in my Redux store that gets set on the first onComponentDidMount, and I check that flag to know if I need to render the <Provider> etc. or not.
@MathieuLoutre I used your snippet above, but replaced client.rendered with process.browser, and it all seems to work.
Really? That's amazing, I need to look into that. That would simplify things quite a bit. Thanks for this @keeth!
I've just released react-stripe-elements-universal, which renders successfully on both the server and browser.
Drop-in replacement.
@leebenson are you willing to create a pull request to the official repository?
@vanbroup - absolutely -> https://github.com/stripe/react-stripe-elements/pull/128
Why is this issue closed? the solution is not yet included in the codebase
A year later but looks like there is already a oficial solution for SSR
Most helpful comment
I've just released react-stripe-elements-universal, which renders successfully on both the server and browser.
Drop-in replacement.