'How to integrate Paddle with NextJS
Paddle requires these two scripts to be insert before </body> in HTML:
<script src="https://cdn.paddle.com/paddle/paddle.js"></script>
<script type="text/javascript">
Paddle.Setup({ vendor: 1234567 });
</script>
But NextJS doesn't have HTML files and when I insert into return function, { vendor: 1234567, debug: true } part creates a '}' expected error.
Does anyone know how to solve this?
Solution 1:[1]
You can use the Script component provided by Next.Js
https://nextjs.org/docs/basic-features/script
import Script from 'next/script'
<Script
key="init-paddle"
src="https://cdn.paddle.com/paddle/paddle.js"
onLoad={() => {
console.log('On paddle load')
if (PADDLE_SANDBOX) {
window.Paddle.Environment.set('sandbox')
}
window.Paddle.Setup({
vendor: 12345,
eventCallback: function (data) {
// The data.event will specify the event type
if (data.event === 'Checkout.Loaded') {
console.log(data.eventData) // Data specifics on the event
} else if (data.event === 'Checkout.Complete') {
console.log(data.eventData) // Data specifics on the event
} else if (data.event === 'Checkout.Close') {
console.log(data.eventData) // Data specifics on the event
}
},
})
}}
/>
If you're using typescript and you want to type the paddle integration you might use:
(not exhaustive, but better than nothing)
/// paddle.d.ts
export declare global {
interface Customer {
total: number
total_tax: number
currency: string
}
type PaddleEvent =
| 'Checkout.Loaded'
| 'Checkout.Close'
| 'Checkout.Complete'
| 'Checkout.User.Subscribed'
| 'Checkout.Quantity.Change'
| 'Checkout.Login'
| 'Checkout.Logout'
| 'Checkout.PaymentMethodSelected'
| 'Checkout.Coupon.Add'
| 'Checkout.Coupon.Submit'
| 'Checkout.Coupon.Cancel'
| 'Checkout.Coupon.Applied'
| 'Checkout.Coupon.Remove'
| 'Checkout.Error'
| 'Checkout.Location.Submit'
| 'Checkout.Language.Change'
| 'Checkout.Vat.Add'
| 'Checkout.Vat.Cancel'
| 'Checkout.Vat.Submit'
| 'Checkout.Vat.Applied'
| 'Checkout.Vat.Remove'
| 'Checkout.WireTransfer.Complete'
| 'Checkout.PaymentComplete'
| 'Checkout.PaymentMethodChange'
| 'Checkout.WireTransfer.PaymentMethodChange'
interface Window {
Paddle: {
Checkout: {
open: (options: {
product: string | number
title?: string
message?: string
coupon?: string
email?: string
marketingConsent?: '0' | '1'
country?: string
postcode?: string
allowQuantity?: boolean
quantity?: number
disableLogout?: boolean
locale?: string
passthrough?: string
referring_domain?: string
success?: string
successCallback?: string
closeCallback?: string
loadCallback?: string
upsell?: string | number
upsellTitle?: string
upsellText?: string
upsellAction?: string
upsellCoupon?: string
upsellPassthrough?: string
override?: string
displayModeTheme?: string
// Inline checkout
method?: string
frameTarget?: string
frameInitialHeight?: number
frameStyle?: string
}) => void
}
Environment: {
set: (env: string) => void
}
Setup: (options: {
vendor: number
eventCallback: (data: {
event: PaddleEvent
eventData: {
payment_method?: string
available_payment_methods?: string
available_payment_methods_count?: number
checkout: {
recurring_prices: {
customer: Customer
interval: {
type: string
length: number
}
}
prices: {
customer: Customer
}
}
product: { id: number; name: string; quantity: number }
user: { id: string; email: string; country: string }
}
checkoutData: {
'paddlejs-version': '2.0.9'
apple_pay_enabled: string
display_mode: string
guest_email: string
is_popup: string
method: string
paddle_js: string
parentURL: string
parent_url: string
passthrough: string
popup: string
product: string
referring_domain: string
}
}) => void
}) => void
}
}
}
Solution 2:[2]
Don't take the documentation too literally. Since you're using React, it doesn't make sense to include any inline JavaScript. Paddle.js is client-side only, so it should be initialized in a useEffect callback in the root component.
// pages/_document.js
import Document, { Html, Head, Main, NextScript } from 'next/document'
export default class MyDocument extends Document {
static async getInitialProps(ctx) {
const initialProps = await Document.getInitialProps(ctx)
return { ...initialProps }
}
render() {
return (
<Html>
<Head />
<body>
<Main />
<NextScript />
<script src="https://cdn.paddle.com/paddle/paddle.js" />
</body>
</Html>
)
}
}
// pages/_app.js
import { useEffect } from 'react'
function MyApp({ Component, pageProps }) {
// Initialize Paddle
useEffect(() => {
Paddle.Setup({ vendor: 1234567 })
}, [])
return <Component {...pageProps} />
}
Solution 3:[3]
You need to set it as the inner HTML
<script
type="text/javascript"
dangerouslySetInnerHTML={{
__html: `
Paddle.Setup({ vendor: 123456 });`,
}}
></script>
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | kachar |
| Solution 2 | Steve |
| Solution 3 |
