Configuration
Customizing Devfund Components
Learn how to customize and configure Devfund components to match your design system and requirements.
Component Props
All Devfund components accept minimal props for simplicity:
typescriptinterface DevfundComponentProps { username: string; // Required }
Customizing Styles
Via Tailwind CSS Classes
Components use Tailwind CSS classes. Modify the generated component file directly:
tsx// components/devfund/CardPaymentQR.tsx // Change button color className="bg-blue-400 hover:bg-blue-500" // from bg-yellow-400 // Change modal background className="bg-gray-100" // from bg-white // Change border radius className="rounded-3xl" // from rounded-2xl
Override via CSS Modules
If you prefer CSS Modules, add styles to your component:
css/* components/devfund/CardPaymentQR.module.css */ .button { @apply bg-blue-400 hover:bg-blue-500 text-white px-6 py-3 rounded-lg; } .modal { @apply bg-white rounded-2xl shadow-xl p-8; }
Then import in your component:
tsximport styles from './CardPaymentQR.module.css'; // Use: className={styles.button}
Global Styles
Add global styles in your globals.css:
css/* app/globals.css */ .devfund-button { @apply font-semibold px-6 py-3 rounded-lg transition-all; } .devfund-modal { @apply shadow-xl rounded-2xl; }
Extending Components
Create Wrapper Component
Create a wrapper component for consistent styling:
tsx// components/devfund/SupportButton.tsx import CardPaymentQR from '@/components/devfund/CardPaymentQR'; interface SupportButtonProps { username: string; variant?: 'card' | 'glass' | 'minimal' | 'modern' | 'modal'; } export function SupportButton({ username, variant = 'card' }: SupportButtonProps) { // Map variant to component const components: Record<string, typeof CardPaymentQR> = { card: CardPaymentQR, // ... other variants }; const Component = components[variant] || CardPaymentQR; return ( <div className="custom-wrapper"> <Component username={username} /> </div> ); }
Add Context
Add context and information around the component:
tsxexport default function SupportSection({ username }: { username: string }) { return ( <section className="bg-gray-50 rounded-lg p-8"> <div className="max-w-md mx-auto"> <h3 className="text-xl font-bold mb-2">Support My Work</h3> <p className="text-gray-600 mb-6"> Help me continue building amazing tools and libraries. </p> <CardPaymentQR username={username} /> </div> </section> ); }
Configuration Options
API Endpoint
The component fetches from:
https://www.devfund.in/api/profile/{username}
To use a different API, modify the component's fetch URL:
tsxconst response = await fetch( `https://your-api.com/api/profile/${encodeURIComponent(username)}` );
Timeout Duration
Default timeout is 10 seconds. To change it:
tsxsignal: AbortSignal.timeout(15000), // 15 seconds
Error Messages
Customize error messages:
tsxif (response.status === 404) { throw new Error('Profile not found. Please check the username.'); } if (response.status >= 500) { throw new Error('Our servers are temporarily unavailable.'); }
Theming
Light Theme
Use light colors and backgrounds:
tsx// Button className="bg-yellow-400 text-gray-900" // Modal className="bg-white text-gray-900" // Background className="bg-gray-50"
Dark Theme
Use dark colors and light text:
tsx// Button className="bg-gray-700 text-white" // Modal className="bg-gray-800 text-white" // Background className="bg-gray-900"
Advanced Customization
Add Analytics
Track component interactions:
tsxconst handleOpen = () => { setIsOpen(true); // Send analytics if (typeof window !== 'undefined' && window.gtag) { window.gtag('event', 'payment_modal_opened', { username: username, component: 'CardPaymentQR' }); } };
Add Animations
Add custom animations using Framer Motion or CSS:
tsx// With Framer Motion import { motion } from 'framer-motion'; <motion.div initial={{ opacity: 0, scale: 0.95 }} animate={{ opacity: 1, scale: 1 }} transition={{ duration: 0.3 }} className="bg-white rounded-2xl..." > {/* Modal content */} </motion.div>
Add Form Validation
Enhance with input validation:
tsxif (!username || username.trim() === '') { setError('Please provide a valid username'); return; } if (username.length > 50) { setError('Username is too long'); return; }
Environment Variables
For API changes or configuration:
env# .env.local NEXT_PUBLIC_DEVFUND_API=https://devfund.in NEXT_PUBLIC_DEVFUND_TIMEOUT=10000
Then use in component:
tsxconst apiUrl = process.env.NEXT_PUBLIC_DEVFUND_API || 'https://devfund.in'; const timeout = process.env.NEXT_PUBLIC_DEVFUND_TIMEOUT || 10000;
Build Optimization
Tree Shaking
Only import what you need:
tsx// ✅ Good: Import specific component import CardPaymentQR from '@/components/devfund/CardPaymentQR'; // ❌ Avoid: Import all if you only need one
Code Splitting
Lazy load components:
tsximport dynamic from 'next/dynamic'; const CardPaymentQR = dynamic(() => import('@/components/devfund/CardPaymentQR'), { loading: () => <p>Loading...</p> } );
Performance Tips
-
Memoize components if re-rendering frequently:
tsxexport default memo(CardPaymentQR); -
Use loading states to prevent layout shift:
tsxconst [loading, setLoading] = useState(false); -
Optimize images - QR codes should load quickly
-
Cache API responses if possible:
tsx// Implement caching logic const cached = localStorage.getItem(`user_${username}`);
Accessibility Customization
Enhance accessibility:
tsx// Add ARIA descriptions <button aria-describedby="support-help"> Support Button </button> <p id="support-help" className="sr-only"> Opens a payment interface to support via UPI </p>
Integration Examples
With Next.js App Router
tsx// app/support/page.tsx import CardPaymentQR from '@/components/devfund/CardPaymentQR'; export default function SupportPage() { return <CardPaymentQR username="yourname" />; }
With TypeScript
tsximport CardPaymentQR from '@/components/devfund/CardPaymentQR'; interface PageProps { params: { username: string }; } export default function Page({ params }: PageProps) { return <CardPaymentQR username={params.username} />; }
Common Customizations
Remove QR Code
Remove QR code and show only UPI ID:
tsx{/* Hide QR code */} {profile.qrCodeImage && ( <div className="hidden"> <img src={profile.qrCodeImage} /> </div> )}
Show Multiple UPI IDs
Display all available UPI IDs:
tsx<div className="space-y-3"> {profile.upiIds.map((upi) => ( <div key={upi.id} className="p-3 bg-gray-100 rounded"> {upi.label}: {upi.upiId} </div> ))} </div>
Add Default Amount
Show suggested payment amount:
tsx{profile.defaultAmount && ( <div className="mt-4 p-3 bg-yellow-50 rounded"> Suggested: ₹{profile.defaultAmount} </div> )}