When I include this module in one of my views that I render on the server (using React here), I get the ReferenceError mentioned in the subject. Regardless of the fact that I'm not calling .setup() or any braintree methods on the server, Node parses the module and breaks on the navigator references.
I'm not able to offer a pull request on the minified code in this repo, but a cursory look at it tells me the server may break on the unchecked references to window and document.
My current workaround is including the library in the <script> tags in my html, and not in my overall Webpack build. This is unfortunate as it increases the number of requests each page must do.
We do depend on being in a browser environment when our scripts are parsed. Many browsers have specific quirks that we try and optimize for prior to any code being executed.
You could also concatenate our code into any of your own scripts that you serve up to reduce the amount of separate network requests the browser needs to do.
Just setup braintree inside of componentDidMount().
class Payments extends React.Component {
constructor(props) {
super(props)
}
componentDidMount() {
fetch('/api/token')
.then(res => res.text())
.then(token => braintree.setup(token, 'custom', {
...
})
})
}
...
@jaredpalmer The issue isn't that braintree.setup() is being executed on the server (which it isn't), it's that simply including the braintree-web module in code that's run on the server (for rendering) is causing the break due to the references to navigator (and window and document).
This library is only supported from within browser environments. Sadly, this means that running braintree-web inside of Node will cause various issues like the one you're running into. You can use concatenation like @mrak suggested above, or we can help you figure out another workaround.
We're closing this issue for now, but feel free to continue discussion here if you need help with this.
@EvanHahn That's fine. Thanks for being responsive to users' issues. I understand that it may not be feasible or practical to add checks for browser globals, especially when the number of users affected (those doing server-side JS rendering) is I'm sure very small.
Oh sorry, I forgot that I disgustingly added it with just a script tag in my html template. Ugly, but it's the only way to get it work with react and SSR
I am trying to do something similar, how did you reference to the braintree script in index.html from the react components?
While execution of this library is still only supported in browser environments, the latest beta of the new version of our SDK ([email protected]) can be required in Node which may help with server-side rendering.
Here are some links to our official documentation:
Most helpful comment
While execution of this library is still only supported in browser environments, the latest beta of the new version of our SDK (
[email protected]) can berequired in Node which may help with server-side rendering.Here are some links to our official documentation: