Skip to content

Commit a3f2bd5

Browse files
authored
Merge pull request #1 from bajoski34/copilot/add-react-19-support
Add React 19 and Next.js support
2 parents 84cc1ae + 1453801 commit a3f2bd5

8 files changed

Lines changed: 16924 additions & 16043 deletions

File tree

README.md

Lines changed: 182 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ Available features include:
3838

3939
1. Flutterwave version 3 API keys
4040
2. Node version >= 6.9.x and npm >= 3.x.x
41-
3. React version >= 14
41+
3. React version >= 15 (including React 19)
42+
4. For Next.js: Version 12+ (both App Router and Pages Router supported)
4243

4344

4445
## Installation
@@ -89,7 +90,8 @@ Add Flutterwave to your projects as a component or a react hook:
8990

9091
1. [As a Component](#components)
9192
2. [Directly in your code](#hooks)
92-
3. [Making recurrent payments](#recurring-payments)
93+
3. [Next.js Applications](#nextjs-applications)
94+
4. [Making recurrent payments](#recurring-payments)
9395

9496

9597
### Components
@@ -186,6 +188,184 @@ export default function App() {
186188
}
187189
```
188190

191+
### Next.js Applications
192+
193+
The Flutterwave React SDK works seamlessly with Next.js applications. Since the library loads external scripts, you must ensure it runs only on the client side.
194+
195+
#### App Router (Next.js 13+)
196+
197+
Add the `'use client'` directive at the top of your payment component:
198+
199+
```javascript
200+
'use client';
201+
202+
import React from 'react';
203+
import { useFlutterwave, closePaymentModal } from 'flutterwave-react-v3';
204+
205+
export default function FlutterwavePayment() {
206+
const config = {
207+
public_key: 'FLWPUBK-**************************-X',
208+
tx_ref: Date.now(),
209+
amount: 100,
210+
currency: 'NGN',
211+
payment_options: 'card,mobilemoney,ussd',
212+
customer: {
213+
email: 'user@gmail.com',
214+
phone_number: '070********',
215+
name: 'john doe',
216+
},
217+
customizations: {
218+
title: 'My Payment',
219+
description: 'Payment for items in cart',
220+
logo: 'https://st2.depositphotos.com/4403291/7418/v/450/depositphotos_74189661-stock-illustration-online-shop-log.jpg',
221+
},
222+
};
223+
224+
const handleFlutterPayment = useFlutterwave(config);
225+
226+
return (
227+
<div>
228+
<h1>Make Payment</h1>
229+
<button
230+
onClick={() => {
231+
handleFlutterPayment({
232+
callback: (response) => {
233+
console.log(response);
234+
closePaymentModal();
235+
},
236+
onClose: () => {},
237+
});
238+
}}
239+
>
240+
Pay with Flutterwave
241+
</button>
242+
</div>
243+
);
244+
}
245+
```
246+
247+
You can also use the FlutterWaveButton component:
248+
249+
```javascript
250+
'use client';
251+
252+
import React from 'react';
253+
import { FlutterWaveButton, closePaymentModal } from 'flutterwave-react-v3';
254+
255+
export default function PaymentButton() {
256+
const config = {
257+
public_key: 'FLWPUBK-**************************-X',
258+
tx_ref: Date.now(),
259+
amount: 100,
260+
currency: 'NGN',
261+
payment_options: 'card,mobilemoney,ussd',
262+
customer: {
263+
email: 'user@gmail.com',
264+
phone_number: '070********',
265+
name: 'john doe',
266+
},
267+
customizations: {
268+
title: 'My store',
269+
description: 'Payment for items in cart',
270+
logo: 'https://st2.depositphotos.com/4403291/7418/v/450/depositphotos_74189661-stock-illustration-online-shop-log.jpg',
271+
},
272+
};
273+
274+
const fwConfig = {
275+
...config,
276+
text: 'Pay with Flutterwave!',
277+
callback: (response) => {
278+
console.log(response);
279+
closePaymentModal();
280+
},
281+
onClose: () => {},
282+
};
283+
284+
return (
285+
<div>
286+
<h1>Checkout</h1>
287+
<FlutterWaveButton {...fwConfig} />
288+
</div>
289+
);
290+
}
291+
```
292+
293+
#### Pages Router (Next.js 12 and below)
294+
295+
Use dynamic imports with SSR disabled:
296+
297+
```javascript
298+
import dynamic from 'next/dynamic';
299+
300+
// Dynamically import the payment component with SSR disabled
301+
const FlutterwavePayment = dynamic(
302+
() => import('../components/FlutterwavePayment'),
303+
{ ssr: false }
304+
);
305+
306+
export default function CheckoutPage() {
307+
return (
308+
<div>
309+
<h1>Checkout</h1>
310+
<FlutterwavePayment />
311+
</div>
312+
);
313+
}
314+
```
315+
316+
Then create your payment component in `components/FlutterwavePayment.js`:
317+
318+
```javascript
319+
import React from 'react';
320+
import { useFlutterwave, closePaymentModal } from 'flutterwave-react-v3';
321+
322+
export default function FlutterwavePayment() {
323+
const config = {
324+
public_key: 'FLWPUBK-**************************-X',
325+
tx_ref: Date.now(),
326+
amount: 100,
327+
currency: 'NGN',
328+
payment_options: 'card,mobilemoney,ussd',
329+
customer: {
330+
email: 'user@gmail.com',
331+
phone_number: '070********',
332+
name: 'john doe',
333+
},
334+
customizations: {
335+
title: 'My Payment',
336+
description: 'Payment for items in cart',
337+
logo: 'https://st2.depositphotos.com/4403291/7418/v/450/depositphotos_74189661-stock-illustration-online-shop-log.jpg',
338+
},
339+
};
340+
341+
const handleFlutterPayment = useFlutterwave(config);
342+
343+
return (
344+
<div>
345+
<button
346+
onClick={() => {
347+
handleFlutterPayment({
348+
callback: (response) => {
349+
console.log(response);
350+
closePaymentModal();
351+
},
352+
onClose: () => {},
353+
});
354+
}}
355+
>
356+
Pay with Flutterwave
357+
</button>
358+
</div>
359+
);
360+
}
361+
```
362+
363+
**Important Notes:**
364+
- Always use the `'use client'` directive when using Next.js App Router (Next.js 13+)
365+
- The Flutterwave script loads client-side only and cannot be server-side rendered
366+
- Ensure payment components are client components, not server components
367+
- For Pages Router, use `dynamic` import with `ssr: false` to prevent server-side rendering errors
368+
189369
### Recurring Payments
190370

191371
Pass the payment plan ID into your payload to make [recurring payments](https://developer.flutterwave.com/docs/recurring-payments/payment-plans).

dist/FWButton.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,5 @@ interface FlutterWaveButtonProps extends FlutterwaveConfig {
88
children?: React.ReactNode;
99
callback: (response: FlutterWaveResponse) => void;
1010
}
11-
declare const FlutterWaveButton: ({ text, className, children, callback, onClose, disabled, ...config }: FlutterWaveButtonProps) => JSX.Element;
11+
declare const FlutterWaveButton: ({ text, className, children, callback, onClose, disabled, ...config }: FlutterWaveButtonProps) => React.ReactElement;
1212
export default FlutterWaveButton;

0 commit comments

Comments
 (0)