Next.js
@firma/pay uses ecash-lib (WASM). Next.js App Router must not statically prerender pages that import the library at build time — the prerender step loads WASM and fails.
Mark the route dynamic
Add export const dynamic = 'force-dynamic' to any server page that renders PayWithFirma (directly or via a client child):
app/checkout/page.tsx
// app/checkout/page.tsx
export const dynamic = 'force-dynamic';
import { Checkout } from './Checkout';
export default function CheckoutPage() {
return <Checkout />;
}Client component
Keep PayWithFirma in a 'use client' component and import the stylesheet there:
app/checkout/Checkout.tsx
'use client';
import '@firma/pay/firma-pay.css';
import { PayWithFirma } from '@firma/pay';
export function Checkout() {
return (
<PayWithFirma
receiverUsername="merchant"
orderId="VP9G"
amount="10.00"
currency="USD"
onPaymentFinalized={(txid) => console.log('Paid!', txid)}
/>
);
}transpilePackages
If you consume @firma/pay from a monorepo workspace package, add it to transpilePackages in next.config.ts:
next.config.ts
import type { NextConfig } from 'next';
const nextConfig: NextConfig = {
transpilePackages: ['@firma/pay'],
};
export default nextConfig;See the live example in this repo at cf/firma/pay.firma.cash or try the Demo.