Overview
The platform uses Cloudflare services for fast, global asset delivery:
Cloudflare R2 - Object storage for static assets (logos, icons, audio files)
Cloudflare Images - Dynamic image optimization with responsive variants
Global CDN - Edge caching for low-latency delivery worldwide
Configuration
CDN Base URLs
All CDN assets are served from:
const CDN_BASE_URL = 'https://cdn.njrajatmahotsav.com'
const CLOUDFLARE_IMAGES_BASE = 'https://imagedelivery.net/vdFY6FzpM3Q9zi31qlYmGA/'
Environment Variables (Optional)
For R2 uploads via server-side API routes:
R2_ENDPOINT = https://your-account-id.r2.cloudflarestorage.com
R2_ACCESS_KEY_ID = your-access-key
R2_SECRET_ACCESS_KEY = your-secret-key
R2_BUCKET_NAME = your-bucket-name
R2_BUCKET_PREFIX = uploads/
These variables are only needed for server-side upload functionality. Static asset serving works without them.
Cloudflare R2 Assets
Static Asset Catalog
Pre-uploaded assets are defined in lib/cdn-assets.ts:
lib/cdn-assets.ts
Usage Example
const CDN_BASE_URL = 'https://cdn.njrajatmahotsav.com'
export const CDN_ASSETS = {
// Logos
mainLogo: ` ${ CDN_BASE_URL } /main_logo.png` ,
mainLogoNoText: ` ${ CDN_BASE_URL } /main_logo_no_text.png` ,
maningarLogo: ` ${ CDN_BASE_URL } /maninagar_logo.png` ,
whiteLogo: ` ${ CDN_BASE_URL } /white_logo.png` ,
linenLogo: ` ${ CDN_BASE_URL } /LinenLogo.png` ,
// Icons
instagramIcon: ` ${ CDN_BASE_URL } /Instagram_Glyph_Gradient.png` ,
youtubeIcon: ` ${ CDN_BASE_URL } /youtube_red_icon.png` ,
tilak: ` ${ CDN_BASE_URL } /Tilak.png` ,
}
export const getR2Image = ( filename : string ) =>
` ${ CDN_BASE_URL }${ filename } `
Dynamic R2 Assets
For assets not in the catalog, use the getR2Image helper:
import { getR2Image } from '@/lib/cdn-assets'
const audioUrl = getR2Image ( '/audio/background-music.mp3' )
const pdfUrl = getR2Image ( '/documents/event-schedule.pdf' )
Cloudflare Images
Image Variants
Cloudflare Images supports three optimized variants:
Variant Width Quality Use Case bigger1200px 90% Desktop hero images, galleries mobileWP800px 90% Mobile hero images, cards biggest2400px 100% Full-screen modals, downloads
Helper Functions
lib/cdn-assets.ts
Usage Example
const CLOUDFLARE_IMAGES_BASE = 'https://imagedelivery.net/vdFY6FzpM3Q9zi31qlYmGA/'
export const getCloudflareImage = ( imageId : string ) =>
` ${ CLOUDFLARE_IMAGES_BASE }${ imageId } /bigger?format=auto&quality=90`
export const getCloudflareImageMobileWp = ( imageId : string ) =>
` ${ CLOUDFLARE_IMAGES_BASE }${ imageId } /mobileWP?format=auto&quality=90`
export const getCloudflareImageBiggest = ( imageId : string ) =>
` ${ CLOUDFLARE_IMAGES_BASE }${ imageId } /biggest?format=auto&quality=100`
Responsive Image Patterns
Standard Image with Variants
import { getCloudflareImage , getCloudflareImageMobileWp } from '@/lib/cdn-assets'
const desktopSrc = getCloudflareImage ( 'image-id-123' )
const mobileSrc = getCloudflareImageMobileWp ( 'image-id-123' )
< picture >
< source media = "(max-width: 768px)" srcSet = { mobileSrc } />
< source media = "(min-width: 769px)" srcSet = { desktopSrc } />
< img src = { desktopSrc } alt = "Responsive image" loading = "lazy" />
</ picture >
High-Resolution Modal Image
import { getCloudflareImageBiggest } from '@/lib/cdn-assets'
function ImageModal ({ imageId } : { imageId : string }) {
return (
< div className = "modal" >
< img
src = { getCloudflareImageBiggest ( imageId )}
alt = "Full resolution image"
className = "max-w-full h-auto"
/>
</ div >
)
}
Gallery Grid
import { getCloudflareImage } from '@/lib/cdn-assets'
const galleryImages = [
'id-1' , 'id-2' , 'id-3' , 'id-4' , 'id-5' , 'id-6'
]
export function ImageGallery () {
return (
< div className = "grid grid-cols-3 gap-4" >
{ galleryImages . map (( id ) => (
< img
key = { id }
src = { getCloudflareImage ( id )}
alt = { `Gallery image ${ id } ` }
className = "w-full h-auto rounded-lg"
loading = "lazy"
/>
))}
</ div >
)
}
All Cloudflare Images helpers use format=auto, which automatically serves:
WebP for modern browsers (Chrome, Edge, Firefox)
AVIF for supported browsers (Chrome 85+, Firefox 93+)
JPEG/PNG fallback for legacy browsers
No code changes needed - format selection is automatic based on browser support.
Use Correct Variant
Choose the appropriate variant for your use case:
bigger (1200px) for desktop content
mobileWP (800px) for mobile views
biggest (2400px) only for full-screen/download scenarios
Lazy Load Images
Add loading="lazy" to images below the fold: < img src = {getCloudflareImage(id)} loading = "lazy" alt = "..." />
Specify Dimensions
Always include width and height to prevent layout shift: < img src = {url} width = {1200} height = {600} alt = "..." />
Use Picture Element for Art Direction
Serve different crops/variants based on viewport: < picture >
< source media = "(max-width: 768px)" srcSet = {mobileSrc} />
< img src = {desktopSrc} alt = "..." />
</ picture >
Migration Guide
From Local Images to Cloudflare Images
Upload to Cloudflare Images
Go to Cloudflare Dashboard → Images
Upload your image
Copy the image ID (e.g., abc-123-def-456)
Update Component
- import heroImage from '/public/images/hero.jpg'
+ import { getCloudflareImage } from '@/lib/cdn-assets'
export function Hero() {
return (
- <img src={heroImage.src} alt="Hero" />
+ <img src={getCloudflareImage('abc-123-def-456')} alt="Hero" />
)
}
Test Variants
Verify image loads correctly on desktop and mobile viewports.
From Local Static Assets to R2
Upload to R2 Bucket
Use the Cloudflare Dashboard or CLI to upload files to your R2 bucket.
Add to CDN Assets Catalog
// lib/cdn-assets.ts
export const CDN_ASSETS = {
// ... existing assets
newAsset: ` ${ CDN_BASE_URL } /path/to/new-asset.png` ,
}
Update References
- import logo from '/public/logo.png'
+ import { CDN_ASSETS } from '@/lib/cdn-assets'
- <img src={logo.src} alt="Logo" />
+ <img src={CDN_ASSETS.newAsset} alt="Logo" />
Troubleshooting
Image not loading? Check these common issues:
Incorrect image ID - Verify the ID from Cloudflare Dashboard
Variant not found - Ensure the variant (bigger, mobileWP, biggest) exists
CORS errors - Check Cloudflare Images CORS settings
404 errors - Verify the R2 bucket is publicly accessible
Debug Checklist
// Test image URL directly in browser
const testUrl = getCloudflareImage ( 'your-image-id' )
console . log ( 'Testing URL:' , testUrl )
// Visit URL in browser to check if it loads
// Check if helpers are working
import { getCloudflareImage } from '@/lib/cdn-assets'
console . log ( getCloudflareImage ( 'test' ))
// Expected: https://imagedelivery.net/vdFY6FzpM3Q9zi31qlYmGA/test/bigger?format=auto&quality=90
Resources
Cloudflare R2 Docs Object storage documentation and API reference
Cloudflare Images Docs Image optimization and delivery guide
Performance Best Practices Optimize image delivery for speed and Core Web Vitals